diff options
Diffstat (limited to '2025/d2.rs')
| -rw-r--r-- | 2025/d2.rs | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/2025/d2.rs b/2025/d2.rs new file mode 100644 index 0000000..9c2b060 --- /dev/null +++ b/2025/d2.rs @@ -0,0 +1,110 @@ +use aoc::fetch::fetch; + +struct Checker { + first: usize, + last: usize, +} + +impl Checker { + fn new(first: usize, last: usize) -> Result<Self, ()> { + if first + .to_string() + .chars() + .next() + .unwrap() + == '0' + { + return Err(()); + } + + Ok( + Self { + first, + last, + }, + ) + } + + fn parse_section_part1(num: usize) -> usize { + let s = num.to_string(); + let len = s.len(); + for substr_len in 1..=len / 2 { + if len % substr_len == 0 { + let first = &s[0..substr_len]; + if s.as_bytes() + .chunks(substr_len) + .all(|chunk| chunk == first.as_bytes()) + { + return num; + } + } + } + 0 + } + + fn parse_section_part2(num: usize) -> usize { + let s = num.to_string(); + if s.len() % 2 != 0 { + return 0; + } + if s[0..s.len() / 2] == s[s.len() / 2..s.len()] { + return num; + } + 0 + } + + fn parse(self, part2: bool) -> usize { + let mut ans = 0; + for i in self.first..=self.last { + ans += if part2 { + Self::parse_section_part2(i) + } else { + Self::parse_section_part1(i) + }; + } + ans + } +} + +fn run(part2: bool) { + let input = fetch( + 2, ',', + ); + let mut ans = 0; + + for s in input { + let s = s.replace( + '\n', "", + ); + if s.is_empty() { + continue; + } + let split = s.split('-'); + let first = split + .clone() + .next() + .unwrap() + .parse() + .unwrap(); + let last = split + .clone() + .nth(1) + .unwrap() + .parse() + .unwrap(); + ans += &Checker::new( + first, last, + ) + .unwrap() + .parse(part2); + } + println!("{ans}"); +} + +pub fn part1() { + run(false); +} + +pub fn part2() { + run(true); +} |
