aoc/2021/15/lib.rkt

58 lines
1.7 KiB
Racket

#lang racket
(provide part1 part2)
(require racket/stream)
(define (part1 seed)
(solution seed 2020))
(define (part2 seed)
(solution seed 30000000))
(define (solution seed n)
(stream-ref (memory-game-stream seed) (sub1 n)))
(define (memory-game-stream seed)
(define (stream-calculated i seen previous-value)
(define previous-last-seen (hash-ref seen previous-value (list (sub1 i) (sub1 i))))
(define value (apply - (take previous-last-seen 2)))
(define last-seen (take (hash-ref seen value (list i)) 1))
(define next-seen (hash-set seen value (cons i last-seen)))
(stream-cons value (stream-calculated (add1 i) next-seen value)))
(define (stream-seed seed i seen value)
(define (update-seen seen key i)
(define last-seen (hash-ref seen key (list i)))
(hash-set seen key (cons i last-seen)))
(cond
[(empty? seed) (stream-calculated i seen value)]
[else
(define next (car seed))
(stream-cons next
(stream-seed (cdr seed)
(add1 i)
(update-seen seen next i)
next))]))
(stream-seed seed 0 (hash) (car seed)))
(module+ test
(require rackunit)
(check-equal? (part1 '(1 3 2)) 1)
(check-equal? (part1 '(2 1 3)) 10)
(check-equal? (part1 '(1 2 3)) 27)
(check-equal? (part1 '(2 3 1)) 78)
(check-equal? (part1 '(3 2 1)) 438)
(check-equal? (part1 '(3 1 2)) 1836)
(check-equal? (part2 '(0 3 6)) 175594)
(check-equal? (part2 '(1 3 2)) 2578)
(check-equal? (part2 '(2 1 3)) 3544142)
(check-equal? (part2 '(1 2 3)) 261214)
(check-equal? (part2 '(2 3 1)) 6895259)
(check-equal? (part2 '(3 2 1)) 18)
(check-equal? (part2 '(3 1 2)) 362))