This commit is contained in:
Beatrice Szilvasy 2024-12-20 10:49:19 +00:00
parent 4df60f7775
commit 99d3aafa27
2 changed files with 102 additions and 0 deletions

96
days/day20.st Normal file
View file

@ -0,0 +1,96 @@
Object subclass: Racetrack [
| grid distToEnd start end trackLen allCheats |
rows: r
[ grid := Grid new rows: r.
self initTrack ]
initTrack
[ | pos dir step |
trackLen := 1.
grid allPosnsDo: [
:p | | c | c := grid at: p.
(c = $S or: [c = $E]) ifTrue: [
grid at: p put: $..
c = $S ifTrue: [start := p].
c = $E ifTrue: [end := p].
].
c = $. ifTrue: [ trackLen := trackLen + 1 ]].
distToEnd := Grid width: grid width
height: grid height
initWith: [:p | nil].
pos := start.
dir := {Posn up. Posn down. Posn left. Posn right} findFirstElt: [
:dir | self isEmpty: start + dir ].
step := 0.
[ pos = end ] whileFalse: [
distToEnd at: pos put: trackLen - step.
dir := {dir. dir rotateCw. dir rotateCcw} findFirstElt: [
:dir | self isEmpty: pos + dir ].
pos := pos + dir.
step := step + 1.
].
distToEnd at: end put: 0.
]
isEmpty: pos [ ^(grid at: pos) = $. ]
countCheatsWithTime: time
[ | total |
total := 0.
"allCheats := Bag new."
grid allPosnsDo: [
:pos | total := total + (self countCheatsFrom: pos withTime: time) ].
"allCheats printNl."
^total ]
countCheatsFrom: pos withTime: time
[ | dist |
dist := distToEnd at: pos.
dist ifNil: [^0].
"dist < 100 ifTrue: [^0]."
^self rangeCount: [
:dpos :ddist |
self validCheatFrom: pos dist: dist
to: dpos dist: ddist
withTime: time
]
inManhDistance: time
from: pos
maxDist: dist - 100. ]
validCheatFrom: pos dist: dist
to: dpos dist: ddist
withTime: time
[ | ctime saved |
ctime := (dpos x - pos x) abs +
(dpos y - pos y) abs.
ctime > time ifTrue: [^false].
saved := dist - ddist - ctime.
"saved > 0 ifTrue: [allCheats add: saved]."
^saved >= 100 ]
rangeCount: block
inManhDistance: distmh
from: pos
maxDist: mscore
[ | ddist dpos count px py doit |
count := 0.
dpos := Posn new.
px := pos x. py := pos y.
distmh negated to: distmh do: [
:dx | distmh negated to: distmh do: [
:dy |
(dx abs + dy abs) <= distmh ifTrue: [
dpos x: px + dx; y: py + dy.
ddist := distToEnd at: dpos.
ddist ifNotNil: [
(block value: dpos value: ddist)
ifTrue: [ count := count + 1 ]]]]].
^count ]
]
AOC input: [ Racetrack new rows: stdin toLines asArray ];
part1: 2; part2: 20;
result: [ :track :time | track countCheatsWithTime: time ];
finish.

View file

@ -156,6 +156,12 @@ Iterable extend [
intoCollection: acc [ self do: [:x | acc add: x]. ^acc ] intoCollection: acc [ self do: [:x | acc add: x]. ^acc ]
] ]
SequenceableCollection extend [
findFirstElt: block [ ^self at: (self findFirst: block) ]
findFirstElt: block ifAbsent: abs
[ ^self at: (self findFirst: block) ifAbsent: abs ]
]
Collection extend [ Collection extend [
transposed transposed
[ ^(self size <= 0) ifTrue: [ ^(self size <= 0) ifTrue: