Advertisement
musifter

AoC 2024, day 20 (smalltalk)

Dec 20th, 2024
46
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Smalltalk 2.21 KB | Source Code | 0 0
  1. #!/usr/local/bin/gst -q
  2.  
  3. " Extend Point for Manhattan distance: "
  4. Point extend [ distance: pt [^(self x - pt x) abs + (self y - pt y) abs] ]
  5.  
  6. " Class to convert input into a Array of the path: "
  7. Object subclass: TextGrid [
  8.     | grid dim start end |
  9.     dirs  := {(0@-1). (-1@0). (1@0). (0 @1)}.
  10.  
  11.     TextGrid class >> new: mapArray [^super new init: mapArray]
  12.     init: mapArray [
  13.         | sentinel |
  14.         dim  := (mapArray first size) @ (mapArray size).
  15.         grid := mapArray join.
  16.  
  17.         start := self toCoord: (grid indexOfSubCollection: 'S').
  18.         end   := self toCoord: (grid indexOfSubCollection: 'E').
  19.         ^self
  20.     ]
  21.  
  22.     " Access to grid via Points "
  23.     at: pt           [^grid at: (pt y * dim x) + pt x + 1]
  24.     at: pt put: chr  [^grid at: (pt y * dim x) + pt x + 1 put: chr]
  25.     toCoord: idx     [^(idx - 1 \\ dim x) @ (idx - 1 // dim x)]
  26.  
  27.     " Return path from start to end as and array of Points "
  28.     getPath [
  29.         | path pos back dir |
  30.         path := OrderedCollection with: start.
  31.         pos  := start.
  32.         back := (0@0).
  33.  
  34.         [pos ~= end] whileTrue: [
  35.             dir  := dirs detect: [:d | ((self at: (pos + d)) ~= $#) and: [back ~= d]].
  36.             back := dir * -1.
  37.             pos  := path add: (pos + dir).
  38.         ].
  39.  
  40.         ^path asArray
  41.     ]
  42. ]
  43.  
  44. "
  45. | Mainline
  46. "
  47. grid := TextGrid new: stdin lines contents.
  48. path := grid getPath.
  49.  
  50. " Done with the grid, lets just use the path list for the rest. "
  51. part1 := 0.
  52. part2 := 0.
  53. targ  := 100.       " Target number of picoseconds for a cheat "
  54.  
  55. " Compare points that are far enough apart on the path to potentially gain target."
  56. (1 to: path size - (targ + 2)) do: [:i |
  57.     (i \\ 50 == 0) ifTrue: [
  58.         stderr nextPutAll: ('[%1] %2' % {i. part2}); cr; flush.
  59.     ].
  60.  
  61.     (i + (targ + 2) to: path size) do: [:j |
  62.         dist := (path at: i) distance: (path at: j).
  63.  
  64.         " Check allowed distance, and if we didn't lose too much time. "
  65.         (dist <= 20 and: [j - i - dist >= targ]) ifTrue: [
  66.             part2 := part2 + 1.
  67.             (dist == 2) ifTrue: [part1 := part1 + 1].
  68.         ].
  69.     ].
  70. ].
  71.  
  72. stdout nl.
  73. ('Part 1: %1' % {(part1)}) displayNl.
  74. ('Part 2: %1' % {(part2)}) displayNl.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement