diff options
| -rw-r--r-- | day1/src/main.rs | 120 |
1 files changed, 36 insertions, 84 deletions
diff --git a/day1/src/main.rs b/day1/src/main.rs index 2058021..50ab8e1 100644 --- a/day1/src/main.rs +++ b/day1/src/main.rs @@ -39,51 +39,28 @@ struct Dial(u8); struct RotateResult(u32, Dial); impl Dial { - fn new() -> Self { - Self(50) - } - fn rotate(self, rot: &Rotation) -> RotateResult { - match rot { - Rotation::Left(n) => self.rotate_left(*n), - Rotation::Right(n) => self.rotate_right(*n), - } - } - - fn rotate_left(self, n: u32) -> RotateResult { let pos = self.0 as u32; - if pos != 0 && n >= pos { - let quot = n.div_ceil(100); - RotateResult(quot, self - n) - } else { - RotateResult(0, self - n) - } - } - - fn rotate_right(self, n: u32) -> RotateResult { - let pos = self.0 as u32; - - if n + pos >= 100 { - let quot = n.div_ceil(100); - RotateResult(quot, self + n) - } else { - RotateResult(0, self + n) - } - } - - fn rotate_all(self, rotations: &[Rotation]) -> RotateResult { - let mut dial = Dial::from(50); - let mut zeros_total = 0; - - for rot in rotations { - let RotateResult(zeros, new_dial) = dial.rotate(rot); - zeros_total += zeros; - dial = new_dial; - println!("{:?}, dial: {}, zeros: {}", rot, dial.0, zeros); + match rot { + Rotation::Left(n) => { + if pos != 0 && *n >= pos { + let quot = n.div_ceil(100); + RotateResult(quot, self - *n) + } else { + RotateResult(0, self - *n) + } + } + + Rotation::Right(n) => { + if n + pos >= 100 { + let quot = n.div_ceil(100); + RotateResult(quot, self + *n) + } else { + RotateResult(0, self + *n) + } + } } - - RotateResult(zeros_total, dial) } } @@ -119,37 +96,9 @@ impl PartialEq<u8> for Dial { } } -fn part1(rotations: &[Rotation]) -> RotateResult { - let mut dial = Dial::new(); - let mut zeros = 0; - - for rot in rotations { - match rot { - Rotation::Left(n) => dial = dial - *n, - Rotation::Right(n) => dial = dial + *n, - } - - if dial == 0 { - zeros = zeros + 1; - } - } - - RotateResult(zeros, dial) -} - fn main() -> anyhow::Result<()> { - let usage_err = || anyhow!("usage: day1 PART INPUT"); - let mut args = env::args(); - - let part: u8 = args - .nth(1) - .ok_or_else(usage_err)? - .parse() - .map_err(|_| usage_err())?; - - let input_path = args.next().ok_or_else(usage_err)?; - + let input_path = args.nth(1).ok_or_else(|| anyhow!("usage: day1 INPUT"))?; let input = fs::read_to_string(input_path)?; let rotations: Vec<Rotation> = input @@ -157,22 +106,25 @@ fn main() -> anyhow::Result<()> { .map(|s| s.parse().map_err(|_| anyhow!("bad rotation: {}", s))) .collect::<anyhow::Result<_>>()?; - match part { - 1 => { - let RotateResult(zeros, _) = part1(&rotations); - println!("Result: {}", zeros); - Ok(()) - } + let mut dial = Dial::from(50); + let mut exact_zeros = 0; + let mut total_zeros = 0; - 2 => { - let dial = Dial::from(50); - let RotateResult(zeros, _) = dial.rotate_all(&rotations); - println!("Result: {}", zeros); - Ok(()) + for rot in &rotations { + let RotateResult(zeros, new_dial) = dial.rotate(rot); + + if new_dial == 0 { + exact_zeros += 1; } - _ => Err(usage_err()), + total_zeros += zeros; + dial = new_dial; } + + println!("Password: {}", exact_zeros); + println!("Password (method 0x434C49434B): {}", total_zeros); + + Ok(()) } #[cfg(test)] @@ -196,7 +148,7 @@ mod tests { #[test] fn dial_ops() { - let dial = Dial::new(); + let dial = Dial::from(50); assert_eq!(dial + 1, 51); assert_eq!(dial + 50, 0); @@ -219,7 +171,7 @@ mod tests { #[test] fn dial_rotate() { - let mut dial = Dial::new(); + let mut dial = Dial::from(50); let rotations = vec