From 4e08117ed0127e0c9b10ffc76b6268b4121cf144 Mon Sep 17 00:00:00 2001 From: Ruediger Ludwig Date: Sun, 29 Jan 2023 19:12:22 +0100 Subject: [PATCH] applied clippy --- Cargo.toml | 1 + src/common/area.rs | 68 +++++++++-------- src/common/file.rs | 4 +- src/common/helper.rs | 18 ----- src/common/math.rs | 106 +++++--------------------- src/common/mod.rs | 2 - src/common/number.rs | 102 ------------------------- src/common/permutations.rs | 152 ------------------------------------- src/common/pos.rs | 104 ++++++++++++++++--------- src/common/turn.rs | 12 +-- src/days/day01/mod.rs | 10 +-- src/days/day02/mod.rs | 70 ++++++++--------- src/days/day03/mod.rs | 12 +-- src/days/day04/mod.rs | 12 +-- src/days/template.rs | 8 +- src/main.rs | 28 +++---- 16 files changed, 205 insertions(+), 504 deletions(-) delete mode 100644 src/common/number.rs delete mode 100644 src/common/permutations.rs diff --git a/Cargo.toml b/Cargo.toml index 03a5631..050a474 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,4 +7,5 @@ edition = "2021" [dependencies] anyhow = "1.0" itertools = "0.10" +num-traits = "0.2.15" thiserror = "1.0" diff --git a/src/common/area.rs b/src/common/area.rs index e1966a7..dbda7b1 100644 --- a/src/common/area.rs +++ b/src/common/area.rs @@ -1,12 +1,14 @@ #![allow(dead_code)] use std::fmt::Display; -use super::{number::Number, pos::Pos}; +use num_traits::{Num, NumAssignOps}; + +use super::pos::Pos; #[derive(Debug, Clone, Copy, Default)] pub struct Area where - T: Number, + T: Num, { lower_left: Pos, upper_right: Pos, @@ -14,7 +16,7 @@ where impl Area where - T: Number + Ord, + T: Num + Ord + Copy, { pub fn new(p1: Pos, p2: Pos) -> Area { Area { @@ -22,7 +24,12 @@ where upper_right: p1.max_components(&p2), } } +} +impl Area +where + T: Num + Ord + Copy, +{ pub fn extend(&self, pos: Pos) -> Area { if self.contains(pos) { return *self; @@ -33,7 +40,6 @@ where upper_right: self.upper_right.max_components(&pos), } } - pub fn get_lower_left(&self) -> Pos { self.lower_left } @@ -52,7 +58,7 @@ where impl<'a, T> Area where - T: Number + Ord + 'a, + T: Num + Ord + 'a + Copy, { pub fn from_iterator(mut iter: I) -> Option where @@ -60,7 +66,7 @@ where { let first = *iter.next()?; let (upper, lower) = iter.fold((first, first), |(mx, mn), p| { - (mx.max_components(&p), mn.min_components(&p)) + (mx.max_components(p), mn.min_components(p)) }); Some(Area::new(lower, upper)) @@ -69,21 +75,21 @@ where impl Area where - T: Number, + T: Num + Copy, { pub fn width(&self) -> T { - self.upper_right.x() - self.lower_left.x() + T::ONE + self.upper_right.x() - self.lower_left.x() + T::one() } #[allow(dead_code)] pub fn height(&self) -> T { - self.upper_right.y() - self.lower_left.y() + T::ONE + self.upper_right.y() - self.lower_left.y() + T::one() } } impl Area where - T: Number, + T: Num + Copy, { #[allow(dead_code)] pub fn area(&self) -> T { @@ -93,7 +99,7 @@ where impl Display for Area where - T: Number + Display, + T: Num + Display, { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "[{}-{}]", self.lower_left, self.upper_right) @@ -102,7 +108,7 @@ where impl Area where - T: Number, + T: Num + Copy, { pub fn cells(&self, ascending: bool) -> CellIterator<'_, T> { CellIterator::new(self, ascending) @@ -116,7 +122,7 @@ where #[derive(Debug)] pub struct RowIterator<'a, T> where - T: Number, + T: Num + Copy, { area: &'a Area, row: T, @@ -125,7 +131,7 @@ where impl<'a, T> RowIterator<'a, T> where - T: Number, + T: Num + Copy, { fn new(area: &'a Area, ascending: bool) -> RowIterator<'a, T> { RowIterator { @@ -142,7 +148,7 @@ where impl<'a, T> Iterator for RowIterator<'a, T> where - T: Number, + T: Num + Ord + NumAssignOps + Copy, { type Item = Row<'a, T>; @@ -155,9 +161,9 @@ where row: self.row, }; if self.ascending { - self.row += T::ONE; + self.row += T::one(); } else { - self.row -= T::ONE; + self.row -= T::one(); } Some(row) } else { @@ -169,7 +175,7 @@ where #[derive(Debug)] pub struct Row<'a, T> where - T: Number, + T: Num, { area: &'a Area, row: T, @@ -177,7 +183,7 @@ where impl<'a, T> Row<'a, T> where - T: Number, + T: Num + Copy, { pub fn cols(&self, ascending: bool) -> ColIterator<'_, T> { ColIterator { @@ -196,7 +202,7 @@ where #[derive(Debug)] pub struct ColIterator<'a, T> where - T: Number, + T: Num, { area: &'a Area, row: T, @@ -206,7 +212,7 @@ where impl<'a, T> Iterator for ColIterator<'a, T> where - T: Number, + T: Num + Ord + NumAssignOps + Copy, { type Item = Pos; fn next(&mut self) -> Option { @@ -215,10 +221,10 @@ where { let pos = Pos::new(self.col, self.row); if self.ascending { - self.col += T::ONE + self.col += T::one(); } else { - self.col -= T::ONE - }; + self.col -= T::one(); + } Some(pos) } else { None @@ -229,7 +235,7 @@ where #[derive(Debug)] pub struct CellIterator<'a, T> where - T: Number, + T: Num, { area: &'a Area, row: T, @@ -239,7 +245,7 @@ where impl<'a, T> CellIterator<'a, T> where - T: Number, + T: Num + Copy, { pub fn new(area: &'a Area, ascending: bool) -> CellIterator<'a, T> { let (col, row) = if ascending { @@ -258,7 +264,7 @@ where impl<'a, T> Iterator for CellIterator<'a, T> where - T: Number, + T: Num + Ord + NumAssignOps + Copy, { type Item = Pos; @@ -268,15 +274,15 @@ where { let pos = Pos::new(self.col, self.row); if self.ascending { - self.col += T::ONE; + self.col += T::one(); if self.col > self.area.upper_right.x() { - self.row += T::ONE; + self.row += T::one(); self.col = self.area.lower_left.x(); } } else { - self.col -= T::ONE; + self.col -= T::one(); if self.col < self.area.lower_left.x() { - self.row -= T::ONE; + self.row -= T::one(); self.col = self.area.upper_right.x(); } } diff --git a/src/common/file.rs b/src/common/file.rs index 71d03f2..a564879 100644 --- a/src/common/file.rs +++ b/src/common/file.rs @@ -2,7 +2,7 @@ use itertools::Itertools; use std::{fs, io}; fn read_data(day_num: usize, file: &str) -> io::Result { - fs::read_to_string(format!("data/day{:02}/{}", day_num, file)) + fs::read_to_string(format!("data/day{day_num:02}/{file}")) } pub fn read_lines(day_num: usize, file: &str) -> io::Result> { @@ -15,7 +15,7 @@ pub fn read_lines(day_num: usize, file: &str) -> io::Result> { | itertools::Position::Middle(line) | itertools::Position::Only(line) => Some(line.to_owned()), itertools::Position::Last(line) => { - if line.len() == 0 { + if line.is_empty() { None } else { Some(line.to_owned()) diff --git a/src/common/helper.rs b/src/common/helper.rs index 71d6bd0..b8bd892 100644 --- a/src/common/helper.rs +++ b/src/common/helper.rs @@ -74,21 +74,3 @@ pub fn zip7( _ => None, } } - -pub fn zip8( - o1: Option, - o2: Option, - o3: Option, - o4: Option, - o5: Option, - o6: Option, - o7: Option, - o8: Option, -) -> Option<(A, B, C, D, E, F, G, H)> { - match (o1, o2, o3, o4, o5, o6, o7, o8) { - (Some(a), Some(b), Some(c), Some(d), Some(e), Some(f), Some(g), Some(h)) => { - Some((a, b, c, d, e, f, g, h)) - } - _ => None, - } -} diff --git a/src/common/math.rs b/src/common/math.rs index a2ce540..6b22811 100644 --- a/src/common/math.rs +++ b/src/common/math.rs @@ -1,7 +1,7 @@ #![allow(dead_code)] use thiserror::Error; -use super::number::Number; +use num_traits::{Euclid, Num}; #[derive(Error, Debug)] pub enum MathError { @@ -17,35 +17,36 @@ pub enum MathError { fn non_zero_gcd(mut a: T, mut b: T) -> T where - T: Number, + T: Num + Ord + Copy, { - while b != T::ZERO { + while !b.is_zero() { let t = a % b; a = b; b = t; } - a.abs() + a } pub fn gcd(a: T, b: T) -> T where - T: Number, + T: Num + Ord + Copy, { - if a == T::ZERO { - b.abs() - } else if b == T::ZERO { - a.abs() + assert!(a >= T::zero()); + assert!(b >= T::zero()); + if a.is_zero() { + b + } else if b.is_zero() { + a } else { non_zero_gcd(a, b) } } - pub fn lcm(a: T, b: T) -> T where - T: Number, + T: Num + Ord + Copy, { - if a == T::ZERO || b == T::ZERO { - T::ZERO + if a.is_zero() || b.is_zero() { + T::zero() } else { a * b / non_zero_gcd(a, b) } @@ -53,64 +54,20 @@ where pub fn modulus_inv(num: T, modulo: T) -> Option where - T: Number, + T: Num + Euclid + Copy, { - let num = num.rem_euclid(modulo); - let mut s = (T::ZERO, T::ONE); + let num = num.rem_euclid(&modulo); + let mut s = (T::zero(), T::one()); let mut r = (modulo, num); - while r.0 != T::ZERO { + while !r.0.is_zero() { let q = r.1 / r.0; r = (r.1 - q * r.0, r.0); s = (s.1 - q * s.0, s.0); } - if r.1 != T::ONE { + if !r.1.is_one() { None } else { - Some(s.1.rem_euclid(modulo)) - } -} - -pub fn modulus_mul(a: T, b: T, modulo: T) -> Result -where - T: Number, -{ - let mul = if let Some(mul) = a.checked_mul(b) { - mul - } else if T::MAX >> T::ONE >= a { - let start = if b.is_odd() { a } else { T::ZERO }; - start + modulus_mul((a << T::ONE).rem_euclid(modulo), b >> T::ONE, modulo)? - } else { - return Err(MathError::TooHigh); - }; - - Ok(mul.rem_euclid(modulo)) -} - -pub fn modulus_exp(base: T, exponent: T, modulo: T) -> Result -where - T: Number, -{ - if modulo < T::ONE { - return Err(MathError::NeedPositiveModulo); - } - if exponent < T::ZERO { - return Err(MathError::NeedNonNegativeExponent); - } - - if modulo == T::ONE { - Ok(T::ZERO) - } else { - let mut result = T::ONE; - let mut base = base.rem_euclid(modulo); - let mut exponent = exponent; - while exponent > T::ZERO { - if exponent.is_odd() { - result = modulus_mul(result, base, modulo)?; - } - exponent = exponent >> T::ONE; - base = modulus_mul(base, base, modulo)?; - } - Ok(result) + Some(s.1.rem_euclid(&modulo)) } } @@ -131,29 +88,6 @@ mod tests { assert_eq!(20, lcm(5, 4)); } - #[test] - fn test_modulo_mul() -> Result<(), MathError> { - let a = 1_234_567_890_123_456i64; - let b = 98_765; - let result = modulus_mul(a, b, 3_333_333_333_333_333)?; - - assert_eq!(result, 2_097_668_043_144_033); - - Ok(()) - } - - #[test] - fn test_modulo_exp() -> Result<(), MathError> { - let base = 4; - let exponent = 13; - let modulo = 497; - let result = modulus_exp(base, exponent, modulo)?; - - assert_eq!(result, 445); - - Ok(()) - } - #[test] fn test_inverse_modulo() { let num = 3; diff --git a/src/common/mod.rs b/src/common/mod.rs index e615dc0..3c42571 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -3,7 +3,5 @@ pub mod direction; pub mod file; pub mod helper; pub mod math; -pub mod number; -pub mod permutations; pub mod pos; pub mod turn; diff --git a/src/common/number.rs b/src/common/number.rs deleted file mode 100644 index f562b6f..0000000 --- a/src/common/number.rs +++ /dev/null @@ -1,102 +0,0 @@ -use std::ops::{Add, AddAssign, BitAnd, Div, Mul, Rem, Shl, Shr, Sub, SubAssign}; - -pub trait Number: - Copy - + Add - + Sub - + Mul - + Div - + Rem - + Shr - + Shl - + AddAssign - + SubAssign - + BitAnd - + PartialEq - + PartialOrd - + Ord -{ - const ZERO: Self; - const ONE: Self; - const MAX: Self; - - fn abs(self) -> Self; - fn checked_mul(self, rhs: Self) -> Option; - fn rem_euclid(self, rhs: Self) -> Self; - - fn is_odd(&self) -> bool { - *self & Self::ONE == Self::ONE - } - - fn is_even(&self) -> bool { - !self.is_odd() - } - - fn as_f64(self) -> f64; -} - -impl Number for i32 { - const ZERO: i32 = 0i32; - const ONE: i32 = 1i32; - const MAX: i32 = i32::MAX; - - fn abs(self) -> Self { - (self as i32).abs() - } - - fn rem_euclid(self, rhs: Self) -> Self { - (self as i32).rem_euclid(rhs) - } - - fn checked_mul(self, rhs: Self) -> Option { - (self as i32).checked_mul(rhs) - } - - fn as_f64(self) -> f64 { - self as f64 - } -} - -impl Number for i64 { - const ZERO: i64 = 0i64; - const ONE: i64 = 1i64; - const MAX: i64 = i64::MAX; - - fn abs(self) -> Self { - (self as i64).abs() - } - - fn rem_euclid(self, rhs: Self) -> Self { - (self as i64).rem_euclid(rhs) - } - - fn checked_mul(self, rhs: Self) -> Option { - (self as i64).checked_mul(rhs) - } - - fn as_f64(self) -> f64 { - self as f64 - } -} - -impl Number for i128 { - const ZERO: i128 = 0i128; - const ONE: i128 = 1i128; - const MAX: i128 = i128::MAX; - - fn abs(self) -> Self { - (self as i128).abs() - } - - fn rem_euclid(self, rhs: Self) -> Self { - (self as i128).rem_euclid(rhs) - } - - fn checked_mul(self, rhs: Self) -> Option { - (self as i128).checked_mul(rhs) - } - - fn as_f64(self) -> f64 { - self as f64 - } -} diff --git a/src/common/permutations.rs b/src/common/permutations.rs deleted file mode 100644 index 34d6fdd..0000000 --- a/src/common/permutations.rs +++ /dev/null @@ -1,152 +0,0 @@ -use std::{cell::RefCell, rc::Rc}; - -pub trait PermutateExt: IntoIterator { - fn permutate(&self) -> Permutations<'_, T>; -} - -impl PermutateExt for Vec { - fn permutate(&self) -> Permutations<'_, T> { - let list = self.into_iter().collect::>(); - Permutations { - list: Rc::new(RefCell::new(list)), - - start: 0, - current: 0, - len: self.len(), - maybe_tail: None, - } - } -} - -pub struct Permutations<'a, T> { - list: Rc>>, - start: usize, - current: usize, - len: usize, - maybe_tail: Option>>, -} - -impl<'a, T> Iterator for Permutations<'a, T> { - type Item = Vec<&'a T>; - - fn next(&mut self) -> Option> { - if self.current >= self.len { - None - } else if self.start + 1 == self.len { - self.current += 1; - Some(self.list.borrow().clone()) - } else { - if let Some(mut tail) = self.maybe_tail.take() { - if let Some(result) = tail.next() { - self.maybe_tail = Some(tail); - return Some(result); - } else { - let mut borrow = (*self.list).borrow_mut(); - // Swapping prev first item back to its original osition - for p in self.start..self.current { - borrow.swap(p, p + 1); - } - - self.current += 1; - if self.current >= self.len { - return None; - } - - // Getting next first item for next iteration - for p in (self.start..self.current).rev() { - borrow.swap(p, p + 1); - } - } - } - - let mut rest = Box::new(Permutations { - len: self.len, - list: self.list.clone(), - current: self.start + 1, - start: self.start + 1, - maybe_tail: None, - }); - let result = rest.next(); - self.maybe_tail = Some(rest); - - result - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_zero() { - let input: Vec = vec![]; - let result = input.permutate().collect::>(); - let expected: Vec> = vec![]; - assert_eq!(result, expected); - } - - #[test] - fn test_one() { - let input = vec![1]; - let result = input.permutate().collect::>(); - let expected = vec![[&1]]; - assert_eq!(result, expected); - } - - #[test] - fn test_two() { - let input = vec![1, 2]; - let result = input.permutate().collect::>(); - let expected = vec![[&1, &2], [&2, &1]]; - assert_eq!(result, expected); - } - - #[test] - fn test_three() { - let input = vec![1, 2, 3]; - let result = input.permutate().collect::>(); - let expected = vec![ - [&1, &2, &3], - [&1, &3, &2], - [&2, &1, &3], - [&2, &3, &1], - [&3, &1, &2], - [&3, &2, &1], - ]; - assert_eq!(result, expected); - } - - #[test] - fn test_four() { - let input = vec![1, 2, 3, 4]; - let result = input.permutate().collect::>(); - let expected = vec![ - [&1, &2, &3, &4], - [&1, &2, &4, &3], - [&1, &3, &2, &4], - [&1, &3, &4, &2], - [&1, &4, &2, &3], - [&1, &4, &3, &2], - [&2, &1, &3, &4], - [&2, &1, &4, &3], - [&2, &3, &1, &4], - [&2, &3, &4, &1], - [&2, &4, &1, &3], - [&2, &4, &3, &1], - [&3, &1, &2, &4], - [&3, &1, &4, &2], - [&3, &2, &1, &4], - [&3, &2, &4, &1], - [&3, &4, &1, &2], - [&3, &4, &2, &1], - [&4, &1, &2, &3], - [&4, &1, &3, &2], - [&4, &2, &1, &3], - [&4, &2, &3, &1], - [&4, &3, &1, &2], - [&4, &3, &2, &1], - ]; - assert_eq!(result, expected); - } -} diff --git a/src/common/pos.rs b/src/common/pos.rs index 99f3f89..d5ffb07 100644 --- a/src/common/pos.rs +++ b/src/common/pos.rs @@ -1,20 +1,27 @@ -use super::{direction::Direction, math::gcd, number::Number}; +use super::direction::Direction; +use super::math::gcd; +use num_traits::{Num, NumCast, Signed}; use std::fmt; use std::ops::{Add, Mul, Sub}; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)] pub struct Pos(T, T) where - T: Number; + T: Num; impl Pos where - T: Number, + T: Num, { pub fn new(x: T, y: T) -> Pos { Pos(x, y) } +} +impl Pos +where + T: Num + Copy, +{ pub fn x(&self) -> T { self.0 } @@ -22,7 +29,47 @@ where pub fn y(&self) -> T { self.1 } +} +impl Pos +where + T: Num + Ord + Copy, +{ + pub fn normalize(&self) -> (Pos, T) { + if self.0.is_zero() && self.1.is_zero() { + (*self, T::one()) + } else { + let ggt = gcd(self.0, self.1); + (Pos::new(self.0 / ggt, self.1 / ggt), ggt) + } + } +} + +impl Pos +where + T: Num + NumCast, +{ + pub fn angle(&self) -> f64 { + if let (Some(x), Some(y)) = (self.0.to_f64(), self.1.to_f64()) { + y.atan2(x) + } else { + f64::NAN + } + } + + pub fn angle2(&self) -> f64 { + if let (Some(x), Some(y)) = (self.0.to_f64(), self.1.to_f64()) { + (-x.atan2(-y) + std::f64::consts::PI).rem_euclid(2.0 * std::f64::consts::PI) + } else { + f64::NAN + } + } +} + +impl Pos +where + T: Num + Ord + Copy, +{ pub fn max_components(&self, other: &Pos) -> Self { Self(self.0.max(other.0), self.1.max(other.1)) } @@ -30,33 +77,20 @@ where pub fn min_components(&self, other: &Pos) -> Self { Self(self.0.min(other.0), self.1.min(other.1)) } +} +impl Pos +where + T: Num + Signed, +{ pub fn abs(&self) -> T { self.0.abs() + self.1.abs() } - - pub fn normalize(&self) -> (Pos, T) { - if self.0 == T::ZERO && self.1 == T::ZERO { - (*self, T::ONE) - } else { - let ggt = gcd(self.0, self.1); - (Pos::new(self.0 / ggt, self.1 / ggt), ggt) - } - } - - pub fn angle(&self) -> f64 { - self.1.as_f64().atan2(self.0.as_f64()) - } - - pub fn angle2(&self) -> f64 { - (-self.0.as_f64().atan2(-self.1.as_f64()) + std::f64::consts::PI) - .rem_euclid(2.0 * std::f64::consts::PI) - } } impl fmt::Display for Pos where - T: Number + fmt::Display, + T: Num + fmt::Display, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "({}, {})", self.0, self.1) @@ -65,7 +99,7 @@ where impl Add for Pos where - T: Number, + T: Num, { type Output = Self; fn add(self, rhs: Self) -> Self::Output { @@ -75,7 +109,7 @@ where impl Add for &Pos where - T: Number, + T: Num + Copy, { type Output = as Add>>::Output; @@ -86,7 +120,7 @@ where impl Add<&Pos> for Pos where - T: Number, + T: Num + Copy, { type Output = as Add>>::Output; fn add(self, rhs: &Self) -> Self::Output { @@ -96,7 +130,7 @@ where impl Add> for &Pos where - T: Number, + T: Num + Copy, { type Output = as Add>>::Output; fn add(self, rhs: Pos) -> Self::Output { @@ -106,7 +140,7 @@ where impl Add<(T, T)> for Pos where - T: Number, + T: Num, { type Output = Self; fn add(self, rhs: (T, T)) -> Self::Output { @@ -148,7 +182,7 @@ impl Add for &Pos { impl Sub for Pos where - T: Number, + T: Num, { type Output = Pos; fn sub(self, rhs: Self) -> Self::Output { @@ -158,7 +192,7 @@ where impl Sub<&Self> for Pos where - T: Number, + T: Num + Copy, { type Output = Pos; fn sub(self, rhs: &Self) -> Self::Output { @@ -168,7 +202,7 @@ where impl Sub for &Pos where - T: Number, + T: Num + Copy, { type Output = Pos; fn sub(self, rhs: &Pos) -> Self::Output { @@ -178,7 +212,7 @@ where impl Sub> for &Pos where - T: Number, + T: Num + Copy, { type Output = Pos; fn sub(self, rhs: Pos) -> Self::Output { @@ -188,7 +222,7 @@ where impl Mul for Pos where - T: Number, + T: Num + Copy, { type Output = Self; fn mul(self, rhs: T) -> Self::Output { @@ -198,7 +232,7 @@ where impl Mul for &Pos where - T: Number, + T: Num + Copy, { type Output = Pos; fn mul(self, rhs: T) -> Self::Output { @@ -208,7 +242,7 @@ where impl Mul<&T> for Pos where - T: Number, + T: Num + Copy, { type Output = Pos; fn mul(self, rhs: &T) -> Self::Output { @@ -218,7 +252,7 @@ where impl Mul<&T> for &Pos where - T: Number, + T: Num + Copy, { type Output = Pos; fn mul(self, rhs: &T) -> Self::Output { diff --git a/src/common/turn.rs b/src/common/turn.rs index d810032..3dc816c 100644 --- a/src/common/turn.rs +++ b/src/common/turn.rs @@ -12,7 +12,7 @@ pub enum Turn { use Turn::*; impl Turn { - pub fn to_left(&self) -> Turn { + pub fn turn_left(&self) -> Turn { match *self { Left => Back, Back => Right, @@ -21,7 +21,7 @@ impl Turn { } } - pub fn to_right(&self) -> Turn { + pub fn turn_right(&self) -> Turn { match *self { Left => Forward, Back => Left, @@ -30,7 +30,7 @@ impl Turn { } } - pub fn to_back(&self) -> Turn { + pub fn turn_back(&self) -> Turn { match *self { Left => Right, Back => Forward, @@ -56,9 +56,9 @@ impl Add for Turn { fn add(self, rhs: Turn) -> Self::Output { match rhs { - Left => self.to_left(), - Back => self.to_back(), - Right => self.to_right(), + Left => self.turn_left(), + Back => self.turn_back(), + Right => self.turn_right(), Forward => self, } } diff --git a/src/days/day01/mod.rs b/src/days/day01/mod.rs index 20656a6..0bda729 100644 --- a/src/days/day01/mod.rs +++ b/src/days/day01/mod.rs @@ -16,13 +16,13 @@ impl DayTrait for Day { fn part1(&self, lines: &[String]) -> anyhow::Result { let vector = Day::parse(lines)?; let max = vector.iter().max().ok_or(CalorieError::Empty)?; - Ok(ResultType::IntResult(*max)) + Ok(ResultType::Integer(*max)) } fn part2(&self, lines: &[String]) -> anyhow::Result { let vector = Day::parse(lines)?; let sum = vector.iter().sorted_by(|a, b| Ord::cmp(b, a)).take(3).sum(); - Ok(ResultType::IntResult(sum)) + Ok(ResultType::Integer(sum)) } } @@ -32,7 +32,7 @@ impl Day { .iter() .batching(|it| { let result = it - .take_while(|line| line.len() != 0) + .take_while(|line| !line.is_empty()) .map(|line| line.parse::()) .collect::, _>>() .map(|lst: _| lst.iter().sum::()); @@ -64,7 +64,7 @@ mod test { fn test_part1() -> Result<()> { let day = Day {}; let lines = read_lines(day.get_day_number(), "example01.txt")?; - let expected = ResultType::IntResult(24_000); + let expected = ResultType::Integer(24_000); let result = day.part1(&lines)?; assert_eq!(result, expected); @@ -75,7 +75,7 @@ mod test { fn test_part2() -> Result<()> { let day = Day {}; let lines = read_lines(day.get_day_number(), "example01.txt")?; - let expected = ResultType::IntResult(45_000); + let expected = ResultType::Integer(45_000); let result = day.part2(&lines)?; assert_eq!(result, expected); diff --git a/src/days/day02/mod.rs b/src/days/day02/mod.rs index 7f77b01..39c5efb 100644 --- a/src/days/day02/mod.rs +++ b/src/days/day02/mod.rs @@ -15,25 +15,25 @@ impl DayTrait for Day { fn part1(&self, lines: &[String]) -> anyhow::Result { let sum = lines .iter() - .map(|line| RPS::parse_line(&line)) + .map(|line| Rps::parse_line(line)) .collect::, _>>()? .into_iter() .map(|(first, second)| second.asses_pair(&first)) .sum(); - Ok(ResultType::IntResult(sum)) + Ok(ResultType::Integer(sum)) } fn part2(&self, lines: &[String]) -> anyhow::Result { let sum = lines .iter() - .map(|line| Strategy::parse_line(&line)) + .map(|line| Strategy::parse_line(line)) .collect::, _>>()? .into_iter() .map(|(first, second)| second.fullfill(&first).asses_pair(&first)) .sum(); - Ok(ResultType::IntResult(sum)) + Ok(ResultType::Integer(sum)) } } @@ -47,29 +47,29 @@ enum RPSError { } #[derive(Debug, PartialEq, Eq, Copy, Clone)] -enum RPS { +enum Rps { Rock, Paper, Scissors, } -impl RPS { +impl Rps { pub fn parse_line(line: &str) -> Result<(Self, Self), RPSError> { - let mut parts = line.split(" "); + let mut parts = line.split(' '); let (Some(first), Some(second)) = (parts.next(), parts.next()) else { Err(RPSError::IllegalLine(line.to_owned()))? }; - let first = RPS::try_from(first)?; - let second = RPS::try_from(second)?; + let first = Rps::try_from(first)?; + let second = Rps::try_from(second)?; Ok((first, second)) } pub fn value(&self) -> i64 { match self { - RPS::Rock => 1, - RPS::Paper => 2, - RPS::Scissors => 3, + Rps::Rock => 1, + Rps::Paper => 2, + Rps::Scissors => 3, } } @@ -84,13 +84,13 @@ impl RPS { } } -impl PartialOrd for RPS { +impl PartialOrd for Rps { fn partial_cmp(&self, other: &Self) -> Option { match (self, other) { - (RPS::Rock, RPS::Paper) | (RPS::Paper, RPS::Scissors) | (RPS::Scissors, RPS::Rock) => { + (Rps::Rock, Rps::Paper) | (Rps::Paper, Rps::Scissors) | (Rps::Scissors, Rps::Rock) => { Some(Ordering::Less) } - (RPS::Rock, RPS::Scissors) | (RPS::Paper, RPS::Rock) | (RPS::Scissors, RPS::Paper) => { + (Rps::Rock, Rps::Scissors) | (Rps::Paper, Rps::Rock) | (Rps::Scissors, Rps::Paper) => { Some(Ordering::Greater) } _ => Some(Ordering::Equal), @@ -98,14 +98,14 @@ impl PartialOrd for RPS { } } -impl TryFrom<&str> for RPS { +impl TryFrom<&str> for Rps { type Error = RPSError; fn try_from(value: &str) -> std::result::Result { match value { - "A" | "X" => Ok(RPS::Rock), - "B" | "Y" => Ok(RPS::Paper), - "C" | "Z" => Ok(RPS::Scissors), + "A" | "X" => Ok(Rps::Rock), + "B" | "Y" => Ok(Rps::Paper), + "C" | "Z" => Ok(Rps::Scissors), _ => Err(RPSError::ParseError(value.to_owned())), } } @@ -118,23 +118,23 @@ enum Strategy { } impl Strategy { - pub fn parse_line(line: &str) -> Result<(RPS, Self), RPSError> { - let mut parts = line.split(" "); + pub fn parse_line(line: &str) -> Result<(Rps, Self), RPSError> { + let mut parts = line.split(' '); let (Some(first), Some(second)) = (parts.next(), parts.next()) else { Err(RPSError::IllegalLine(line.to_owned()))? }; - let first = RPS::try_from(first)?; + let first = Rps::try_from(first)?; let second = Strategy::try_from(second)?; Ok((first, second)) } - pub fn fullfill(&self, other: &RPS) -> RPS { + pub fn fullfill(&self, other: &Rps) -> Rps { match (other, self) { (_, Strategy::Draw) => *other, - (RPS::Rock, Strategy::Win) | (RPS::Scissors, Strategy::Loose) => RPS::Paper, - (RPS::Paper, Strategy::Win) | (RPS::Rock, Strategy::Loose) => RPS::Scissors, - (RPS::Scissors, Strategy::Win) | (RPS::Paper, Strategy::Loose) => RPS::Rock, + (Rps::Rock, Strategy::Win) | (Rps::Scissors, Strategy::Loose) => Rps::Paper, + (Rps::Paper, Strategy::Win) | (Rps::Rock, Strategy::Loose) => Rps::Scissors, + (Rps::Scissors, Strategy::Win) | (Rps::Paper, Strategy::Loose) => Rps::Rock, } } } @@ -161,8 +161,8 @@ mod test { #[test] fn test_parse() -> Result<()> { let input = "A Y"; - let expected = (RPS::Rock, RPS::Paper); - let result = RPS::parse_line(input)?; + let expected = (Rps::Rock, Rps::Paper); + let result = Rps::parse_line(input)?; assert_eq!(result, expected); Ok(()) @@ -170,8 +170,8 @@ mod test { #[test] fn test_assess() -> Result<()> { - let first = RPS::Scissors; - let second = RPS::Paper; + let first = Rps::Scissors; + let second = Rps::Paper; let expected = 9; let result = first.asses_pair(&second); assert_eq!(result, expected); @@ -183,7 +183,7 @@ mod test { fn test_part1() -> Result<()> { let day = Day {}; let lines = read_lines(day.get_day_number(), "example01.txt")?; - let expected = ResultType::IntResult(15); + let expected = ResultType::Integer(15); let result = day.part1(&lines)?; assert_eq!(result, expected); @@ -193,7 +193,7 @@ mod test { #[test] fn test_parse_strategy() -> Result<()> { let input = "A Y"; - let expected = (RPS::Rock, Strategy::Draw); + let expected = (Rps::Rock, Strategy::Draw); let result = Strategy::parse_line(input)?; assert_eq!(result, expected); @@ -202,9 +202,9 @@ mod test { #[test] fn test_assess_stragety() -> Result<()> { - let first = RPS::Scissors; + let first = Rps::Scissors; let second = Strategy::Win; - let expected = RPS::Rock; + let expected = Rps::Rock; let result = second.fullfill(&first); assert_eq!(result, expected); @@ -215,7 +215,7 @@ mod test { fn test_part2() -> Result<()> { let day = Day {}; let lines = read_lines(day.get_day_number(), "example01.txt")?; - let expected = ResultType::NoResult; + let expected = ResultType::Nothing; let result = day.part2(&lines)?; assert_eq!(result, expected); diff --git a/src/days/day03/mod.rs b/src/days/day03/mod.rs index 159f759..f263f63 100644 --- a/src/days/day03/mod.rs +++ b/src/days/day03/mod.rs @@ -14,11 +14,11 @@ impl DayTrait for Day { fn part1(&self, lines: &[String]) -> anyhow::Result { let sum = lines .iter() - .map(|line| find_double(&line)) + .map(|line| find_double(line)) .map_ok(priority) .flatten_ok() .fold_ok(0, |a, b| a + b)?; - Ok(ResultType::IntResult(sum)) + Ok(ResultType::Integer(sum)) } fn part2(&self, lines: &[String]) -> anyhow::Result { @@ -30,7 +30,7 @@ impl DayTrait for Day { .map_ok(priority) .flatten_ok() .fold_ok(0, |a, b| a + b)?; - Ok(ResultType::IntResult(sum)) + Ok(ResultType::Integer(sum)) } } @@ -71,7 +71,7 @@ fn find_double(content: &str) -> Result { Err(RucksackError::NoDoubleFound)? } -fn find_badge<'a>(elves: &[&String]) -> Result { +fn find_badge(elves: &[&String]) -> Result { if elves.len() < 2 { return Err(RucksackError::NeedAtLeastTwo); }; @@ -109,7 +109,7 @@ mod test { fn test_part1() -> Result<()> { let day = Day {}; let lines = read_lines(day.get_day_number(), "example01.txt")?; - let expected = ResultType::IntResult(157); + let expected = ResultType::Integer(157); let result = day.part1(&lines)?; assert_eq!(result, expected); @@ -120,7 +120,7 @@ mod test { fn test_part2() -> Result<()> { let day = Day {}; let lines = read_lines(day.get_day_number(), "example01.txt")?; - let expected = ResultType::IntResult(70); + let expected = ResultType::Integer(70); let result = day.part2(&lines)?; assert_eq!(result, expected); diff --git a/src/days/day04/mod.rs b/src/days/day04/mod.rs index f5a1303..2696dc7 100644 --- a/src/days/day04/mod.rs +++ b/src/days/day04/mod.rs @@ -15,19 +15,19 @@ impl DayTrait for Day { fn part1(&self, lines: &[String]) -> anyhow::Result { let sum = lines .iter() - .map(|line| parse(&line)) + .map(|line| parse(line)) .filter_ok(fully_contained) .fold_ok(0i64, |a, _| a + 1)?; - Ok(ResultType::IntResult(sum)) + Ok(ResultType::Integer(sum)) } fn part2(&self, lines: &[String]) -> anyhow::Result { let sum = lines .iter() - .map(|line| parse(&line)) + .map(|line| parse(line)) .filter_ok(overlaps) .fold_ok(0i64, |a, _| a + 1)?; - Ok(ResultType::IntResult(sum)) + Ok(ResultType::Integer(sum)) } } @@ -94,7 +94,7 @@ mod test { fn test_part1() -> Result<()> { let day = Day {}; let lines = read_lines(day.get_day_number(), "example01.txt")?; - let expected = ResultType::IntResult(2); + let expected = ResultType::Integer(2); let result = day.part1(&lines)?; assert_eq!(result, expected); @@ -105,7 +105,7 @@ mod test { fn test_part2() -> Result<()> { let day = Day {}; let lines = read_lines(day.get_day_number(), "example01.txt")?; - let expected = ResultType::IntResult(4); + let expected = ResultType::Integer(4); let result = day.part2(&lines)?; assert_eq!(result, expected); diff --git a/src/days/template.rs b/src/days/template.rs index fdeae87..73a779d 100644 --- a/src/days/template.rs +++ b/src/days/template.rs @@ -3,10 +3,10 @@ use anyhow::Result; #[allow(dead_code)] #[derive(Debug, PartialEq, Eq)] pub enum ResultType { - IntResult(i64), - StringResult(String), - LinesResult(Vec), - NoResult, + Integer(i64), + String(String), + Lines(Vec), + Nothing, } pub trait DayTrait { diff --git a/src/main.rs b/src/main.rs index ce71b85..ff4cd7f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,9 +11,9 @@ use std::{ }; use thiserror::Error; -fn output(day: usize, part: usize, result: ResultType, time: Duration) -> () { +fn output(day: usize, part: usize, result: ResultType, time: Duration) { match result { - ResultType::IntResult(value) => { + ResultType::Integer(value) => { println!( "Day {:02} part {}: {} ({})", day, @@ -22,7 +22,7 @@ fn output(day: usize, part: usize, result: ResultType, time: Duration) -> () { time.as_secs_f64() ); } - ResultType::StringResult(value) => { + ResultType::String(value) => { println!( "Day {:02} part {}: {} ({})", day, @@ -31,7 +31,7 @@ fn output(day: usize, part: usize, result: ResultType, time: Duration) -> () { time.as_secs_f32() ); } - ResultType::LinesResult(value) => { + ResultType::Lines(value) => { println!( "Day {:02} part {}: {} ({})", day, @@ -40,14 +40,14 @@ fn output(day: usize, part: usize, result: ResultType, time: Duration) -> () { time.as_secs_f32() ); for line in &value[1..] { - println!(" part : {}", line); + println!(" part : {line}"); } } - ResultType::NoResult => {} + ResultType::Nothing => {} } } -fn run_part(day: &Box, is_part1: bool, lines: &[String]) -> Result { +fn run_part(day: &dyn DayTrait, is_part1: bool, lines: &[String]) -> Result { let now = Instant::now(); let result = if is_part1 { day.part1(lines)? @@ -55,7 +55,7 @@ fn run_part(day: &Box, is_part1: bool, lines: &[String]) -> Result day.part2(lines)? }; - if matches!(result, ResultType::NoResult) { + if matches!(result, ResultType::Nothing) { Ok(Duration::ZERO) } else { let elapsed = now.elapsed(); @@ -69,7 +69,7 @@ fn run_part(day: &Box, is_part1: bool, lines: &[String]) -> Result } } -fn run(day: &Box, part1: bool, part2: bool) -> Result { +fn run(day: &dyn DayTrait, part1: bool, part2: bool) -> Result { let lines = read_lines(day.get_day_number(), "input.txt")?; let elapsed1 = if part1 { run_part(day, true, &lines)? @@ -99,25 +99,25 @@ fn run_on_parameters(params: &[String]) -> Result<()> { 0 => { let mut runtime = Duration::ZERO; for day in day_provider::get_all_days() { - runtime += run(&day, true, true)?; + runtime += run(day.as_ref(), true, true)?; } println!(); println!("Runtime: {}", runtime.as_secs_f32()); } 1 => { - let mut parts = params[0].split("/"); + let mut parts = params[0].split('/'); if let Some(day_str) = parts.next() { let day_number = day_str.parse::()?; let day = day_provider::get_day(day_number)?; if let Some(part_str) = parts.next() { match part_str.parse::()? { - 1 => run(&day, true, false)?, - 2 => run(&day, false, true)?, + 1 => run(day.as_ref(), true, false)?, + 2 => run(day.as_ref(), false, true)?, p => Err(ParamError::UnknownPart(p))?, }; } else { - let runtime = run(&day, true, true)?; + let runtime = run(day.as_ref(), true, true)?; println!("Runtime: {}", runtime.as_secs_f32()); } }