Advertisement
musifter

AoC 2023 day 17, part 2 (Smalltalk)

Dec 19th, 2023 (edited)
1,348
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Smalltalk 2.89 KB | Source Code | 0 0
  1. #!/usr/local/bin/gst -q
  2.  
  3. FileStream fileIn: '../../smalltalk/Priority.st'!
  4.  
  5. Symbol extend  [ value: arg  [^arg perform: self] ]
  6. Integer extend [ %% modulus  [^self - 1 \\ modulus + 1] ]
  7.  
  8. Object subclass: DigitGrid [
  9.     | grid dimY dimX visit dirs start end |
  10.  
  11.     DigitGrid class >> new: arrayStrings [
  12.         ^(super new) init: arrayStrings.
  13.     ]
  14.  
  15.     init: mapArray [
  16.         | sent |
  17.         dimY  := mapArray size + 2.
  18.         dimX  := (mapArray at: 1) size + 2.
  19.         dirs  := {dimX. 1. -1 * dimX. -1}.
  20.  
  21.         start := dimX + 2.
  22.         end   := dimX * (dimY - 1) - 1.
  23.  
  24.         sent  := (1 to: dimX) inject: '' into: [:a :b | a, '0'].
  25.         grid  := sent, (mapArray collect: [:row | '0', row, '0']) join, sent.
  26.         grid  := grid asArray collect: #digitValue.
  27.  
  28.         visit := Array new: grid size * 2 withAll: SmallInteger largest.
  29.         ^self
  30.     ]
  31.  
  32.     " Access to grid by index to flat array "
  33.     at: idx   [ ^grid at: idx ]
  34.  
  35.     start  [ ^start ]
  36.     end    [ ^end   ]
  37.  
  38.     visited: idx from: dir  [^visit at: idx + (grid size * (dir \\ 2))]
  39.  
  40.     visit: idx from: dir at: cool  [
  41.         ^visit at: idx + (grid size * (dir \\ 2)) put: cool
  42.     ]
  43.  
  44.     getDirDelta: d  [ ^dirs at: d ]
  45.     getTurns: dir   [ ^{(dir + 1) %% 4. (dir - 1) %% 4} ]
  46. ]
  47.  
  48. "
  49. | Mainline
  50. "
  51. ObjectMemory spaceGrowRate: 500.0.
  52.  
  53. Eval [
  54.     grid := DigitGrid new: (stdin lines contents).
  55.     start := grid start.
  56.     end   := grid end.
  57.  
  58.     queue := PriorityQueue new.
  59.     queue at: 0 insert: {0. start. 1}.
  60.     queue at: 0 insert: {0. start. 2}.
  61.  
  62.     time := 0.
  63.  
  64.     [ queue notEmpty ] whileTrue: [
  65.         | state cool pos dir |
  66.         state := queue next.
  67.         cool  := state first.
  68.         pos   := state second.
  69.         dir   := state third.
  70.  
  71.         ((time := time + 1) \\ 50000 == 1) ifTrue: [
  72.             stderr nextPutAll: ('Cool: %1' % {cool}); cr; flush.
  73.         ].
  74.  
  75.         (pos = end) ifTrue: [
  76.             ^('Part 2: %1' % {cool}) displayNl.
  77.         ].
  78.  
  79.         ((grid visited: pos from: dir) > cool) ifTrue: [
  80.             grid visit: pos from: dir at: cool.
  81.  
  82.             (grid getTurns: dir) do: [ :turn |
  83.                | newPos newCool cooling delta i done |
  84.  
  85.                 newPos  := pos.
  86.                 newCool := cool.
  87.                 delta   := grid getDirDelta: turn.
  88.  
  89.                 i := 1.
  90.                 done := false.
  91.  
  92.                 [(i <= 10) & done not] whileTrue: [
  93.                     newPos  := newPos + delta.
  94.                     i := i + 1.
  95.                     ((cooling := grid at: newPos) = 0) ifTrue: [
  96.                         done := true.  " Hit edge sentinel "
  97.                     ] ifFalse: [
  98.                         newCool := newCool + cooling.
  99.                         (i > 4) ifTrue: [queue at: newCool insert: {newCool. newPos. turn}].
  100.                     ]
  101.                 ]
  102.             ]
  103.         ]
  104.     ]
  105. ]
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement