Day 7
This commit is contained in:
parent
170d9a3447
commit
2e5c426dcf
3 changed files with 100 additions and 31 deletions
|
|
@ -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:
|
|
||||||
[ self allPosnsDo:
|
|
||||||
[ :pos |
|
|
||||||
(self at: pos) = $^ ifTrue: [
|
|
||||||
origGuard := pos.
|
|
||||||
self at: pos put: $..
|
|
||||||
self resetGuard.
|
|
||||||
^guard.
|
|
||||||
]]].
|
|
||||||
^nil ]
|
|
||||||
|
|
||||||
resetGuard [ guard := origGuard. dir := Posn up. ]
|
initGuard
|
||||||
|
[ self allPosnsDo: [
|
||||||
|
:pos |
|
||||||
|
((self at: pos) = $^) ifTrue: [
|
||||||
|
origGuard := pos.
|
||||||
|
self at: pos put: $..
|
||||||
|
self resetGuard.
|
||||||
|
^guard.
|
||||||
|
]]]
|
||||||
|
|
||||||
|
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
47
days/day07.st
Normal 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.
|
||||||
|
|
@ -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 ]
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue