Advertisement
musifter

AoC 2021 day 9 (smalltalk)

Dec 9th, 2021
1,748
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/local/bin/gst -q
  2.  
  3. Collection extend [
  4.     apply: method  [ ^self collect: [:x | x perform: method] ]
  5.  
  6.     sum      [ ^self inject: 0 into: [:a : b | a + b]  ]
  7.     product  [ ^self inject: 1 into: [:a : b | a * b]  ]
  8. ]
  9.  
  10. "
  11. |  Class to handle the 2D HeightMap, as well as tracking visited status for basin search
  12. "
  13. Object subclass: HeightMap [
  14.     | grid xsize visit |
  15.  
  16.     dirs := { -1 @ 0. 0 @ -1. 1 @ 0. 0 @ 1 }.
  17.  
  18.     HeightMap class >> new: arrayStrings [
  19.         ^(super new) init: arrayStrings.
  20.     ]
  21.  
  22.     init: mapArray [
  23.         xsize := (mapArray at: 1) size + 2.
  24.  
  25.         grid := Array new: mapArray size + 2.
  26.  
  27.         grid at: 1           put: (Array new: xsize withAll: 9).
  28.         grid at: (grid size) put: (Array new: xsize withAll: 9).
  29.  
  30.         mapArray keysAndValuesDo: [ :i :line |
  31.            | row |
  32.             row := (OrderedCollection from: ((Array withAll: line) apply: #digitValue))
  33.                     addFirst: 9; addLast: 9; yourself.
  34.  
  35.             grid at: i+1 put: row asArray.
  36.         ].
  37.  
  38.         visit := (1 to: grid size) collect: [:i | Array new: xsize withAll: false].
  39.         ^self
  40.     ]
  41.  
  42.     " Access to grid by Points "
  43.     at: pt [
  44.         ^(grid at: pt y) at: pt x
  45.     ]
  46.  
  47.     " Get coordinates of neighbours "
  48.     neighbours: pt [
  49.         ^dirs collect: [ :d | pt + d ]
  50.     ]
  51.  
  52.     " Execute a block on every Point of our input "
  53.     pointDo: aBlock [
  54.         (2 to: grid size - 1) do: [ :y |
  55.             (2 to: xsize - 1) do: [ :x |
  56.                 aBlock value: (x@y).
  57.             ]
  58.         ]
  59.     ]
  60.  
  61.     " Access to visit via Points "
  62.     visit: pt [
  63.         ^(visit at: pt y) at: pt x put: true.
  64.     ]
  65.  
  66.     visited: pt [
  67.         ^(visit at: pt y) at: pt x
  68.     ]
  69. ]
  70.  
  71. "
  72. | Mainline
  73. "
  74. map := HeightMap new: (stdin lines contents).
  75.  
  76. "
  77. |  Part 1
  78. "
  79. lows := OrderedCollection new.
  80.  
  81. map pointDo: [ :pt |
  82.     height := map at: pt.
  83.     ((map neighbours: pt) conform: [:x | (map at: x) > height]) ifTrue: [
  84.         lows add: pt.
  85.     ]
  86. ].
  87.  
  88. ('Part 1: %1' % {(lows collect: [:pt | (map at: pt) + 1]) sum}) displayNl.
  89.  
  90. "
  91. |  Part 2
  92. "
  93. basins := SortedCollection new.
  94.  
  95. lows do: [ :low |
  96.     (map visited: low) ifFalse: [
  97.         size := 0.
  98.         queue := OrderedCollection with: low.
  99.  
  100.         [queue notEmpty] whileTrue: [
  101.             pos := queue removeFirst.
  102.  
  103.             ((map visited: pos) not and: [(map at: pos) < 9]) ifTrue: [
  104.                 map visit: pos.
  105.                 size := size + 1.
  106.                 queue addAllLast: (map neighbours: pos)
  107.             ]
  108.         ].
  109.  
  110.         basins add: size
  111.     ]
  112. ].
  113.  
  114. ('Part 2: %1' % {(basins reverse atAll: (1 to: 3)) product}) displayNl.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement