garnet/rust/puzzles/day2.rs

70 lines
1.7 KiB
Rust
Raw Normal View History

2025-12-10 10:51:30 +00:00
use crate::puzzle::Puzzle;
2025-12-10 12:39:12 +00:00
use nom::{
Parser,
character::complete::{char, newline, usize},
combinator::eof,
2025-12-10 12:39:12 +00:00
error::Error,
multi::separated_list1,
sequence::{separated_pair, terminated},
};
2025-12-10 10:51:30 +00:00
pub const PUZZLE: Puzzle<Vec<(usize, usize)>, 2> = Puzzle {
2025-12-10 10:51:30 +00:00
number: 2,
parser: |_, input| {
terminated::<_, _, Error<&str>, _, _>(
2025-12-10 12:39:12 +00:00
terminated(
separated_list1(char(','), separated_pair(usize, char('-'), usize)),
2025-12-10 12:39:12 +00:00
newline,
),
eof,
)
.parse(input)
.unwrap()
.1
2025-12-10 10:51:30 +00:00
},
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::<usize>()
.to_string()
2025-12-10 10:51:30 +00:00
},
|input| {
input
.into_iter()
.flat_map(|(l, u)| {
(*l..(u + 1)).flat_map(|n| if is_repetition_n(n) { Some(n) } else { None })
})
.sum::<usize>()
.to_string()
2025-12-10 10:51:30 +00:00
},
],
};
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))
2025-12-10 10:51:30 +00:00
}
fn equal_chunks(n: &String, i: usize) -> bool {
let chars = n.chars().collect::<Vec<char>>();
2025-12-17 14:25:10 +00:00
let mut chunks = chars.chunks(i);
2025-12-10 10:51:30 +00:00
match chunks.next() {
None => true,
Some(x) => chunks.all(|y| y == x),
}
}