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 [^visitedPosns]
|
||||
dir [^dir]
|
||||
guard
|
||||
[ guard ifNotNil: [:it|^it] ifNil:
|
||||
[ self allPosnsDo:
|
||||
[ :pos |
|
||||
(self at: pos) = $^ ifTrue: [
|
||||
dir [^dir] guard [^guard]
|
||||
|
||||
initGuard
|
||||
[ self allPosnsDo: [
|
||||
:pos |
|
||||
((self at: pos) = $^) ifTrue: [
|
||||
origGuard := pos.
|
||||
self at: pos put: $..
|
||||
self resetGuard.
|
||||
^guard.
|
||||
]]].
|
||||
^nil ]
|
||||
]]]
|
||||
|
||||
resetGuard [ guard := origGuard. dir := Posn up. ]
|
||||
resetGuard
|
||||
[ origGuard ifNil: [self initGuard].
|
||||
guard := origGuard.
|
||||
dir := Posn up. ]
|
||||
|
||||
isSolid: p [ ^(self at: p) = $# ]
|
||||
isEmpty: p [ ^(self at: p) = $. ]
|
||||
|
||||
copy [ ^Grid new rows: rows; restore: self state ]
|
||||
|
||||
stepGuard
|
||||
[ self guard.
|
||||
[self isSolid: (guard + dir)] whileTrue:
|
||||
[ [self isSolid: guard + dir] whileTrue:
|
||||
[ dir := dir rotateCcw. ].
|
||||
guard := guard + dir. ]
|
||||
|
||||
state [^{self guard . self dir}]
|
||||
state [^{guard . dir}]
|
||||
restore: st [guard := st at: 1. dir := st at: 2]
|
||||
|
||||
guardOob [^(self at: self guard) isNil]
|
||||
guardOob [^(self at: 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]].
|
||||
stepToTurn
|
||||
[ guard := guard copy.
|
||||
[self isSolid: guard + dir] whileTrue: [dir := dir rotateCcw].
|
||||
[self isEmpty: guard] whileTrue: [guard += dir].
|
||||
(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 ]
|
||||
]
|
||||
|
||||
AOC input: [ Grid new rows: stdin toLines asArray ];
|
||||
part1: [ :grid | | posns |
|
||||
posns := Set new.
|
||||
grid walkDo: [posns add: grid guard].
|
||||
part1: [ :grid | | posns prev |
|
||||
posns := Dictionary new. prev := nil.
|
||||
grid walkDo: [
|
||||
posns at: grid guard ifAbsentPut: [prev].
|
||||
prev := grid state].
|
||||
grid visitedPosns: posns.
|
||||
posns ];
|
||||
posns size ];
|
||||
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 ];
|
||||
grid visitedPosns removeKey: grid guard.
|
||||
grid visitedPosns associations count:
|
||||
[ :ass |
|
||||
grid at: ass key put: $#.
|
||||
[grid hasCycleFrom: ass value]
|
||||
ensure: [grid at: ass key put: $.] ] ];
|
||||
result: [ :grid :part | part value: grid resetGuard ];
|
||||
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 ]
|
||||
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
|
||||
[ saved ifNotNil: [
|
||||
|
|
@ -192,8 +192,14 @@ Object extend [ chain [ ^MessageChain new pipelineValue: self ] ]
|
|||
|
||||
Object subclass: Posn [
|
||||
| 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 [ 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 ]
|
||||
|
||||
rotateCw [ ^Posn x: y y: x negated ]
|
||||
rotateCcw [ ^Posn x: y negated y: x ]
|
||||
rotate180 [ ^Posn x: x negated y: y negated ]
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue