47 lines
1.5 KiB
Smalltalk
47 lines
1.5 KiB
Smalltalk
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.
|