Advertisement
musifter

AoC 2021 day 21, part 2 (smalltalk)

Dec 22nd, 2021
2,168
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.     product [ ^self fold: [:a : b | a * b] ]
  7.  
  8.     at: idx inc: val [ ^self at: idx put: ((self at: idx ifAbsent: [0]) + val) ]
  9. ]
  10.  
  11. String extend [
  12.     asInterval [
  13.         | range |
  14.         range := (self substrings: $.) apply: #asInteger.
  15.         ^Interval from: range first to: range second.
  16.     ]
  17. ]
  18.  
  19. Object subclass: Cuboid [
  20.     | ranges str |
  21.     Cuboid class >> new: rangeArr [
  22.         ^super new init: rangeArr
  23.     ]
  24.  
  25.     init: rangeArr [
  26.         ranges := rangeArr.
  27.         str := ranges gather: [:r | r first asString, '..', r last asString, ' '].
  28.         ^self.
  29.     ]
  30.  
  31.     intersect: aCub [
  32.         | intersect |
  33.         intersect := ranges with: aCub ranges collect: [ :r :s |
  34.                          (r first max: s first) to: (r last min: s last)
  35.                      ].
  36.  
  37.         (intersect conform: [:r | r notEmpty]) ifFalse: [ ^nil ].
  38.         ^Cuboid new: intersect.
  39.     ]
  40.  
  41.     " Need both of these for LookupTable key checks to work correctly "
  42.     = aCub [ ^str = aCub string ]
  43.     hash   [ ^str hash ]
  44.  
  45.     string [ ^str ]
  46.     ranges [ ^ranges ]
  47.  
  48.     volume [ ^(ranges apply: #size) product ]
  49.  
  50.     printOn: aStream [
  51.         str printOn: aStream
  52.     ]
  53. ]
  54.  
  55. "
  56. | Mainline
  57. "
  58. input := stdin lines contents collect: [:line | line substrings: ' xyz=,'].
  59.  
  60. count := 0.
  61. cuboids := LookupTable new.
  62. input do: [ :in |
  63.    | newCube |
  64.     stderr nextPutAll: ('Working: %1' % {count := count + 1}); cr; flush.
  65.  
  66.     newCube := Cuboid new: (in allButFirst apply: #asInterval).
  67.  
  68.     subCubes := LookupTable with: (newCube -> (in first = 'on') asCBooleanValue).
  69.     cuboids keysAndValuesDo: [ :cub :weight |
  70.        | int |
  71.         (int := cub intersect: newCube) ifNotNil: [
  72.             subCubes at: int inc: weight negated   " toggling for overlap parities "
  73.         ]
  74.     ].
  75.  
  76.     " merge and prune "
  77.     subCubes keysAndValuesDo: [ :sc :w |
  78.         ((cuboids at: sc inc: w) = 0) ifTrue: [ cuboids removeKey: sc ].
  79.     ]
  80. ].
  81.  
  82. stdout nl.
  83. ('Cuboids: %1' % {cuboids size}) displayNl.
  84.  
  85. part1 := 0.
  86. cuboids keysAndValuesDo: [ :c :w |
  87.     part1 := part1 + (c volume * w).
  88. ].
  89.  
  90. ('Part 2: %1' % {part1}) displayNl.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement