#lang curly-fn racket (require "scripts/aoc.rkt") ;; solution for day 22 (define (score cards) (for/sum ([card (in-list cards)] [mult (in-range (length cards) 0 -1)]) (* card mult))) (define (play p1 p2) (match* (p1 p2) [('() _) (score p2)] [(_ '()) (score p1)] [((cons p1-card p1-rest) (cons p2-card p2-rest)) (if (> p1-card p2-card) (play (append p1-rest (list p1-card p2-card)) p2-rest) (play p1-rest (append p2-rest (list p2-card p1-card))))])) (define (part1 input) (match-define (list p1 p2) input) (play p1 p2)) (define (part2 input) (match-define (list p1 p2) input) (define/memoized (play/recur p1 p2) (define local-memo (mutable-set)) (let loop ([p1 p1] [p2 p2]) (cond [(set-member? local-memo (list p1 p2)) (cons 'p1 p1)] [(empty? p1) (cons 'p2 p2)] [(empty? p2) (cons 'p1 p1)] [else (set-add! local-memo (list p1 p2)) (match-define (cons p1-card p1-rest) p1) (match-define (cons p2-card p2-rest) p2) (cond [(and (>= (length p1-rest) p1-card) (>= (length p2-rest) p2-card)) (match-define (cons winner score) (play/recur (take p1-rest p1-card) (take p2-rest p2-card))) (if (symbol=? winner 'p1) (loop (append p1-rest (list p1-card p2-card)) p2-rest) (loop p1-rest (append p2-rest (list p2-card p1-card))))] [(> p1-card p2-card) (loop (append p1-rest (list p1-card p2-card)) p2-rest)] [else (loop p1-rest (append p2-rest (list p2-card p1-card)))])]))) (score (cdr (play/recur p1 p2)))) ;; parse input file (define (parse fname) (match-define (list p1 p2) (string-split (file->string fname) "\n\n")) (list (map string->number (rest (string-split p1 "\n"))) (map string->number (rest (string-split p2 "\n"))))) (time (part2 (parse "/tmp/adventofcode-2020/input/22.txt"))) (module+ test (require rackunit) ;; tests here (displayln "no tests :(")) (module+ main (define input (parse "inputs/22")) (answer 22 1 (time (part1 input))) (answer 22 2 (time (part2 input))) (displayln "meow"))