Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/local/bin/gst -q
- Symbol extend [ value: arg [^arg perform: self] ]
- Point class extend [ from: array [^array first @ array second] ]
- Object subclass: TimeGrid [
- | grid dim end time |
- dirs := {(-1@0). (0@-1). (0@1). (1@0)}.
- TimeGrid class >> new: size drops: array [^super new init: size drops: array]
- init: size drops: dropList [
- | sent |
- dim := (size + 2) @ (size + 2).
- end := (size - 1) @ (size - 1).
- time := 0.
- " Mark clear grids with largest SmallInteger (2^62 - 1) "
- grid := Array new: (size + 2) * (size + 2) withAll: SmallInteger largest.
- " Set Sentinel Walls (occupied at time -1)"
- (1 to: dim x) do: [:i |
- grid at: i put: -1. " top "
- grid at: dim x * (dim y - 1) + i put: -1. " bottom "
- grid at: (i-1) * dim y + 1 put: -1. " left "
- grid at: i * dim y put: -1. " right "
- ].
- " Set the drop block times in grid: "
- dropList keysAndValuesDo: [:time :pos | self at: pos put: time ].
- ^self
- ]
- " Set current time (return self for convenience): "
- time: t [ time := t. ^self ]
- " Mark square as targeted at time "
- at: pt put: time [^grid at: ((pt y + 1) * dim x) + pt x + 2 put: time]
- " Get status of point at current time "
- at: pt [
- ^((grid at: ((pt y + 1) * dim x) + pt x + 2) <= time) ifTrue: [$#] ifFalse: [$.]
- ]
- " Basic access "
- dirs [^dirs]
- dim [^dim]
- getRoute [
- | queue visit state move targ |
- queue := OrderedCollection with: {0@0. 0}. " first: pos; second: time "
- visit := Set new.
- [queue notEmpty] whileTrue: [
- state := queue removeFirst.
- (state first = end) ifTrue: [ ^state second ].
- (visit includes: state first) ifFalse: [
- visit add: state first.
- dirs do: [:d |
- move := state first + d.
- targ := self at: move.
- (targ == $.) ifTrue: [
- queue addLast: {move. state second + 1}.
- ]
- ]
- ]
- ].
- ^nil
- ]
- " Print grid at current time on stream "
- printOn: aStream [
- grid keysAndValuesDo: [:idx :t |
- aStream nextPut: ((t < time) ifTrue: [$#] ifFalse: [$.]).
- (idx \\ dim x = 0) ifTrue: [aStream nl].
- ]
- ]
- ]
- "
- | Mainline
- "
- input := stdin lines contents collect: [:line |
- Point from: ((line substrings: $,) collect: #asNumber).
- ].
- grid := TimeGrid new: 71 drops: input.
- (grid time: 1024) displayNl.
- path := grid getRoute.
- ('Part 1: %1' % {path}) displayNl.
- " Binary search for first blocking drop: "
- range := (1025 to: input size).
- [range size > 1] whileTrue: [
- range displayNl.
- mid := range at: range size // 2.
- path := (grid time: mid) getRoute.
- range := (path isNil) ifTrue: [range first to: mid]
- ifFalse: [mid+1 to: range last].
- ].
- block := input at: range first.
- ('Part 2: %1,%2' % {block x. block y}) displayNl.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement