Day 13
This commit is contained in:
parent
e4a0a46036
commit
c4bac0aa4f
2 changed files with 89 additions and 0 deletions
57
days/day13.st
Normal file
57
days/day13.st
Normal file
|
|
@ -0,0 +1,57 @@
|
||||||
|
Object subclass: Machine [
|
||||||
|
| vecA vecB prize |
|
||||||
|
parse: line
|
||||||
|
[ line scanf: 'Button A: X+%d, Y+%d Button B: X+%d, Y+%d Prize: X=%d, Y=%d'
|
||||||
|
with: [ :aX :aY :bX :bY :pX :pY |
|
||||||
|
vecA := Posn x: aX y: aY.
|
||||||
|
vecB := Posn x: bX y: bY.
|
||||||
|
prize := Posn x: pX y: pY ] ]
|
||||||
|
|
||||||
|
printOn: st
|
||||||
|
[ st << '{A: ' << vecA << '; B: ' << vecB << '; P: ' << prize << '}' ]
|
||||||
|
|
||||||
|
priceA [^3] priceB [^1]
|
||||||
|
|
||||||
|
solve: offV
|
||||||
|
[ ^(Mat2 col: vecA col: vecB) inverse
|
||||||
|
ifNotNil: [
|
||||||
|
:inv | | vec |
|
||||||
|
vec := inv *> (prize + offV).
|
||||||
|
(vec x isInteger and: [vec y isInteger])
|
||||||
|
ifTrue: [^vec]
|
||||||
|
ifFalse: [^nil] ]
|
||||||
|
ifNil: [
|
||||||
|
"linearly dependent -- not actually reached"
|
||||||
|
| slvA slvB |
|
||||||
|
'Linearly dependent!' displayNl.
|
||||||
|
slvA := self solveLinDep: vecA.
|
||||||
|
slvB := self solveLinDep: vecB.
|
||||||
|
slvA ifNil: [
|
||||||
|
slvB ifNil: [^nil]
|
||||||
|
ifNotNil: [^Posn x: 0 y: slvB]].
|
||||||
|
slvB ifNil: [^Posn x: slvA y: 0].
|
||||||
|
((slvA * self priceA) <= (slvB * self priceB))
|
||||||
|
ifTrue: [^Posn x: slvA y: 0]
|
||||||
|
ifFalse: [^Posn x: 0 y: slvB]] ]
|
||||||
|
|
||||||
|
tokenCost: soln
|
||||||
|
[ soln ifNil: [^0].
|
||||||
|
^(soln x * self priceA) + (soln y * self priceB) ]
|
||||||
|
|
||||||
|
solveCost: offV [ ^self tokenCost: (self solve: offV) ]
|
||||||
|
|
||||||
|
solveLinDep: vec
|
||||||
|
[ | sf |
|
||||||
|
sf := prize x / vec x.
|
||||||
|
(prize y / vec y) = sf ifFalse: [^nil].
|
||||||
|
sf isInteger ifFalse: [^nil].
|
||||||
|
^sf ]
|
||||||
|
]
|
||||||
|
|
||||||
|
AOC input: [ stdin chain contents; tokenize: (String with: $<10> with: $<10>);
|
||||||
|
collect: [:it | Machine new parse: it] ];
|
||||||
|
part1: 0; part2: 10000000000000;
|
||||||
|
result: [ :machines :off | | offV |
|
||||||
|
offV := Posn x: off y: off.
|
||||||
|
machines inject: 0 into: [:a :it | a + (it solveCost: offV)] ];
|
||||||
|
finish.
|
||||||
|
|
@ -236,6 +236,38 @@ Posn class extend [
|
||||||
zero [^Posn x: 0 y: 0]
|
zero [^Posn x: 0 y: 0]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
Object subclass: Mat2 [
|
||||||
|
| m11 m12
|
||||||
|
m21 m22 |
|
||||||
|
m11: n11 m12: n12 m21: n21 m22: n22 [m11:=n11. m12:=n12. m21:=n21. m22:=n22]
|
||||||
|
|
||||||
|
determinant [ ^(m11 * m22) - (m12 * m21) ]
|
||||||
|
inverse
|
||||||
|
[ | det r rn | det := self determinant.
|
||||||
|
det = det zero ifTrue: [^nil].
|
||||||
|
r := det reciprocal.
|
||||||
|
rn := r negated.
|
||||||
|
^Mat2 m11: r * m22 m12: rn * m12
|
||||||
|
m21: rn * m21 m22: r * m11 ]
|
||||||
|
|
||||||
|
*> p [ ^Posn x: (m11 * p x) + (m12 * p y)
|
||||||
|
y: (m21 * p x) + (m22 * p y) ]
|
||||||
|
|
||||||
|
printOn: st [ st << ('{ %1, %2 ; %3, %4 }' % {m11. m12. m21. m22}) ]
|
||||||
|
]
|
||||||
|
Mat2 class extend [
|
||||||
|
m11: n11 m12: n12 m21: n21 m22: n22
|
||||||
|
[ ^self new m11: n11 m12: n12 m21: n21 m22: n22 ]
|
||||||
|
|
||||||
|
col: a col: b
|
||||||
|
[ ^self m11: a x m12: b x
|
||||||
|
m21: a y m22: b y ]
|
||||||
|
|
||||||
|
row: a row: b
|
||||||
|
[ ^self m11: a x m12: a y
|
||||||
|
m21: b x m22: b y ]
|
||||||
|
]
|
||||||
|
|
||||||
Array extend [ asPosn [ ^Posn x: (self at: 1) y: (self at: 2) ] ]
|
Array extend [ asPosn [ ^Posn x: (self at: 1) y: (self at: 2) ] ]
|
||||||
Iterable extend [ asPosns [ ^self collect: [:it | it asPosn] ] ]
|
Iterable extend [ asPosns [ ^self collect: [:it | it asPosn] ] ]
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue