Advent of code 2021: Day 2

This article is part of a series where I'll be diving head first into the Advent of code 2021. I'll be documenting the challenge of solving such a puzzle and how I got to the answer. I want to prefix this by stating that I can't cheat for any of these challenges; with that, I mean I can't look up any other implementations online.

In this article I'll be solving: Advent of code 2021: Day #2.

Part 1

I am given a file called input in which there is a list of 1000 instructions in the format of: forward 1, down 1, up 6 etc. The submarine can move forward, up or down. The depth increases or decreases depending on their related up or down instructions. The position can only increase with a forward instruction. What is the product of the final depth times the final position, after following all the instructions?

fn move_submarine(coords: &Vec<&str>) -> u32 {
    let mut start = (0, 0);

    for coord in coords {
        let d: Vec<&str> = coord.split(" ").collect();
        let x: u32 = d[1].parse().unwrap();
        match d[0] {
            "forward" => start.0 += x,
            "down" => start.1 += x,
            "up" => start.1 -= x,
            _ => panic!("invalid direction")
        }
    }

    start.0 * start.1
}

#[test]
fn test_movement() {
    let final_pos = move_submarine(
        &vec![
            "forward 5",
            "down 5",
            "forward 8",
            "up 3",
            "down 8",
            "forward 2"
        ]
    );

    assert_eq!(final_pos, 150)
}

Part 2

The second part of the question introduces a third variable alongside depth and position, a thing called aim. The aim increases or decreases depending on their related up or down instructions. The position increases with a forward instruction, however the depth now also increases by the aim times the forward motion. What is the product of the final depth and the final position, after following all the instructions?

I swapped out the tuple from the first part and just used named variables. It does convey a bit better what it is we are trying to achieve.

fn move_submarine(coords: &Vec<&str>) -> u32 {
    let mut depth = 0;
    let mut position = 0;
    let mut aim = 0;

    for coord in coords {
        let d: Vec<&str> = coord.split(" ").collect();
        let x: u32 = d[1].parse().unwrap();

        match d[0] {
            "forward" => {
                position += x;
                depth += aim * x;
            },
            "down" => aim += x,
            "up" => aim -= x,
            _ => panic!("invalid direction")
        }
    }

    depth * position
}

Nothing too hard for day 2, and so I gained another two stars ⭐️⭐️.

The full solution is available on GitHub.

1716151413121110987654321