You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
aoc-racket/2021/14.rkt

54 lines
2.2 KiB
Racket

2 years ago
#lang br
(require racket/file sugar rackunit racket/dict)
(define lines (file->lines "14.rktd"))
(define (template->duos template-str)
(define cs (string->list template-str))
(for/list ([c1 cs]
[c2 (cdr cs)])
(list c1 c2)))
(define starting-template (car lines))
(define template (frequency-hash (template->duos starting-template)))
(define rule-strs (cddr lines))
(define procs (for/list ([rule-str rule-strs])
(match-define (list pat repl) (string-split rule-str " -> "))
(define duo (string->list pat))
(define replc (string-ref repl 0))
(λ (h)
(match (hash-ref h duo #f)
[#false null]
[duo-count
(define new-left-duo (list (first duo) replc))
(define new-right-duo (list replc (second duo)))
(cons
(cons duo (- duo-count))
(map (λ (new-duo) (cons new-duo duo-count))
(list new-left-duo new-right-duo)))]))))
(define (do-insertion template steps)
(for/fold ([template template])
([step steps])
(define delta-dict (append-map (λ (proc) (proc template)) procs))
(define this-template (make-hash))
(for ([(k v) (in-dict (append (hash->list template) delta-dict))])
(hash-update! this-template k (λ (val) (+ val v)) 0))
this-template))
(define (element-counts template)
(define orig-template-cs (string->list starting-template))
(define h (make-hash))
(for* ([(k v) (in-dict template)]
[c k])
(hash-update! h c (λ (val) (+ val v)) 0))
(for-each (λ (c) (hash-update! h c add1)) (list (first orig-template-cs) (last orig-template-cs)))
(for/hash ([(k v) (in-hash h)])
(values k (/ v 2))))
(define (score template)
(- (apply max (hash-values template)) (apply min (hash-values template))))
(check-equal? (score (element-counts (do-insertion template 10))) 2703)
(check-equal? (score (element-counts (do-insertion template 40))) 2984946368465)