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 let helper = |[a, b]: [&str; 2]| {
20 let amount = b.signed();
21 match a {
22 "up" => Sub::Up(amount),
23 "down" => Sub::Down(amount),
24 "forward" => Sub::Forward(amount),
25 _ => unreachable!(),
26 }
27 };
28 input.split_ascii_whitespace().chunk::<2>().map(helper).collect()
29}
30
31pub fn part1(input: &[Sub]) -> i32 {
32 let helper = |(position, depth), next| match next {
33 Sub::Up(n) => (position, depth - n),
34 Sub::Down(n) => (position, depth + n),
35 Sub::Forward(n) => (position + n, depth),
36 };
37 let (position, depth) = input.iter().copied().fold((0, 0), helper);
38 position * depth
39}
40
41pub fn part2(input: &[Sub]) -> i32 {
42 let helper = |(position, depth, aim), next| match next {
43 Sub::Up(n) => (position, depth, aim - n),
44 Sub::Down(n) => (position, depth, aim + n),
45 Sub::Forward(n) => (position + n, depth + aim * n, aim),
46 };
47 let (position, depth, _) = input.iter().copied().fold((0, 0, 0), helper);
48 position * depth
49}