aoc2024/days/day06.st
2024-12-06 11:16:02 +00:00

58 lines
1.7 KiB
Smalltalk

Grid extend [
| guard dir origGuard visitedPosns |
visitedPosns: n [visitedPosns:=n]
visitedPosns [^visitedPosns]
dir [^dir]
guard
[ guard ifNotNil: [:it|^it] ifNil:
[ self allPosnsDo:
[ :pos |
(self at: pos) = $^ ifTrue: [
origGuard := pos.
self at: pos put: $..
self resetGuard.
^guard.
]]].
^nil ]
resetGuard [ guard := origGuard. dir := Posn up. ]
isSolid: p [ ^(self at: p) = $# ]
copy [ ^Grid new rows: rows; restore: self state ]
stepGuard
[ self guard.
[self isSolid: (guard + dir)] whileTrue:
[ dir := dir rotateCcw. ].
guard := guard + dir. ]
state [^{self guard . self dir}]
restore: st [guard := st at: 1. dir := st at: 2]
guardOob [^(self at: self guard) isNil]
walkDo: block
[ [self guardOob] whileFalse: [block value. self stepGuard] ]
hasCycle
[ | fast | fast := self resetGuard copy.
[fast guardOob] whileFalse:
[self stepGuard. fast stepGuard stepGuard.
self state = fast state ifTrue: [^true]].
^false ]
]
AOC input: [ Grid new rows: stdin toLines asArray ];
part1: [ :grid | | posns |
posns := Set new.
grid walkDo: [posns add: grid guard].
grid visitedPosns: posns.
posns ];
part2: [ :grid | | i | i := 1.
grid visitedPosns select:
[ :p | grid at: p put: $#. i printNl. i := i + 1.
[grid hasCycle] ensure: [grid at: p put: $.] ] ];
result: [ :grid :part | (part value: grid resetGuard) size ];
finish.