Advertisement
musifter

AoC 2024, day 18 (smalltalk)

Dec 18th, 2024 (edited)
37
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Smalltalk 3.23 KB | Source Code | 0 0
  1. #!/usr/local/bin/gst -q
  2.  
  3. Symbol extend       [ value: arg [^arg perform: self] ]
  4. Point class extend  [ from: array  [^array first @ array second] ]
  5.  
  6. Object subclass: TimeGrid [
  7.     | grid dim end time |
  8.     dirs := {(-1@0). (0@-1). (0@1). (1@0)}.
  9.  
  10.     TimeGrid class >> new: size drops: array [^super new init: size drops: array]
  11.     init: size drops: dropList [
  12.         | sent |
  13.         dim := (size + 2) @ (size + 2).
  14.         end := (size - 1) @ (size - 1).
  15.         time := 0.
  16.  
  17.         " Mark clear grids with largest SmallInteger (2^62 - 1) "
  18.         grid := Array new: (size + 2) * (size + 2) withAll: SmallInteger largest.
  19.  
  20.         " Set Sentinel Walls (occupied at time -1)"
  21.         (1 to: dim x) do: [:i |
  22.             grid at: i put: -1.                          " top "
  23.             grid at: dim x * (dim y - 1) + i  put: -1.   " bottom "
  24.             grid at: (i-1) * dim y + 1  put: -1.         " left "
  25.             grid at: i * dim y  put: -1.                 " right "
  26.         ].
  27.  
  28.         " Set the drop block times in grid: "
  29.         dropList keysAndValuesDo: [:time :pos | self at: pos put: time ].
  30.         ^self
  31.     ]
  32.  
  33.     " Set current time (return self for convenience): "
  34.     time: t  [ time := t. ^self ]
  35.  
  36.     " Mark square as targeted at time "
  37.     at: pt put: time  [^grid at: ((pt y + 1) * dim x) + pt x + 2 put: time]
  38.  
  39.     " Get status of point at current time "
  40.     at: pt [
  41.         ^((grid at: ((pt y + 1) * dim x) + pt x + 2) <= time) ifTrue: [$#] ifFalse: [$.]
  42.     ]
  43.  
  44.     " Basic access "
  45.     dirs        [^dirs]
  46.     dim         [^dim]
  47.  
  48.     getRoute [
  49.         | queue visit state move targ |
  50.         queue := OrderedCollection with: {0@0. 0}.  " first: pos; second: time "
  51.         visit := Set new.
  52.  
  53.         [queue notEmpty] whileTrue: [
  54.             state := queue removeFirst.
  55.             (state first = end) ifTrue: [ ^state second ].
  56.  
  57.             (visit includes: state first) ifFalse: [
  58.                 visit add: state first.
  59.                 dirs do: [:d |
  60.                     move := state first + d.
  61.                     targ := self at: move.
  62.                     (targ == $.) ifTrue: [
  63.                         queue addLast: {move. state second + 1}.
  64.                     ]
  65.                 ]
  66.             ]
  67.         ].
  68.         ^nil
  69.     ]
  70.  
  71.     " Print grid at current time on stream "
  72.     printOn: aStream [
  73.         grid keysAndValuesDo: [:idx :t |
  74.             aStream nextPut: ((t < time) ifTrue: [$#] ifFalse: [$.]).
  75.             (idx \\ dim x = 0) ifTrue: [aStream nl].
  76.         ]
  77.     ]
  78. ]
  79.  
  80. "
  81. | Mainline
  82. "
  83. input := stdin lines contents collect: [:line |
  84.              Point from: ((line substrings: $,) collect: #asNumber).
  85.          ].
  86.  
  87. grid := TimeGrid new: 71 drops: input.
  88. (grid time: 1024) displayNl.
  89.  
  90. path := grid getRoute.
  91. ('Part 1: %1' % {path}) displayNl.
  92.  
  93. " Binary search for first blocking drop: "
  94. range := (1025 to: input size).
  95. [range size > 1] whileTrue: [
  96.     range displayNl.
  97.     mid  := range at: range size // 2.
  98.  
  99.     path  := (grid time: mid) getRoute.
  100.     range := (path isNil) ifTrue:  [range first to: mid]
  101.                           ifFalse: [mid+1 to: range last].
  102. ].
  103.  
  104. block := input at: range first.
  105. ('Part 2: %1,%2' % {block x. block y}) displayNl.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement