Day 2

Great, it's another one of these coordinate puzzles. We're going to get a set of directions that our boat is going to take. I like these, as I got my programming career started with games programming, and so anything to do with coordinates, maps, and moving things around is a set of problems for which I already have some of the tools.

There's a fun twist on this one. In previous years, it's often been about rotating, or moving north, east, south and west. But in this case, we've only got 3 instructions, forward, up and down. Furthermore, our depth is measured as a distance from the surface of the sea, so going down is going to increase our depth. i.e. if we're at the surface, we're at depth 0, but going down will take us down to depth 1, and so on.

In this case, we need to know what depth we end up with. We can do this the simple to understand, but harder to implement way, or we can do it the mathmatical way, that's easier to implement, but a little harder to understand.

Let me explain teh second, and then we'll do it the "proper" way.

We've got 3 commands, and if we were plotting these on a y,z axis, the commands result in a change to the y axis, or to the z axis. However, in this case, we've only been asked for the endpoint, which means we don't actually care about any intermediate numbers or steps, we just care about the end total.

So we could, for the y axis, simply take all the forwards, add all the numbers together, and that will be the result. We could also take all the down's add them together, and then subtract the total of all the ups, and that would be our resultant depth.

However, I suspect we'll want to look more closely at this, and possibily at something like the deepest point we've ever got to, so instead we're going to create a submarine data structure, and then parse each instruction and update the y or z position respectively.

This time, we're going to build our parser first, because I want to turn each line into an instruction, so the parser is more complex.

How are we going to do that?

We're going to read the line, and if it's "forward 15", we'll turn it into a "vector". In this case it'll just be a tuple, although Python has a handy namedtuple class so I'll use that. We're going to define the y coordinate as starting at 0 and incrementing as the sub goes forward. The z oordinate will represent the depth from the bottom

So we've got two named tuples, one for the sub and one for the Vector. We'll show later how we can add one to another, but first our parser needs to turn a line of text into a Vector

So we can now turn a list of intructions into a list of vectors, let's check that against the test data nad make sure it works.

Now that we've got the data into vectors, we can pretty simply move hte submarine by adding the sub and the vector together. We however need to define to python how that addition works, because by default it will just assume we have tuples, and adding two tuples together is treated like concatonation, rather than fieldwise addition.

We need to redefine the Sub class here, because it's a pain to add a method to an existing class, luckily we hadn't really used Sub anywhere yet. Strike one for the PythonNotebook though, I need to remember not to define things until I need them.

Now we can walk the list of vectors we got, moving the sub at each point, and we'll get a Sub with end position at the end

Let's do it on real data

Cool, onto

Part 2

Oh great, so instead of our parsing meaning that we're changing the vector, what we need to do is something slightly more complex, we need our Sub to have an aim. This means we're going to need to store 3 values for our Sub, our y, our z and our aim. When we get a forward command we apply a change to our y and our z, and when we get an up or down command, we can change our aim.

We can probably do this without changing our vector, because our parser turns the up and down commands into a positive or negative z, and we can treat that as just a change to aim.

Let's build a new sub and demonstrate with the first few test data examples

Great, that was easier than expected. If I was doing this in normal python, I'd probably rename the z component of a Vector to be called deltaaim, or aimchange, which would make it more readable.

Let's retry running the parsed data on the test data and see what happens

Brilliant. And lets go again on real data