Login
7 branches 0 tags
Ben (X13/Arch) Added a little disclaimer to the perf. report a26304b 3 years ago 924 Commits
nujel / tests / ridiculous / day18.nuj
#!/usr/bin/env nujel

[defn snail/read-line [line]
      [read/single [join [split line ","] " . "]]]

[defn snail/parse-list [l d]
      [cond [[nil? l] #nil]
            [[int? l] @[:v l]]
            [#t @[:r [snail/parse-list [cdr l]] :l [snail/parse-list [car l]]]]]]

[defn snail/read [line]
      [snail/parse-list [snail/read-line line]]]

[defn snail/int? [l]
      [and l [ref l :v]]]

[defn snail->str [l]
      [cond [[snail/int? l] [string [ref l :v]]]
            [#t [cat "[" [snail->str [ref l :l]]  "," [snail->str [ref l :r]] "]"]]]]

[defn snail/find [root needle as bs]
      [def last #nil]
      [defn rec [t root needle]

            [cond [[snail/int? t] [set! last t] #f]
                  [[= needle t] last]
                  [#t [or [rec [ref t as] root needle]
                          [rec [ref t bs] root needle]]]]]
      [rec root root needle]]

[defn snail/find/previous [root needle]
      [snail/find root needle :l :r]]

[defn snail/find/next [root needle]
      [snail/find root needle :r :l]]

[defn snail/explode [t root]
      [def p [snail/find/previous root t]]
      [when p [tree/+= p :v [ref [ref t :l] :v]]]
      [def n [snail/find/next root t]]
      [when n [tree/+= n :v [ref [ref t :r] :v]]]
      [-> t
          [tree/set! :v 0]
          [tree/set! :l #nil]
          [tree/set! :r #nil]]]

[defn snail/split [t root]
      [def lv [div/int [ref t :v] 2]]
      [-> t
          [tree/set! :l @[:v lv]]
          [tree/set! :r @[:v [- [ref t :v] lv]]]
          [tree/set! :v #nil]]]

[defn snail/explode/maybe [t root d]
      [cond [[snail/int? t] #f]
            [[>= d 4] [snail/explode t root]]
            [[snail/explode/maybe [ref t :l] root [+ 1 d]] #t]
            [#t [snail/explode/maybe [ref t :r] root [+ 1 d]]]]]

[defn snail/split/maybe [t root d]
      [cond [[snail/int? t] [and [>= [ref t :v] 10]
                                 [snail/split t root] #t]]
            [[snail/split/maybe [ref t :l] root [+ 1 d]] #t]
            [#t [snail/split/maybe [ref t :r] root [+ 1 d]]]]]

[defn snail/reduce [t]
      [while [or [snail/explode/maybe t t 0]
                 [snail/split/maybe t t 0]]] t]

[defn snail/add [a b]
      [snail/reduce @[:l a :r b]]]

[defn snail/sum [lines]
      [def vals [map [split lines "\n"] snail/read]]
      [reduce [cdr vals] snail/add [car vals]]]

[defn snail/mag [t]
      [cond [[snail/int? t] [ref t :v]]
            [#t [+ [* [snail/mag [ref t :l]] 3]
                   [* [snail/mag [ref t :r]] 2]]]]]

[defn snail/find-biggest [lines]
      [def vals [apply array/new [split lines "\n"]]]
      [def cmax 0]
      [dotimes [a 100]
               [dotimes [b 100]
                        [when [not= a b]
                              [def cs [snail/add [snail/read [array/ref vals a]] [snail/read [array/ref vals b]]]]
                              [set! cmax [max cmax [snail/mag cs]]]
                              [def cs [snail/add [snail/read [array/ref vals b]] [snail/read [array/ref vals a]]]]
                              [set! cmax [max cmax [snail/mag cs]]]]]]
      cmax]

[def res-p1 [snail/mag [snail/sum [file/read "tests/slow/day18.input"]]]]
[when [not= res-p1 3725]
      [throw [list :wrong-result "Wrong result" res-p1]]]
[def res-p2 [snail/find-biggest [file/read "tests/slow/day18.input"]]]
[when [not= res-p2 4832]
      [throw [list :wrong-result "Wrong result" res-p2]]]

[return :success]