You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
62 lines
1.8 KiB
62 lines
1.8 KiB
#lang racket |
|
(require "lib/common.rkt" |
|
fancy-app |
|
threading) |
|
|
|
(define (parse input) |
|
(match-define `(,poly-str ,rules) (string-split input "\n\n")) |
|
(values (for/fold ([hsh (hash)]) |
|
([tortoise (in-string poly-str)] |
|
[hare (in-list (rest (string->list poly-str)))]) |
|
(hash-update hsh (cons (string tortoise) (string hare)) add1 0)) |
|
(for/hash ([rule (in-list (string-split rules "\n"))]) |
|
(match-define (pregexp "(.)(.) -> (.)" (list _ ch1 ch2 ch3)) rule) |
|
(values (cons ch1 ch2) ch3)))) |
|
|
|
(define (step poly rules) |
|
(for/fold ([hsh (hash)]) |
|
([(pair num) (in-hash poly)]) |
|
(match-define (cons l r) pair) |
|
(define i (hash-ref rules pair)) |
|
(~> hsh |
|
(hash-update (cons l i) (+ _ num) 0) |
|
(hash-update (cons i r) (+ _ num) 0)))) |
|
|
|
(define (score poly) |
|
(define freqs |
|
(for/fold ([hsh (hash)]) |
|
([(pair num) (in-hash poly)]) |
|
(match-define (cons l r) pair) |
|
(~> hsh |
|
(hash-update l (+ _ num) 0) |
|
(hash-update r (+ _ num) 0)))) |
|
(floor |
|
(- (/ (apply max (hash-values freqs)) 2) |
|
(/ (apply min (hash-values freqs)) 2)))) |
|
|
|
(define (day14a poly rules) |
|
(score |
|
(for/fold ([cur-poly poly]) |
|
([_ (in-range 10)]) |
|
(step cur-poly rules)))) |
|
|
|
(define (day14b poly rules) |
|
(score |
|
(for/fold ([cur-poly poly]) |
|
([_ (in-range 40)]) |
|
(step cur-poly rules)))) |
|
|
|
(module+ main |
|
(call-with-input-file "data/day14.txt" |
|
(λ (prt) |
|
(define-values (poly rules) (parse (port->string prt))) |
|
#;(answer 14 1 (day14a poly rules)) |
|
(answer 14 2 (day14b poly rules))))) |
|
|
|
(module+ test |
|
(require rackunit) |
|
|
|
(call-with-input-file "data/day14.test.txt" |
|
(λ (prt) |
|
(define-values (poly rules) (parse (port->string prt))) |
|
(check-equal? (day14a poly rules) 1588))))
|
|
|