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.