Day 17 - Take aim

Ok. I nearly didn't start this one. I took a look at the puzzle, and thought "I can work out how to simulate the probe but I've got no idea how to work out the best start value". This feels like I should be able to solve with maths somehow, like reason about the graph, solve for the intercept and there is it. Except that my maths isn't strong enough to do that.

But I then started dreaming about it, and thinking about it idly, and an idea came to me, an idea that I want to try out.

Todays solution is going to be far more functional than previous weeks.

My idea was to write a simple function that can take the initial variables and calculate each successive step each time its called. For any given start values, we can then generate an infinite stream of coordinates. We're going to then filter that stream for anything that goes outside our bounds, that's the edge of the target box, or above an arbitrary height or behind the sub. Finally we'll search that stream for the maximum y coordinate. That will give us a mapping of start settings to maximum y.

We'll then have some settings that we can play with. We're going to need to explore the solution space for those settings, but we won't know whats possible. At a gut feel, based on the numbers, anything that has an x-increment of more than half the total x bound is pointless, as we wont have more than 1 point in the stream. On the y coordinate test, I don't really know what a sensible number is, so lets try around -1000 to 1000 and see if that works

Finally, there's a thought. I don't actually ever think I want an infinite range, stuff with infinite loops makes me nervous, so I'm going to hardcode a global MAX_ITERATIONS of around 1000. That should be plenty

Ok, we have a generator that can create the path for any probe, now we need to find it either going out of bounds or hitting the target.

We can filter out anything that goes out of bounds first

Now we need something to tell us if the entire stream hits the goal or not. This is the same as the bounds filter, just for a smaller bounds

Ok, we can finda target that hits a goal.

But I've had a thought, instead of using the bounds filter, we might want a generator that stops at the bounds as well, that means that we don't have to generate a thousand items for a poor shot. It also means we can drop the islice calls

Ok, we can now generate steps, filter for those which hit a goal.

We can try to different numbers and see how they work. We're going to have to try a range of numbers. The x probably needs to go from 1 to 1/2 the start of the target area. The y needs to go from 0 to ... at a guess about the same bound.

Let's give that a try for a search, which should give us a couple of hundred combinations. We can then filter those for only those sequences that contain at least 1 goal hitting step, and then we can search that list for the one with the highest y

Ok, We can find the highest Y, but we need to parse the original file, and we need to work out if we're guessing the right numbers.

We'll start with parsing, but for the numbers, we're going to have to rely on asking it to find an answer and then seeing if the adventofcode website finds it.

Ok, lets try that production data

That's not right, but at 861 y, I think we're way too small with a maximum y of 1000, so lets increase that by 10x

We found it!

Part 2 - Phew, what a relief

Ok, our next part requires us to simply list all the initial velocities that result in a valid firing solution, luckily, we already wrote that with findValidFiringSolutions, so we should just be able to run that and see if it works.

Let's try that on our test set and see what works

Hmm, we don't have enough solutions. Let's take a look at the examples and see what we've done.

Oh, I see a problem. I always assumed that we were looking for paths that went up and down, hence the x//2, but in fact, we obviously can also use every single location within the target area as the first step as well.

Let's change our initial bounds to cover the entire target area as well as see if that helps

Well that was a pain to find. The Y coordinate is still a nightmare, I can't work out how to come up with sensible guesses.

We know that the highest that the Y coordinate ever gets is around 3500, so lets hope that a maximum of 1000 is enough.

Overall, I'm really unhappy with this one. A 6 second runtime makes me think that I'm missing something clever, but this was decidedly horrible.