--- Day 13: Crane Machines ---

December 13

Listening to: N.U.D.E. | Liquid DnB / Jungle Mix


This one looks slightly annoying to parse, but not exactly the worst. The actual problem doesn't seem that bad though: First, find every possible solution to get to a given prize's X position given the X values, then see if the Y values would also reach there. There can only be so many valid values for just X, and only so many of those for Y, right?

Or maybe I can just brute force it?

private int GetLeastTokensBrute(Machine machine)
{
    int least = int.MaxValue;

    for (int a = 0; a <= 100; a++)
    {
        for (int b = 0; b <= 100; b++)
        {
            if ((machine.ax * a) + (machine.bx * b) == machine.targetX &&
                (machine.ay * a) + (machine.by * b) == machine.targetY)
            {
                var tokens = (a * 3) + b;
                least = Math.Min(tokens, least);
            }
        }
    }

    return least;
}

I did try a more clever solution first, but it got a wrong answer on the input and I'm not sure why. This brute force solution somehow runs faster and gets the right answer.


Yep, I expected this kind of extreme change for the solution. Add a whole 10000000000000 to the goal range. Bleh. I do have to get clever anyway.

It's a linear equation kind of solver isn't it.

I admit, I'm not the best at linear equations, but admittedly this was simple enough that I was able to muddle through it. It would have been far easier if I could use some Matrix math, but I didn't want to go through the trouble of getting a library for it, or implementing matrix math myself, so I just kinda... hard-coded it for this solution I guess? That and some trial-and-error.

private long GetLeastTokensLinear(Machine m)
{
    var bPress = (m.targetY * m.ax - m.targetX * m.ay) / (m.by * m.ax - m.bx * m.ay);
    var aPress = (m.targetX - bPress * m.bx) / m.ax;

    if (aPress > 0 &&
        bPress > 0 &&
        (aPress * m.ax + bPress * m.bx) == m.targetX &&
        (aPress * m.ay + bPress * m.by) == m.targetY)
    {
        return (aPress * 3) + bPress;
    }

    return 0;
}

At least it runs fast.


Time taken: 90 minutes

My solutions for today's puzzles