Login
7 branches 0 tags
Ben (Win10) [fmt] can now deal with specified FP precision 13ad2f7 3 years ago 424 Commits
nujel / tests / fast / day14.nuj
#!/usr/bin/env nujel

[defun polymer/read [line]
       [def eles @[]]
       [def pairs @[]]
       [for [i 0 [string/length line]]
            [tree/++ eles [str->sym [string/cut line i [+ i 1]]]]
            [when [< i [- [string/length line] 1]]
                  [tree/++ pairs [str->sym [string/cut line i [+ i 2]]]]]]
       @[:pairs pairs :eles eles :combinations '[]]]

[defun combination/parse [recipe last-recipe]
       [def source [str->sym [car recipe]]]
       [def new    [str->sym [cadr recipe]]]
       [def new-α [str->sym [cat [string/cut [car recipe] 0 1] [cadr recipe]]]]
       [def new-β [str->sym [cat [cadr recipe] [string/cut [car recipe] 1 2]]]]
       [\ [α Ω]
          [def count [int [[α :pairs] source]]]
          [tree/+= [Ω :eles] new count]
          [tree/+= [Ω :pairs] source [- count]]
          [tree/+= [Ω :pairs] new-α count]
          [tree/+= [Ω :pairs] new-β count]
          [if [lambda? last-recipe] [last-recipe α Ω] Ω]]]

[defun combination/add [state recipe]
       [tree/set! state :combinations [combination/parse recipe [state :combinations]]]]

[defun combinations/read [state lines]
       [for-each lines [\ [line] [combination/add state [split line " -> "]]]]
       state]

[defun state/read [fn]
       [def input-raw [split [file/read fn] "\n"]]
       [def state [polymer/read [car input-raw]]]
       [combinations/read state [cddr input-raw]]]

[defun state/dup [α]
       @[:combinations [α :combinations] :pairs [tree/dup [α :pairs]] :eles [tree/dup [α :eles]]]]

[defun state/run/once [α]
       [[α :combinations] α [state/dup α]]]

[defun state/run/many [α steps]
       [if [<= steps 0] α
           [state/run/many [state/run/once α] [- steps 1]]]]

[defun result [state]
  [- [max [tree/values [state :eles]]]
     [min [tree/values [state :eles]]]]]

[def state [state/read "tests/fast/day14.input"]]
[def p1-state [state/run/many state 10]]
[def res-p1 [result p1-state]]
[when [!= res-p1 2010]
      [throw [list :wrong-result "Wrong Part 1 result" res-p1]]]
[def res-p2 [result [state/run/many p1-state 30]]]
[when [!= res-p2 2437698971143]
      [throw [list :wrong-result "Wrong Part 2 result" res-p2]]]