Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/local/bin/gst -q
- "
- | Part 1: set to 3
- | Part 2: set to 4
- "
- num_dimensions := 3.
- " Extension to numbers: convert to an array of digits in a specified radix. "
- Number extend [
- asListRadix: n [
- | ret x |
- ret := OrderedCollection new.
- x := self.
- [ (x >= n) ] whileTrue: [
- ret addLast: (x \\ n).
- x := x // n.
- ].
- ^ret addLast: x; yourself.
- ]
- ]
- " Extension for Array for simple vector addition "
- Array extend [
- + arr [
- | ret |
- ret := Array new: (self size).
- self doWithIndex: [ :n :i | ret at: i put: ((self at: i) + (arr at: i)) ].
- ^ret
- ]
- ]
- "
- | Class to maintain an N-space for our Conway Cubes.
- "
- Object subclass: NSpace [
- | neigh dims space row active live |
- " Constructors: "
- NSpace class >> new [
- ^(super new) init: 3
- ]
- NSpace class >> dims: d [
- ^(super new) init: d
- ]
- " Initialization: "
- init: d [
- | num_neigh |
- dims := d.
- live := 0.
- row := 1. " Only used for loading "
- space := LookupTable new.
- active := Set new.
- " Build table of vectors for neighbours "
- num_neigh := ((3 raisedTo: dims) - 1).
- neigh := Array new: num_neigh.
- (1 to: num_neigh) do: [ :i |
- | list |
- list := (i asListRadix: 3).
- [ list size < dims ] whileTrue: [
- list addLast: 0.
- ].
- neigh at: i put: (list collect: [ :n | (n = 2) ifTrue: [-1] ifFalse: [n] ]) asArray.
- ].
- ^self
- ]
- " Load Space from strings "
- loadRow: str [
- str doWithIndex: [:c :i |
- | coord |
- coord := Array new: dims withAll: 0.
- coord at: 1 put: i; at: 2 put: row.
- (c == $#) ifTrue: [ self setLive: coord ].
- ].
- row := row + 1.
- ]
- " Accessors: "
- getActive [ ^active ] " Set of cells that might change "
- getNumLive [ ^live ] " Number of live cells "
- getCell: coord [
- ^space at: (coord printString) ifAbsent: [0]
- ]
- " Set a cell to live, mark neighbours for checking next time "
- setLive: coord [
- space at: (coord printString) put: 1.
- self markNeighbours: coord.
- live := live + 1.
- ]
- " Number of live cells adjacent to coord "
- countNeighbours: coord [
- ^neigh inject: 0 into: [ :acc :vec | acc + (self getCell: (coord + vec)) ]
- ]
- " Add coord and its neighbours to the Set to check next time "
- markNeighbours: coord [
- active add: coord.
- neigh do: [ :vec | active add: (coord + vec) ].
- ]
- ]
- "
- | Mainline:
- "
- " Load initial state: "
- curr := NSpace dims: num_dimensions.
- stdin linesDo: [ :line |
- curr loadRow: line.
- ].
- " Run cellular automata: "
- (1 to: 6) do: [ :t |
- next := NSpace dims: num_dimensions.
- (curr getActive) do: [ :coord |
- | neigh |
- neigh := curr countNeighbours: coord.
- ((curr getCell: coord) = 1) ifTrue: [
- ((neigh = 2) or: [ neigh = 3 ]) ifTrue: [ next setLive: coord ].
- ] ifFalse: [
- (neigh = 3) ifTrue: [ next setLive: coord ].
- ].
- ].
- stdout nextPutAll: ('Time: ', t asString, '; Live: ', next getNumLive asString); nl; flush.
- curr := next.
- ]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement