Day 22: Cleanup

This commit is contained in:
Jonathan Chan 2020-12-21 22:43:07 -08:00
parent 5ad3469266
commit ecb7df09a8
1 changed files with 34 additions and 43 deletions

View File

@ -24,48 +24,39 @@
(combat (rest player1) (combat (rest player1)
(append (rest player2) (list p2 p1)))))])) (append (rest player2) (list p2 p1)))))]))
(define memo (make-hash '())) (define (recursive-combat player1 player2)
(let loop ([player1 player1]
(define (recursive-combat player1 player2 game) [player2 player2]
(if (hash-has-key? memo (list player1 player2))
(hash-ref memo (list player1 player2))
#;(printf "~a " game)
(let loop ([player1* player1]
[player2* player2]
[seen (set)]) [seen (set)])
(cond (cond
[(empty? player1*) [(empty? player1) (list #f player2)]
(hash-set! memo (list player1 player2) (list #f player2*)) [(empty? player2) (list #t player1)]
(list #f player2*)] [(set-member? seen (list player1 player2)) (list #t player1)]
[(empty? player2*)
(hash-set! memo (list player1 player2) (list #t player1*))
(list #t player1*)]
[(set-member? seen (list player1* player2*))
(hash-set! memo (list player1 player2) (list #t player1*))
(list #t player1*)]
[else [else
(let ([p1 (first player1*)] (let ([p1 (first player1)]
[p2 (first player2*)] [p2 (first player2)]
[seen (set-add seen (list player1* player2*))]) [seen (set-add seen (list player1 player2))])
(cond (cond
[(and (<= p1 (sub1 (length player1*))) [(and (<= p1 (sub1 (length player1)))
(<= p2 (sub1 (length player2*)))) (<= p2 (sub1 (length player2))))
(match-let ([(list p1-won? deck) (recursive-combat (take (rest player1*) p1) (take (rest player2*) p2) (add1 game))]) (match-define (list p1-won? deck)
(recursive-combat (take (rest player1) p1)
(take (rest player2) p2)))
(if p1-won? (if p1-won?
(loop (append (rest player1*) (list p1 p2)) (loop (append (rest player1) (list p1 p2))
(rest player2*) (rest player2)
seen) seen)
(loop (rest player1*) (loop (rest player1)
(append (rest player2*) (list p2 p1)) (append (rest player2) (list p2 p1))
seen)))] seen))]
[(> p1 p2) [(> p1 p2)
(loop (append (rest player1*) (list p1 p2)) (loop (append (rest player1) (list p1 p2))
(rest player2*) (rest player2)
seen)] seen)]
[(< p1 p2) [(< p1 p2)
(loop (rest player1*) (loop (rest player1)
(append (rest player2*) (list p2 p1)) (append (rest player2) (list p2 p1))
seen)]))])))) seen)]))])))
(define part1 (define part1
(let ([deck (combat player1 player2)]) (let ([deck (combat player1 player2)])
@ -74,7 +65,7 @@
(* card score)))) (* card score))))
(define part2 (define part2
(match-let ([(list _ deck) (recursive-combat player1 player2 1)]) (match-let ([(list _ deck) (recursive-combat player1 player2)])
(for/sum ([card deck] (for/sum ([card deck]
[score (reverse (range 1 (add1 (length deck))))]) [score (reverse (range 1 (add1 (length deck))))])
(* card score)))) (* card score))))