Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/local/bin/gst -q
- FileStream fileIn: '../../smalltalk/Priority.st'!
- Symbol extend [ value: arg [^arg perform: self] ]
- Integer extend [ %% modulus [^self - 1 \\ modulus + 1] ]
- Object subclass: DigitGrid [
- | grid dimY dimX visit dirs start end |
- DigitGrid class >> new: arrayStrings [
- ^(super new) init: arrayStrings.
- ]
- init: mapArray [
- | sent |
- dimY := mapArray size + 2.
- dimX := (mapArray at: 1) size + 2.
- dirs := {dimX. 1. -1 * dimX. -1}.
- start := dimX + 2.
- end := dimX * (dimY - 1) - 1.
- sent := (1 to: dimX) inject: '' into: [:a :b | a, '0'].
- grid := sent, (mapArray collect: [:row | '0', row, '0']) join, sent.
- grid := grid asArray collect: #digitValue.
- visit := Array new: grid size * 2 withAll: SmallInteger largest.
- ^self
- ]
- " Access to grid by index to flat array "
- at: idx [ ^grid at: idx ]
- start [ ^start ]
- end [ ^end ]
- visited: idx from: dir [^visit at: idx + (grid size * (dir \\ 2))]
- visit: idx from: dir at: cool [
- ^visit at: idx + (grid size * (dir \\ 2)) put: cool
- ]
- getDirDelta: d [ ^dirs at: d ]
- getTurns: dir [ ^{(dir + 1) %% 4. (dir - 1) %% 4} ]
- ]
- "
- | Mainline
- "
- ObjectMemory spaceGrowRate: 500.0.
- Eval [
- grid := DigitGrid new: (stdin lines contents).
- start := grid start.
- end := grid end.
- queue := PriorityQueue new.
- queue at: 0 insert: {0. start. 1}.
- queue at: 0 insert: {0. start. 2}.
- time := 0.
- [ queue notEmpty ] whileTrue: [
- | state cool pos dir |
- state := queue next.
- cool := state first.
- pos := state second.
- dir := state third.
- ((time := time + 1) \\ 50000 == 1) ifTrue: [
- stderr nextPutAll: ('Cool: %1' % {cool}); cr; flush.
- ].
- (pos = end) ifTrue: [
- ^('Part 2: %1' % {cool}) displayNl.
- ].
- ((grid visited: pos from: dir) > cool) ifTrue: [
- grid visit: pos from: dir at: cool.
- (grid getTurns: dir) do: [ :turn |
- | newPos newCool cooling delta i done |
- newPos := pos.
- newCool := cool.
- delta := grid getDirDelta: turn.
- i := 1.
- done := false.
- [(i <= 10) & done not] whileTrue: [
- newPos := newPos + delta.
- i := i + 1.
- ((cooling := grid at: newPos) = 0) ifTrue: [
- done := true. " Hit edge sentinel "
- ] ifFalse: [
- newCool := newCool + cooling.
- (i > 4) ifTrue: [queue at: newCool insert: {newCool. newPos. turn}].
- ]
- ]
- ]
- ]
- ]
- ]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement