The Advent of Code 2019 made us travel in the whole Solar System. The Advent of Code 2020 made us go on holidays in a paradise island. This year, it seems we will travel under the sea.

Part 1

I woke up a few minutes late and was a bit slow to complete this part (about 50 minutes and I was ranked beyond the 10000th place).

First, we define an Enum where each variant represent a submarine command (forward, down, up) with a numeric parameter.

pub enum Instruction {
    Forward(u64),
    Down(u64),
    Up(u64)
}

Then, we write a parser function, that will be called for each input line.

pub fn parse_instruction(line: &String) -> Result<Instruction, &'static str> {
    let tokens = line.split(" ").collect::<Vec<&str>>();
    let units = u64::from_str(tokens[1]).expect("Wrong format number");
    
    match tokens[0] {
        "forward" => { Ok(Instruction::Forward(units)) },
        "down"  =>  { Ok(Instruction::Down(units)) },
        "up"    =>  { Ok(Instruction::Up(units)) },
        _ => { Err("Wrong instruction type") }
    }
}

Finally, in the main function, that will return the result, we use a match control flow operator, where each arm represents a command type

pub fn solve_part1(input: &Vec<String>) -> u64 {
    let mut horizontal = 0;
    let mut depth = 0;

    for i in 0..input.len() {
        match parse_instruction(&input[i]).unwrap() {
            Instruction::Forward(u) => { horizontal += u },
            Instruction::Down(u)  =>  { depth += u },
            Instruction::Up(u)    =>  { depth -= u },
        };
    }

    horizontal * depth
}

Part 2

There is absolutely no difficulty here. We simply have to modify the formulas written in match arms.

pub fn solve_part2(input: &Vec<String>) -> u64 {
    let mut horizontal = 0;
    let mut depth = 0;
    let mut aim = 0;
    
    for i in 0..input.len() {
        match parse_instruction(&input[i]).unwrap() {
            Instruction::Forward(u) => { horizontal += u; depth += aim * u },
            Instruction::Down(u)  =>  { aim += u },
            Instruction::Up(u)    =>  { aim -= u },
        };
    }

    horizontal * depth
}

I validated this part in less than 6 minutes.