advent-of-code/2020/day24/day24.rkt
2024-11-12 21:46:18 +01:00

80 lines
2 KiB
Racket

#lang racket
(module+ test
(require rackunit))
(define (read-input filename)
(map string->tile (file->lines filename)))
(define (string->tile str)
(path->tile (map string->symbol (regexp-match* #rx"(e|w|se|sw|ne|nw)" str))))
(define (path->tile path)
(define-values (q r)
(for/fold ([q 0]
[r 0])
([s (in-list path)])
(match s
['e (values (add1 q) r)]
['ne (values (add1 q) (sub1 r))]
['nw (values q (sub1 r))]
['w (values (sub1 q) r)]
['sw (values (sub1 q) (add1 r))]
['se (values q (add1 r))])))
(list q r))
(define (initial-grid tiles)
(define grid (make-hash))
(for ([tile (in-list tiles)])
(hash-update! grid tile not #f))
grid)
(define (count-alive grid)
(for/sum ([(k v) (in-hash grid)]
#:when v)
1))
(define (part1 filename)
(define tiles (read-input filename))
(count-alive (initial-grid tiles)))
(module+ test
(check-equal? (part1 "test") 10))
(module+ main
(displayln (part1 "input")))
(define (count-alive-neighbours grid tile)
(define q (car tile))
(define r (cadr tile))
(for*/sum ([i (in-range -1 2)]
[j (in-range -1 2)]
#:unless (= 0 i j)
#:unless (= 2 (abs (+ i j)))
#:when (hash-ref grid (list (+ q i) (+ r j)) #f))
1))
(define (step grid)
(define size (+ 2 (apply max (flatten (hash-keys grid)))))
(for*/hash ([q (in-range (- size) size)]
[r (in-range (- size) size)])
(define color (hash-ref grid (list q r) #f))
(define n (count-alive-neighbours grid (list q r)))
(values (list q r)
(cond
[(and color (or (= 0 n) (> n 2))) #f]
[(and (not color) (= 2 n)) #t]
[else color]))))
(define (part2 filename)
(define tiles (read-input filename))
(count-alive
(for/fold ([grid (initial-grid tiles)])
([i (in-range 100)])
(step grid))))
(module+ test
(check-equal? (part2 "test") 2208))
(module+ main
(displayln (part2 "input")))