Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/local/bin/gst -q
- "
- | Class for handling a 2D array Grid
- "
- ArrayedCollection subclass: Grid [
- | dim alloc row changes dirs |
- <shape: #pointer>
- Grid class >> new: dim [
- ^(super new: (dim x + 2) * (dim y + 2)) init: dim
- ]
- init: d [
- changes := OrderedCollection new.
- dim := d.
- alloc := Point x: (d x + 2) y: (d y + 2).
- row := 1.
- (1 to: (alloc x * alloc y)) do: [ :i | self basicAt: i put: $* ].
- " XXX: hackish declaration "
- dirs := Array new: 8.
- dirs at: 1 put: (-1 @ -1).
- dirs at: 2 put: (-1 @ 0).
- dirs at: 3 put: (-1 @ 1).
- dirs at: 4 put: ( 0 @ -1).
- dirs at: 5 put: ( 0 @ 1).
- dirs at: 6 put: ( 1 @ -1).
- dirs at: 7 put: ( 1 @ 0).
- dirs at: 8 put: ( 1 @ 1).
- ^self
- ]
- " loading method "
- addRow: str [
- str doWithIndex: [:c :i | self atPoint: (i @ row) put: c].
- row := row + 1.
- ^self
- ]
- " access methods "
- changes [ ^changes size ]
- atPoint: pt [
- ^self basicAt: (pt x * alloc y + pt y + 1).
- ]
- atPoint: pt put: val [
- ^self basicAt: (pt x * alloc y + pt y + 1) put: val.
- ]
- " iterator methods "
- do: aBlock [
- (1 to: dim y) do: [ :y |
- (1 to: dim x) do: [ :x |
- aBlock value: (self atPoint: (x @ y)).
- ]
- ]
- ]
- doPoint: aBlock [
- (1 to: dim y) do: [ :y |
- (1 to: dim x) do: [ :x |
- aBlock value: (x @ y)
- ]
- ]
- ]
- inject: val into: aBlock [
- | ret |
- ret := val.
- self do: [ :b | ret := aBlock value: ret value: b ].
- ^ret
- ]
- from: pt1 to: pt2 inject: val into: aBlock [
- | ret |
- ret := val.
- (pt1 y to: pt2 y) do: [ :y |
- (pt1 x to: pt2 x) do: [ :x |
- ret := aBlock value: ret value: (self atPoint: (x @ y)).
- ]
- ].
- ^ret
- ]
- neighbours: pt inject: val into: aBlock [
- | pt1 pt2 |
- pt1 := (pt x - 1) @ (pt y - 1).
- pt2 := (pt x + 1) @ (pt y + 1).
- ^self from: pt1 to: pt2 inject: val into: aBlock
- ]
- from: pt ray: dir whileTrue: aPred [
- | npt |
- npt := Point x: (pt x + dir x) y: (pt y + dir y).
- [ aPred value: npt ] whileTrue: [
- npt x: (npt x + dir x) y: (npt y + dir y).
- ].
- ^self atPoint: npt
- ]
- occupiedFrom: pt [
- | ret cell |
- ret := 0.
- dirs do: [ :d |
- cell := self from: pt ray: d whileTrue: [ :pt | ((self atPoint: pt) = $.) ].
- ret := ret + (cell == $#) asCBooleanValue.
- ].
- ^ret
- ]
- " methods for marking changes and applying them "
- mark: pt put: val [
- changes add: (Array with: pt with: val).
- ]
- applyChanges [
- changes do: [ :ch |
- self atPoint: ch first put: ch second.
- ].
- changes empty.
- ]
- " output method "
- printOn: stream [
- (1 to: dim y) do: [ :y |
- (1 to: dim x) do: [ :x |
- stream nextPutAll: (self atPoint: (x @ y)) asString.
- ].
- stream nl.
- ].
- ]
- ]
- "
- | Mainline
- "
- " XXX: Hardcoded dimensions for now "
- grid := Grid new: (98 @ 99).
- stdin linesDo: [ :line |
- grid addRow: line.
- ].
- gen := 1.
- [ (grid changes > 0) or: [ gen = 1 ] ] whileTrue: [
- stdout nextPutAll: 'Generation: ', gen asString,
- ' Changes: ', grid changes asString, ' ';
- cr; flush.
- grid applyChanges.
- gen := gen + 1.
- grid doPoint: [ :pt |
- cell := grid atPoint: pt.
- (cell == $.) ifFalse: [
- occ := grid occupiedFrom: pt.
- ((cell == $#) and: [occ >= 5]) ifTrue: [ grid mark: pt put: $L ].
- ((cell == $L) and: [occ = 0]) ifTrue: [ grid mark: pt put: $# ].
- ]
- ]
- ].
- part1 := grid inject: 0 into: [ :a :b | a + ((b == $#) asCBooleanValue) ].
- stdout nl; nextPutAll: 'Part 1: ', part1 asString; nl.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement