diff --git a/rust/main.rs b/rust/main.rs index 1b39588..71c853b 100644 --- a/rust/main.rs +++ b/rust/main.rs @@ -2,10 +2,11 @@ mod puzzle; mod puzzles; use crate::puzzle::Puzzle; use puzzles::day1; +use puzzles::day2; use std::fmt::Display; use std::fs; -const PUZZLES: [&dyn SomePuzzle; 1] = [&day1::PUZZLE]; +const PUZZLES: [&dyn SomePuzzle; 2] = [&day1::PUZZLE, &day2::PUZZLE]; fn main() { [false, true].iter().for_each(|is_real_data| { diff --git a/rust/puzzles/day2.rs b/rust/puzzles/day2.rs new file mode 100644 index 0000000..3d2866f --- /dev/null +++ b/rust/puzzles/day2.rs @@ -0,0 +1,64 @@ +use crate::puzzle::Puzzle; + +pub const PUZZLE: Puzzle, usize, 2> = Puzzle { + number: 2, + parser: |input| { + input + .strip_suffix("\n") + .unwrap() + .split(',') + .map(|range| { + match range + .split('-') + .map(|n| n.parse().unwrap()) + .collect::>()[..] + { + [a, b] => (a, b), + _ => panic!(), + } + }) + .collect() + }, + parts: [ + |input| { + input + .into_iter() + .flat_map(|(l, u)| { + (*l..(u + 1)).flat_map(|n| if is_repetition_2(n) { Some(n) } else { None }) + }) + .sum() + }, + |input| { + input + .into_iter() + .flat_map(|(l, u)| { + (*l..(u + 1)).flat_map(|n| if is_repetition_n(n) { Some(n) } else { None }) + }) + .sum() + }, + ], +}; + +fn is_repetition_2(n: usize) -> bool { + let n = n.to_string(); + let l = n.len(); + let d = l / 2; + let r = l % 2; + if r == 0 { equal_chunks(&n, d) } else { false } +} + +fn is_repetition_n(n: usize) -> bool { + let n = n.to_string(); + let l = n.len(); + let d = l / 2; + (1..(d + 1)).any(|i| equal_chunks(&n, i)) +} + +fn equal_chunks(n: &String, i: usize) -> bool { + let chars = n.chars().collect::>(); + let mut chunks = (chars[..]).chunks(i); + match chunks.next() { + None => true, + Some(x) => chunks.all(|y| y == x), + } +} diff --git a/rust/puzzles/mod.rs b/rust/puzzles/mod.rs index ca9500f..7daf67a 100644 --- a/rust/puzzles/mod.rs +++ b/rust/puzzles/mod.rs @@ -1 +1,2 @@ pub(crate) mod day1; +pub(crate) mod day2;