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] ]
- Integer extend [ % modulus [^self - 1 \\ modulus + 1] ]
- Object subclass: IntervalGrid [
- | grid dimX dimY start |
- IntervalGrid class >> new: mapArray [
- ^super new init: mapArray
- ]
- init: mapArray [
- | rows cols |
- dimY := mapArray size.
- dimX := mapArray first size.
- rows := (1 to: dimY) collect: [:a | OrderedCollection new ].
- cols := (1 to: dimX) collect: [:a | OrderedCollection new ].
- (1 to: dimY) do: [ :row |
- | startBlock |
- startBlock := 1.
- (1 to: dimX) do: [ :col |
- (((mapArray at: row) at: col) = $#) ifTrue: [
- (rows at: row) add: (startBlock to: col - 1).
- startBlock := col + 1.
- ] ifFalse: [
- (((mapArray at: row) at: col) = $^) ifTrue: [
- start := (col @ row).
- ]
- ]
- ].
- (rows at: row) add: (startBlock to: dimX).
- ].
- (1 to: dimX) do: [ :col |
- | startBlock |
- startBlock := 1.
- (1 to: dimY) do: [ :row |
- (((mapArray at: row) at: col) = $#) ifTrue: [
- (cols at: col) add: (startBlock to: row - 1).
- startBlock := row + 1.
- ].
- ].
- (cols at: col) add: (startBlock to: dimX).
- ].
- grid := {rows. cols}.
- ^self
- ]
- rowInterval: pt [
- ^((grid at: 1) at: pt y) detect: [:a | a includes: pt x] ifNone: [nil].
- ]
- colInterval: pt [
- ^((grid at: 2) at: pt x) detect: [:a | a includes: pt y] ifNone: [nil].
- ]
- dimX [ ^dimX ]
- dimY [ ^dimY ]
- start [ ^start ]
- ]
- "
- | Mainline
- "
- grid := IntervalGrid new: stdin lines contents.
- dirs := { #(#colInterval: #first #y #y:). " Up "
- #(#rowInterval: #last #x #x:). " Right "
- #(#colInterval: #last #y #y:). " Down "
- #(#rowInterval: #first #x #x:) }. " Left "
- limX := grid dimX - 1.
- limY := grid dimY - 1.
- visit := Set new.
- pos := grid start.
- face := 1.
- [(pos x between: 2 and: limX) and: [pos y between: 2 and: limY]] whileTrue: [
- table := dirs at: face.
- interval := grid perform: table first with: pos.
- end := interval perform: table second.
- range := (table second = #first)
- ifTrue: [end to: (pos perform: table third)]
- ifFalse: [(pos perform: table third) to: end].
- range do: [:i | visit add: (pos perform: table last with: i) copy].
- pos perform: table last with: end.
- face := (face + 1) % 4.
- ].
- ('Part 1: %1' % {visit size}) displayNl.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement