Login
7 branches 0 tags
Ben (X13/Arch) Fixed [describe] for NFuncs 18f6460 3 years ago 707 Commits
nujel / tests / ridiculous / day15.nuj
#!/usr/bin/env nujel

[defn map/set/row [data y line w]
       [def cols [map [split line ""] 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 map/supersize [in]
       [def out [array/2d/allocate [* 5 [in :width]] [* 5 [in :height]]]]
       [for [x 0 [in :width]]
       [for [y 0 [in :height]]
            [for [cx 0 5]
            [for [cy 0 5]
                 [array/2d/set! out
                                [+ x [* cx [in :width]]]
                                [+ y [* cy [in :height]]]
                                [+ 1 [% [+ -1 cx cy [array/2d/ref in x y]] 9]]]
                 [array/2d/set! out
                                [+ x [* cx [in :width]]]
                                [+ y [* cy [in :height]]]
                                [+ 1 [% [+ -1 cx cy [array/2d/ref in x y]] 9]]]
            ]]
       ]]
       out
]

[defn queue/insert-sorted [q items]
       [if [and q [< [caar q] [caar items]]]
	   [cons [car q] [queue/insert-sorted [cdr q] items]]
	   [if items
	       [cons [car items] [queue/insert-sorted q [cdr items]]]
	       q]]]

[defn map/walk [cmap]
       [def total-risk [array/2d/allocate [cmap :width] [cmap :height]]]
       [array/fill! [total-risk :data] 9999999999]
       [def x-max [- [cmap :width] 1]]
       [def y-max [- [cmap :height] 1]]
       [def q [list [list 0 x-max y-max]]]
       [while q
              [def cur [car q]]
	      [cdr! q]
              [def risk [car cur]]
              [def x [cadr cur]]
              [def y [caddr cur]]
              [def crisk [array/2d/ref total-risk x y]]
              [when [< risk crisk]
                    [array/2d/set! total-risk x y risk]
                    [+= risk [array/2d/ref cmap x y]]
		    [def tmp #nil]
                    [when [< x x-max] [set! tmp [cons [list risk [+ x 1] y] tmp]]]
                    [when [< y y-max] [set! tmp [cons [list risk x [+ y 1]] tmp]]]
                    [when [> y 0] [set! tmp [cons [list risk x [- y 1]] tmp]]]
                    [when [> x 0] [set! tmp [cons [list risk [- x 1] y] tmp]]]
		    [when tmp [set! q [queue/insert-sorted q tmp]]]
              ]]
       [array/2d/ref total-risk 0 0]]


[def res-p1 [map/walk [map/load "day15.input" 100 100]]]
[when [!= res-p1 315]
      [throw [list :wrong-result "Wrong result" res-p1]]]
[def res-p2 [map/walk [map/supersize [map/load "day15.input" 100 100]]]]
[when [!= res-p2 3040]
      [throw [list :wrong-result "Wrong result" res-p2]]]