Advertisement
musifter

AoC day 11 (pt2), Smalltalk

Dec 11th, 2020
2,155
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/local/bin/gst -q
  2.  
  3. "
  4. |  Class for handling a 2D array Grid
  5. "
  6. ArrayedCollection subclass: Grid [
  7.     | dim alloc row changes dirs |
  8.     <shape: #pointer>
  9.  
  10.     Grid class >> new: dim [
  11.         ^(super new: (dim x + 2) * (dim y + 2)) init: dim
  12.     ]
  13.  
  14.     init: d [
  15.         changes := OrderedCollection new.
  16.         dim   := d.
  17.         alloc := Point x: (d x + 2) y: (d y + 2).
  18.         row   := 1.
  19.         (1 to: (alloc x * alloc y)) do: [ :i | self basicAt: i put: $* ].
  20.         " XXX: hackish declaration "
  21.         dirs  := Array new: 8.
  22.         dirs at: 1 put: (-1 @ -1).
  23.         dirs at: 2 put: (-1 @  0).
  24.         dirs at: 3 put: (-1 @  1).
  25.         dirs at: 4 put: ( 0 @ -1).
  26.         dirs at: 5 put: ( 0 @  1).
  27.         dirs at: 6 put: ( 1 @ -1).
  28.         dirs at: 7 put: ( 1 @  0).
  29.         dirs at: 8 put: ( 1 @  1).
  30.         ^self
  31.     ]
  32.  
  33.     " loading method "
  34.     addRow: str [
  35.         str doWithIndex: [:c :i | self atPoint: (i @ row) put: c].
  36.         row := row + 1.
  37.         ^self
  38.     ]
  39.  
  40.     " access methods "
  41.     changes [ ^changes size ]
  42.  
  43.     atPoint: pt [
  44.         ^self basicAt: (pt x * alloc y + pt y + 1).
  45.     ]
  46.  
  47.     atPoint: pt put: val [
  48.         ^self basicAt: (pt x * alloc y + pt y + 1) put: val.
  49.     ]
  50.  
  51.     " iterator methods "
  52.     do: aBlock [
  53.         (1 to: dim y) do: [ :y |
  54.             (1 to: dim x) do: [ :x |
  55.                 aBlock value: (self atPoint: (x @ y)).
  56.             ]
  57.         ]
  58.     ]
  59.  
  60.     doPoint: aBlock [
  61.         (1 to: dim y) do: [ :y |
  62.             (1 to: dim x) do: [ :x |
  63.                 aBlock value: (x @ y)
  64.             ]
  65.         ]
  66.     ]
  67.  
  68.     inject: val into: aBlock [
  69.         | ret |
  70.         ret := val.
  71.         self do: [ :b | ret := aBlock value: ret value: b ].
  72.         ^ret
  73.     ]
  74.  
  75.     from: pt1 to: pt2 inject: val into: aBlock [
  76.         | ret |
  77.         ret := val.
  78.         (pt1 y to: pt2 y) do: [ :y |
  79.             (pt1 x to: pt2 x) do: [ :x |
  80.                 ret := aBlock value: ret value: (self atPoint: (x @ y)).
  81.             ]
  82.         ].
  83.         ^ret
  84.     ]
  85.  
  86.     neighbours: pt inject: val into: aBlock [
  87.         | pt1 pt2 |
  88.         pt1 := (pt x - 1) @ (pt y - 1).
  89.         pt2 := (pt x + 1) @ (pt y + 1).
  90.         ^self from: pt1 to: pt2 inject: val into: aBlock
  91.     ]
  92.  
  93.     from: pt ray: dir whileTrue: aPred [
  94.         | npt |
  95.         npt := Point x: (pt x + dir x) y: (pt y + dir y).
  96.  
  97.         [ aPred value: npt ] whileTrue: [
  98.             npt x: (npt x + dir x) y: (npt y + dir y).
  99.         ].
  100.         ^self atPoint: npt
  101.     ]
  102.  
  103.     occupiedFrom: pt [
  104.         | ret cell |
  105.         ret := 0.
  106.         dirs do: [ :d |
  107.             cell := self from: pt ray: d whileTrue: [ :pt | ((self atPoint: pt) = $.) ].
  108.             ret := ret + (cell == $#) asCBooleanValue.
  109.         ].
  110.         ^ret
  111.     ]
  112.  
  113.     " methods for marking changes and applying them "
  114.     mark: pt put: val [
  115.         changes add: (Array with: pt with: val).
  116.     ]
  117.  
  118.     applyChanges [
  119.         changes do: [ :ch |
  120.             self atPoint: ch first put: ch second.
  121.         ].
  122.         changes empty.
  123.     ]
  124.  
  125.     " output method "
  126.     printOn: stream [
  127.         (1 to: dim y) do: [ :y |
  128.             (1 to: dim x) do: [ :x |
  129.                 stream nextPutAll: (self atPoint: (x @ y)) asString.
  130.             ].
  131.             stream nl.
  132.         ].
  133.     ]
  134. ]
  135.  
  136. "
  137. |  Mainline
  138. "
  139. " XXX: Hardcoded dimensions for now "
  140. grid := Grid new: (98 @ 99).
  141.  
  142. stdin linesDo: [ :line |
  143.     grid addRow: line.
  144. ].
  145.  
  146. gen := 1.
  147. [ (grid changes > 0) or: [ gen = 1 ] ] whileTrue: [
  148.     stdout nextPutAll: 'Generation: ', gen asString,
  149.                        '  Changes: ',  grid changes asString, '  ';
  150.                        cr; flush.
  151.  
  152.     grid applyChanges.
  153.     gen := gen + 1.
  154.  
  155.     grid doPoint: [ :pt |
  156.         cell := grid atPoint: pt.
  157.  
  158.         (cell == $.) ifFalse: [
  159.             occ := grid occupiedFrom: pt.
  160.  
  161.             ((cell == $#) and: [occ >= 5]) ifTrue: [ grid mark: pt put: $L ].
  162.             ((cell == $L) and: [occ = 0])  ifTrue: [ grid mark: pt put: $# ].
  163.         ]
  164.     ]
  165. ].
  166.  
  167. part1 := grid inject: 0 into: [ :a :b | a + ((b == $#) asCBooleanValue) ].
  168.  
  169. stdout nl; nextPutAll: 'Part 1: ', part1 asString; nl.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement