Login
7 branches 0 tags
Ben (X13/Arch) Removed [time/strftime] and [time/unix] alias bc16f84 3 years ago 551 Commits
nujel / tests / fast / day11.nuj
#!/usr/bin/env nujel

[def flashes/get]
[def flashes/inc!]
[let [[flashes/counter 0]]
     [set! flashes/get [fn [] flashes/counter]]
     [set! flashes/inc! [fn [] [++ flashes/counter]]]]
[def p1-res 0]
[def p2-res 0]

[defn map/set/row [data y line w]
       [def cols [map [split line ""] read/int]]
       [for [x 0 w]
            [array/2d/set! data x y [car cols]]
            [cdr! cols]]]

[defn map/load [filename w h]
       [def ret [array/2d/allocate w h]]
       [def lines [split [file/read filename] "\n"]]
       [for [y 0 h]
            [map/set/row ret y [car lines] w]
            [cdr! lines]]
       ret]

[defn step/increase-energy [α β]
       [for [x 0 [ref α :width]]
       [for [y 0 [ref α :height]]
            [array/2d/set! β x y [+ 1 [array/2d/ref α x y]]]]]]

[defn step/flash-increase [β flash-map x y]
       [when [and [== #f [array/2d/ref flash-map x y]]
                  [>= x 0]
                  [>= y 0]
                  [< x [ref β :width]]
                  [< y [ref β :height]]]
             [array/2d/set! β x y [+ 1 [array/2d/ref β x y]]]
             [step/flash-try β flash-map x y]]]

[defn step/flash-try [β flash-map x y]
       [when-not [array/2d/ref flash-map x y]
                 [when [> [array/2d/ref β x y] 9]
                       [array/2d/set! β x y 0]
                       [array/2d/set! flash-map x y #t]
                       [flashes/inc!]
                       [for [cx [- x 1] [+ x 2]]
                            [for [cy [- y 1] [+ y 2]]
                                 [step/flash-increase β flash-map cx cy]]]]]]

[defn step/flash [β]
       [def flash-map [array/2d/allocate [ref β :width] [ref β :height]]]
       [array/fill! [ref flash-map :data] #f]
       [for [x 0 [ref β :width]]
            [for [y 0 [ref β :height]]
                 [step/flash-try β flash-map x y]]]]

[defn step [α]
       [def β [array/2d/allocate [ref α :width] [ref α :height]]]
       [step/increase-energy α β]
       [step/flash β]
       β]

[defn step/do-many [α steps]
       [for [i 0 steps]
            [if [== i 100] [set! p1-res [flashes/get]]]
            [def pre-flashes [flashes/get]]
            [set! α [step α]]
            [when [== 100 [- [flashes/get] pre-flashes]]
                  [set! p2-res [+ 1 i]]
                  [throw [list :all-flashes]]]]
       α]

[def state [map/load "tests/fast/day11.dat" 10 10]]
[try [fn [ε] [when [!= [car ε] :all-flashes] [throw ε]]]
     [def ret [step/do-many state 1000]]]
[when [!= p1-res 1694]
      [throw [list :wrong-result "Wrong result" p1-res]]]
[when [!= p2-res 346]
      [throw [list :wrong-result "Wrong result" p2-res]]]