1use crate::util::iter::*;
9use crate::util::parse::*;
10
11#[derive(Clone, Copy)]
12pub enum Sub {
13 Up(i32),
14 Down(i32),
15 Forward(i32),
16}
17
18pub fn parse(input: &str) -> Vec<Sub> {
19 input
20 .split_ascii_whitespace()
21 .chunk::<2>()
22 .map(|[first, second]| {
23 let amount = second.signed();
24 match first {
25 "up" => Sub::Up(amount),
26 "down" => Sub::Down(amount),
27 "forward" => Sub::Forward(amount),
28 _ => unreachable!(),
29 }
30 })
31 .collect()
32}
33
34pub fn part1(input: &[Sub]) -> i32 {
35 let (position, depth) =
36 input.iter().copied().fold((0, 0), |(position, depth), next| match next {
37 Sub::Up(n) => (position, depth - n),
38 Sub::Down(n) => (position, depth + n),
39 Sub::Forward(n) => (position + n, depth),
40 });
41 position * depth
42}
43
44pub fn part2(input: &[Sub]) -> i32 {
45 let (position, depth, _) =
46 input.iter().copied().fold((0, 0, 0), |(position, depth, aim), next| match next {
47 Sub::Up(n) => (position, depth, aim - n),
48 Sub::Down(n) => (position, depth, aim + n),
49 Sub::Forward(n) => (position + n, depth + aim * n, aim),
50 });
51 position * depth
52}