diff options
Diffstat (limited to 'day1')
| -rw-r--r-- | day1/Cargo.toml | 1 | ||||
| -rw-r--r-- | day1/src/main.rs | 109 |
2 files changed, 101 insertions, 9 deletions
diff --git a/day1/Cargo.toml b/day1/Cargo.toml index 8ffbbfb..c40a086 100644 --- a/day1/Cargo.toml +++ b/day1/Cargo.toml @@ -4,3 +4,4 @@ version = "0.1.0" edition = "2024" [dependencies] +anyhow = "1.0.100" diff --git a/day1/src/main.rs b/day1/src/main.rs index 2849be2..aaee00b 100644 --- a/day1/src/main.rs +++ b/day1/src/main.rs @@ -1,4 +1,9 @@ -use std::str::FromStr; +use anyhow::anyhow; +use std::{ + env, fs, + ops::{Add, Sub}, + str::FromStr, +}; #[derive(Debug, PartialEq, Eq)] enum Rotation { @@ -6,28 +11,99 @@ enum Rotation { Right(u16), } -struct ParseRotationError(String); +#[derive(Debug)] +struct ParseRotationError; impl FromStr for Rotation { type Err = ParseRotationError; fn from_str(s: &str) -> Result<Self, Self::Err> { - let err = || ParseRotationError(s.into()); - let mut chars = s.chars(); - let lr = chars.next().ok_or_else(err)?; - let n: u16 = chars.collect::<String>().parse().map_err(|_| err())?; + let lr = chars.next().ok_or(ParseRotationError)?; + let n: u16 = chars + .collect::<String>() + .parse() + .map_err(|_| ParseRotationError)?; match lr { 'L' => Ok(Self::Left(n)), 'R' => Ok(Self::Right(n)), - _ => Err(err()), + _ => Err(ParseRotationError), } } } -fn main() { - println!("Hello, world!"); +#[derive(Clone, Copy, Debug)] +struct Dial(u8); + +impl Dial { + fn new() -> Self { + Self(50) + } +} + +impl Add<u16> for Dial { + type Output = Self; + + fn add(self, rhs: u16) -> Self::Output { + let n = self.0 as u16; + let m = (n + rhs) % 100; + Self(m as u8) + } +} + +impl Sub<u16> for Dial { + type Output = Self; + + fn sub(self, rhs: u16) -> Self::Output { + let n = self.0 as u16; + + if rhs > n { + let m = 100 - (n + rhs) % 100; + Self(m as u8) + } else { + let m = n - rhs; + Self(m as u8) + } + } +} + +impl PartialEq<u8> for Dial { + fn eq(&self, other: &u8) -> bool { + self.0 == *other + } +} + +fn main() -> anyhow::Result<()> { + let mut args = env::args(); + let input_path = args.nth(1).ok_or(anyhow!("usage: day1 INPUT"))?; + let input = fs::read_to_string(input_path)?; + + let rotations: Vec<Rotation> = input + .split_whitespace() + .map(|s| s.parse().map_err(|_| anyhow!("bad rotation: {}", s))) + .collect::<anyhow::Result<_>>()?; + + let mut dial = Dial::new(); + let mut zeros = 0; + + for rot in rotations { + println!("dial: {:?}", dial); + println!("rotation: {:?}", rot); + + match rot { + Rotation::Left(n) => dial = dial - n, + Rotation::Right(n) => dial = dial + n, + } + + if dial == 0 { + zeros = zeros + 1; + } + } + + println!("zeros: {}", zeros); + + Ok(()) } #[cfg(test)] @@ -48,4 +124,19 @@ mod tests { assert!("L".parse::<Rotation>().is_err()); assert!("2".parse::<Rotation>().is_err()); } + + #[test] + fn dial() { + let dial = Dial::new(); + + assert_eq!(dial + 1, 51); + assert_eq!(dial + 50, 0); + assert_eq!(dial + 100, 50); + assert_eq!(dial + 150, 0); + + assert_eq!(dial - 1, 49); + assert_eq!(dial - 68, 82); + assert_eq!(dial - 68 - 30, 52); + assert_eq!(dial - 100, 50); + } } |
