58 lines
1.7 KiB
Racket
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))
|