application/octet-stream
•
2.44 KB
•
66 lines
#!/usr/bin/env nujel
(defn polymer/read (line)
(def eles {})
(def pairs {})
(dotimes (i (:length line))
(def key-a (:symbol (:cut line i (+ i 1))))
(if (:has? eles key-a)
(tree/++ eles key-a)
(set! eles key-a 1))
(when (< i (- (:length line) 1))
(def key-b (:symbol (:cut line i (+ i 2))))
(if (:has? pairs key-b)
(tree/++ pairs key-b)
(set! pairs key-b 1))))
{:pairs pairs :eles eles :combinations '()})
(defn combination/parse (recipe last-recipe)
(def source (:symbol (car recipe)))
(def new (:symbol (cadr recipe)))
(def new-α (:symbol (cat (:cut (car recipe) 0 1) (cadr recipe))))
(def new-β (:symbol (cat (cadr recipe) (:cut (car recipe) 1 2))))
(fn (α Ω)
(def count (int (or (ref (ref α :pairs) source) 0)))
(tree/+= (ref Ω :eles) new count)
(tree/+= (ref Ω :pairs) source (- count))
(tree/+= (ref Ω :pairs) new-α count)
(tree/+= (ref Ω :pairs) new-β count)
(if (lambda? last-recipe) (last-recipe α Ω) Ω)))
(defn combination/add (state recipe)
(set! state :combinations (combination/parse recipe (ref state :combinations))))
(defn combinations/read (state lines)
(for-each lines (fn (line) (combination/add state (split line " -> "))))
state)
(defn state/read (fn)
(def input-raw (split (file/read fn) "\n"))
(def state (polymer/read (car input-raw)))
(combinations/read state (cddr input-raw)))
(defn state/dup (α)
{:combinations (ref α :combinations) :pairs (:clone (ref α :pairs)) :eles (:clone (ref α :eles))})
(defn state/run/once (α)
((ref α :combinations) α (state/dup α)))
(defn state/run/many (α steps)
(if (<= steps 0) α
(state/run/many (state/run/once α)
(- steps 1))))
(defn result (state)
(- (apply max (:values (ref state :eles)))
(apply min (:values (ref state :eles)))))
(def state (state/read "tests/fast/day14.dat"))
(def p1-state (state/run/many state 10))
(def res-p1 (result p1-state))
(when (not= res-p1 2010)
(throw (list :wrong-result "Wrong Part 1 result" res-p1)))
(def res-p2 (result (state/run/many p1-state 30)))
(when (not= res-p2 2437698971143)
(throw (list :wrong-result "Wrong Part 2 result" res-p2)))
(return :success)