Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/local/bin/gst -q
- Integer extend [
- " Does number % N, but returns residue on interval of 1 to N, not 0 to N-1. "
- %% modulus [ ^self - 1 \\ modulus + 1 ]
- ]
- "
- | PriorityQueue implementation using SortedCollection for now
- "
- Object subclass: PriorityItem [
- | priority data |
- PriorityItem class >> new: pri data: anArray [ ^super new init: pri data: anArray ]
- init: pri data: array [ priority := pri. data := array. ^self ]
- <= state [ ^self priority <= state priority ]
- priority [ ^priority ]
- data [ ^data ]
- ]
- SortedCollection subclass: PriorityQueue [
- <shape: #pointer>
- PriorityQueue class >> new [ ^super new init ]
- init [ ^self ]
- at: pri insert: data [ self add: (PriorityItem new: pri data: data) ]
- next [ ^self removeFirst data ]
- priority [ ^self first priority ]
- ]
- "
- | Class to handle the 2D Grid
- "
- Object subclass: DigitGrid [
- | grid xsize ysize visit |
- dirs := { (-1@ 0). (0@-1). (0@ 1). (1@ 0) }.
- DigitGrid class >> new: arrayStrings [
- ^(super new) init: arrayStrings.
- ]
- init: mapArray [
- | inx iny |
- inx := (mapArray at: 1) size.
- iny := mapArray size.
- xsize := inx * 5.
- ysize := iny * 5.
- grid := (1 to: ysize) collect: [ :y | Array new: xsize ].
- (1 to: (mapArray at: 1) size) do: [ :y |
- (1 to: mapArray size) do: [ :x |
- (grid at: y) at: x put: ((mapArray at: y) at: x) digitValue.
- ]
- ].
- (0 to: 4) do: [ :cy |
- (0 to: 4) do: [ :cx |
- ((cy ~= 0) | (cx ~= 0)) ifTrue: [
- | inc |
- inc := cy + cx.
- (1 to: iny) do: [ :y |
- (1 to: inx) do: [ :x |
- (grid at: (iny * cy + y)) at: (inx * cx + x)
- put: ((grid at: y) at: x) + inc %% 9.
- ]
- ]
- ]
- ]
- ].
- visit := (1 to: ysize) collect: [:i | Array new: xsize withAll: SmallInteger largest].
- ^self
- ]
- " Access to grid by Points "
- at: pt [ ^(grid at: pt y) at: pt x ]
- visited: pt [ ^(visit at: pt y) at: pt x ]
- visit: pt at: risk [ ^(visit at: pt y) at: pt x put: risk ]
- xsize [ ^xsize ]
- ysize [ ^ysize ]
- " Get coordinates of neighbours "
- neighbours: pt [
- ^(dirs collect: [:d | pt + d ]) select: [:n |
- (n x between: 1 and: xsize) & (n y between: 1 and: ysize)
- ]
- ]
- " For display "
- printOn: aStream [
- grid do: [ :i |
- i printOn: aStream.
- aStream nl.
- ]
- ]
- ]
- "
- | Mainline
- "
- Eval [
- grid := DigitGrid new: (stdin lines contents).
- queue := PriorityQueue new.
- queue at: 0 insert: {0. 1 @ 1}.
- time := 0.
- [ queue notEmpty ] whileTrue: [
- | state pos risk |
- state := queue next.
- risk := state first.
- pos := state second.
- ((time := time + 1) \\ 50000 == 1) ifTrue: [
- stderr nextPutAll: ('Risk: %1' % {risk}); cr; flush.
- ].
- ((pos x == grid xsize) and: [pos y == grid ysize]) ifTrue: [
- ^('Part 2: %1' % {risk}) displayNl.
- ].
- ((grid visited: pos) > risk) ifTrue: [
- grid visit: pos at: risk.
- (grid neighbours: pos) do: [ :move |
- | new_risk |
- new_risk := risk + (grid at: move).
- queue at: new_risk insert: {new_risk. move}.
- ]
- ]
- ]
- ]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement