This commit is contained in:
Beatrice Szilvasy 2024-12-07 09:53:12 +00:00
parent 170d9a3447
commit 2e5c426dcf
3 changed files with 100 additions and 31 deletions

View file

@ -3,56 +3,72 @@ Grid extend [
visitedPosns: n [visitedPosns:=n] visitedPosns: n [visitedPosns:=n]
visitedPosns [^visitedPosns] visitedPosns [^visitedPosns]
dir [^dir] dir [^dir] guard [^guard]
guard
[ guard ifNotNil: [:it|^it] ifNil: initGuard
[ self allPosnsDo: [ self allPosnsDo: [
[ :pos | :pos |
(self at: pos) = $^ ifTrue: [ ((self at: pos) = $^) ifTrue: [
origGuard := pos. origGuard := pos.
self at: pos put: $.. self at: pos put: $..
self resetGuard. self resetGuard.
^guard. ^guard.
]]]. ]]]
^nil ]
resetGuard [ guard := origGuard. dir := Posn up. ] resetGuard
[ origGuard ifNil: [self initGuard].
guard := origGuard.
dir := Posn up. ]
isSolid: p [ ^(self at: p) = $# ] isSolid: p [ ^(self at: p) = $# ]
isEmpty: p [ ^(self at: p) = $. ]
copy [ ^Grid new rows: rows; restore: self state ] copy [ ^Grid new rows: rows; restore: self state ]
stepGuard stepGuard
[ self guard. [ [self isSolid: guard + dir] whileTrue:
[self isSolid: (guard + dir)] whileTrue:
[ dir := dir rotateCcw. ]. [ dir := dir rotateCcw. ].
guard := guard + dir. ] guard := guard + dir. ]
state [^{self guard . self dir}] state [^{guard . dir}]
restore: st [guard := st at: 1. dir := st at: 2] restore: st [guard := st at: 1. dir := st at: 2]
guardOob [^(self at: self guard) isNil] guardOob [^(self at: guard) isNil]
walkDo: block walkDo: block
[ [self guardOob] whileFalse: [block value. self stepGuard] ] [ [self guardOob] whileFalse: [block value. self stepGuard] ]
hasCycle stepToTurn
[ | fast | fast := self resetGuard copy. [ guard := guard copy.
[fast guardOob] whileFalse: [self isSolid: guard + dir] whileTrue: [dir := dir rotateCcw].
[self stepGuard. fast stepGuard stepGuard. [self isEmpty: guard] whileTrue: [guard += dir].
self state = fast state ifTrue: [^true]]. (self isSolid: guard) ifTrue: [guard -= dir] ]
hasCycleFrom: state
[ | seen st |
seen := Set new.
self restore: state.
[self guardOob] whileFalse:
[self stepToTurn. st := self state.
(seen includes: st) ifTrue: [^true].
seen add: st].
^false ] ^false ]
] ]
AOC input: [ Grid new rows: stdin toLines asArray ]; AOC input: [ Grid new rows: stdin toLines asArray ];
part1: [ :grid | | posns | part1: [ :grid | | posns prev |
posns := Set new. posns := Dictionary new. prev := nil.
grid walkDo: [posns add: grid guard]. grid walkDo: [
posns at: grid guard ifAbsentPut: [prev].
prev := grid state].
grid visitedPosns: posns. grid visitedPosns: posns.
posns ]; posns size ];
part2: [ :grid | | i | i := 1. part2: [ :grid | | i | i := 1.
grid visitedPosns select: grid visitedPosns removeKey: grid guard.
[ :p | grid at: p put: $#. i printNl. i := i + 1. grid visitedPosns associations count:
[grid hasCycle] ensure: [grid at: p put: $.] ] ]; [ :ass |
result: [ :grid :part | (part value: grid resetGuard) size ]; grid at: ass key put: $#.
[grid hasCycleFrom: ass value]
ensure: [grid at: ass key put: $.] ] ];
result: [ :grid :part | part value: grid resetGuard ];
finish. finish.

47
days/day07.st Normal file
View file

@ -0,0 +1,47 @@
Object subclass: AddOp
[ tryDo: n target: tgt [ ^tgt - n ] ]
Object subclass: MulOp
[ tryDo: n target: tgt
[ (tgt rem: n) = 0 ifFalse: [^nil].
^tgt quo: n ] ]
MulOp subclass: CatOp
[ tryDo: n target: tgt
[ | p10 | p10 := 10 raisedTo: ((n + 1) log: 10) ceiling.
^super tryDo: p10 target: tgt - n ] ]
Object subclass: Equation [
| target numbers |
target: n [target:=n] numbers: n [numbers:=n]
testValue [^target]
printOn: dst [dst << target << ': ' << numbers]
canSolveFrom: idx target: tgt with: ops
[ | n | n := numbers at: idx.
idx = 1 ifTrue: [^n = tgt].
tgt < n ifTrue: [^false].
ops do: [
:op |
(op tryDo: n target: tgt) ifNotNil:
[:it|(self canSolveFrom: idx - 1 target: it with: ops) ifTrue: [^true]]].
^false ]
canSolveWith: ops [^self canSolveFrom: numbers size target: target with: ops]
]
Equation class extend [
parse: line
[ ^(line tokenize: ': ') letArrayInBlock:
[ :target :numbers |
Equation new target: target asNumber;
numbers: ((numbers tokenize: ' ') collect: [:it|it asNumber]) ] ]
]
AOC input: [ stdin toLines collect: [:line | Equation parse: line] ];
part1: {MulOp new. AddOp new};
part2: {CatOp new. MulOp new. AddOp new};
result: [ :eqns :part |
eqns chain select: [:eqn | eqn canSolveWith: part];
collect: [:it|it testValue];
sum ];
finish.

View file

@ -7,7 +7,7 @@ AOC class extend [
part2: p2Block [ savedP2 := p2Block ] part2: p2Block [ savedP2 := p2Block ]
result: mapBlock [ mapper := mapBlock ] result: mapBlock [ mapper := mapBlock ]
output: value part: part [ stdout << 'Part ' << part << ': ' << value; nl. ] output: value part: part [ stdout << 'Part ' << part << ': ' << value; nl; flush. ]
runPart: saved part: part arg: arg runPart: saved part: part arg: arg
[ saved ifNotNil: [ [ saved ifNotNil: [
@ -192,8 +192,14 @@ Object extend [ chain [ ^MessageChain new pipelineValue: self ] ]
Object subclass: Posn [ Object subclass: Posn [
| x y | x [^x] y [^y] x: n [x:=n] y: n [y:=n] | x y | x [^x] y [^y] x: n [x:=n] y: n [y:=n]
copy [ ^Posn x: x y: y ]
+ o [ ^Posn x: x + o x y: y + o y ] + o [ ^Posn x: x + o x y: y + o y ]
+= o [ self x: x + o x; y: y + o y. ]
- o [ ^Posn x: x - o x y: y - o y ]
-= o [ self x: x - o x; y: y - o y. ]
* n [ ^Posn x: x * n y: y * n ] * n [ ^Posn x: x * n y: y * n ]
rotateCw [ ^Posn x: y y: x negated ] rotateCw [ ^Posn x: y y: x negated ]
rotateCcw [ ^Posn x: y negated y: x ] rotateCcw [ ^Posn x: y negated y: x ]
rotate180 [ ^Posn x: x negated y: y negated ] rotate180 [ ^Posn x: x negated y: y negated ]