Advertisement
musifter

AoC 2023 day 16 (Smalltalk)

Dec 17th, 2023
1,213
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Smalltalk 4.00 KB | Source Code | 0 0
  1. #!/usr/local/bin/gst -q
  2.  
  3. Symbol extend [ value: arg  [^arg perform: self] ]
  4.  
  5. Integer extend [
  6.     bitCount [
  7.         | bits num |
  8.         num := self. bits := 0.
  9.         [num ~= 0] whileTrue: [num := num bitAnd: (num - 1).  bits := bits + 1].
  10.         ^bits
  11.     ]
  12. ]
  13.  
  14. Object subclass: BitMap [
  15.     | array loops |
  16.     BitMap class >> new: rows [
  17.         ^super new init: rows
  18.     ]
  19.  
  20.     init: rows [
  21.         array := Array new: rows withAll: 0.
  22.         loops := Set new.
  23.         ^self
  24.     ]
  25.  
  26.     at: row     [ ^array at: row ]
  27.  
  28.     set: pt     [ ^array at: pt y put: ((array at: pt y) bitOr: (1 bitShift: pt x)) ]
  29.     isSet: pt   [ ^((array at: pt y) bitAnd: (1 bitShift: pt x) ~= 0) ]
  30.  
  31.     bitCount    [ ^array inject: 0 into: [:a :b | a + b bitCount] ]
  32.     bitOr: map  [
  33.         (1 to: array size) do: [ :i |
  34.             array at: i put: ((array at: i) bitOr: (map at: i)).
  35.         ].
  36.         loops addAll: map loops.
  37.     ]
  38.  
  39.     addLoop: keyString     [ ^loops add: keyString ]
  40.     removeLoop: keyString  [ ^loops remove: keyString ]
  41.  
  42.     loops              [ ^loops ]
  43.     clearLoops         [ ^loops empty ]
  44. ]
  45.  
  46. Object subclass: MirrorGrid [
  47.     | grid dim memo visit |
  48.  
  49.     dirs := { (0 @ 1). (1 @ 0). (0 @ -1). (-1 @ 0) }.       " SENW "
  50.     piece := Dictionary from: {
  51.                  $| -> #(   #(1) #(1 3)   #(3) #(1 3) ).
  52.                  $- -> #( #(2 4)   #(2) #(2 4)   #(4) ).
  53.  
  54.                  $\ -> #( #(2) #(1) #(4) #(3) ).
  55.                  $/ -> #( #(4) #(3) #(2) #(1) ).
  56.  
  57.                  $. -> #( #(1) #(2) #(3) #(4) ).
  58.                  $~ -> #( #() #() #() #() )
  59.              }.
  60.  
  61.     MirrorGrid class >> new: mapArray [
  62.         ^super new init: mapArray
  63.     ]
  64.  
  65.     init: mapArray [
  66.         | sent |
  67.         dim   := mapArray size + 2.     " ASSUME: grid is square "
  68.         sent  := (1 to: dim) inject: '' into: [:a :b | a, '~'].
  69.         grid  := sent, (mapArray collect: [:row | '~', row, '~']) join, sent.
  70.         memo  := Dictionary new.
  71.         ^self
  72.     ]
  73.  
  74.     " Access to grid via Points "
  75.     at: pt           [^grid at: (pt y * dim) + pt x + 1]
  76.     at: pt put: chr  [^grid at: (pt y * dim) + pt x + 1 put: chr]
  77.  
  78.     size  [ ^dim - 2 ]
  79.  
  80.     recurseAt: pos movingDir: d [
  81.         | key map chr dir |
  82.         chr := self at: pos.
  83.         dir := d.
  84.  
  85.         (chr = $|) & (dir = 4) ifTrue: [ dir := 2 ].
  86.         (chr = $-) & (dir = 3) ifTrue: [ dir := 1 ].
  87.  
  88.         key := pos displayString, ':', dir asString.
  89.         (memo includesKey: key) ifTrue: [
  90.             (memo at: key) loops do: [ :l |
  91.                 (memo includesKey: l) ifTrue: [
  92.                     (memo at: key) bitOr: (memo at: l).
  93.                     (memo at: key) removeLoop: l.
  94.                 ]
  95.             ].
  96.             ^memo at: key
  97.         ].
  98.  
  99.         map := BitMap new: dim.
  100.  
  101.         (chr = $~) ifTrue: [^map].
  102.         map set: pos.
  103.         (visit includesKey: key) ifTrue: [
  104.             map addLoop: key.
  105.             ^map
  106.         ].
  107.         visit at: key put: 1.
  108.  
  109.         ((piece at: chr) at: dir) do: [:move |
  110.             map bitOr: (self recurseAt: pos + (dirs at: move) movingDir: move).
  111.         ].
  112.  
  113.         memo at: key put: ((memo at: key ifAbsent: [map]) bitOr: map).
  114.         ^map
  115.     ]
  116.  
  117.     fireFrom: pos dir: dir [
  118.         visit := Dictionary new.
  119.         ^self recurseAt: pos movingDir: dir.
  120.     ]
  121. ]
  122.  
  123. "
  124. | Mainline
  125. "
  126. ObjectMemory spaceGrowRate: 500.0.
  127.  
  128. grid := MirrorGrid new: stdin lines contents.
  129. map := grid fireFrom: (1 @ 1) dir: 2.
  130. part1 := map bitCount.
  131. stdout nextPutAll: ('Part 1: %1' % {part1}); nl; flush.
  132.  
  133. part2 := part1.
  134. (1 to: grid size) do: [ :i |
  135.     stderr nextPutAll: ('Pos: %1' % {i}); cr; flush.
  136.     part2 := part2 max: (grid fireFrom: (i @ 1)         dir: 1) bitCount.
  137.     part2 := part2 max: (grid fireFrom: (1 @ i)         dir: 2) bitCount.
  138.     part2 := part2 max: (grid fireFrom: (i @ grid size) dir: 3) bitCount.
  139.     part2 := part2 max: (grid fireFrom: (grid size @ i) dir: 4) bitCount.
  140. ].
  141.  
  142. ('Part 2: %1' % {part2}) displayNl.
  143.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement