Advent of Code 2024 Day 13
Part 1
Big gulp: every permutation?
Another dreaded shortest path
challenge.
Thankfully, it sounds doable with brute force, thanks to the constraint specified:
- No more than
100
button presses
That means if there is a solution, it exists within 1
of 10,000
permutations: 100 * 100 = 10,000
Each machine is represented as 3 lines (plus 1 empty line) in the input, totaling 4 lines.
My input is 1280
lines long.
Thus, the most computations my algorithm would make is:
100 * 100 ------ 10000 * 1280 / 4 ------ 320 ====== 3200000
3.2M
computations isn't bad at all.
Brute force may be an option for Part 1.
Worth a try!
Attempting to brute-force the solution
Turning strings into integers
First, I need to extract the six important numbers from each machine's input:
input .split('\n') .map(block => { let [AX, AY, BX, BY, PX, PY] = [ ...block.matchAll(/d+/g).map(el => +el[0]) ] })
I wrote that here. Then I ran it in a code editor.
Then I debugged and fixed it until I saw the code I expected.
My working algorithm looks like this:
input .split('\n\n') .map(block => [ ...block.matchAll(/\d+/g) ].map(el => +el[0]) )
I made some silly mistakes.
But I now see this in my console:
[ [ 94, 34, 22, 67, 8400, 5400 ], [ 26, 66, 67, 21, 12748, 12176 ], [ 17, 86, 84, 37, 7870, 6450 ], [ 69, 23, 27, 71, 18641, 10279 ] ]
Perfect!
Prepping for 10k permutations
Some tracking variables with starter amounts, and nested loops that count to 100
, all inside a reduce
that processes each machine:
let part1 = input.reduce( (total, machine) => { let [AX, AY, BX, BY, PX, PY] = machine let min = Infinity let minA = Infinity let minB = Infinity for (let A = 0; A <= 100; A++) { for (let B = 0; B <= 100; B++) { } } return total })
Next, some condi-tions, addi-tions and multiplica-tions:
// inside the nested for loops if ((A * AX + B * BX == PX) && (A * AY + B * BY == PY)) { if (3 * A + B < min) { minA = 3 * A minB = B min = minA + minB } }
Again, I wrote that first here.
Then I copy-pasted it into my code editor and ran it.
And I saw the expected winning token amounts!
I got excited and wrote the rest of the algorithm.
After some clean-up and debugging, here's the final working code:
let part1 = input.reduce( (total, machine) => { let [AX, AY, BX, BY, PX, PY] = machine let min = Infinity for (let A = 0; A <= 100; A++) { for (let B = 0; B <= 100; B++) { if ((A * AX + B * BX == PX) && (A * AY + B * BY == PY)) { if (3 * A + B < min) { min = 3 * A + B } } } } if (min < Infinity) { total += min } return total }, 0)
Running it on the example input generates the correct answer.
What about on my puzzle input?
...
Well, it finished within a second.
And generated an answer in the 10's of thousands.
Is it correct?
...
It is!
Sweet!
I don't anticipate having the computer science knowledge to refactor my brute-force algorithm into something that can solve Part 2.
I'm still excited to see the twist, though!
Part 2
Yyyyuuupp. Just what I suspected.
1 trillion higher? Yikes!
Just like yesterday's Part 2, I'm stumped.
Bummer.
After a 10-day streak of 2-stars, I'm on a 3-day streak of 1-stars.
To be fair, this is usually the spot each year where I get 0 or 1 stars.
At least I got 1!
Onward to Day 14.
Top comments (0)