aoc2020/22.rkt

71 lines
2.1 KiB
Racket

#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"))