From a402156786ef23a7f71510a2ac0d42713e3932b3 Mon Sep 17 00:00:00 2001 From: Russell Champoux Date: Thu, 4 Dec 2025 17:11:46 -0500 Subject: [PATCH] Solve Day 2: Gift Shop --- README.md | 3 +- data/examples/02.txt | 2 + src/bin/02.rs | 110 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 data/examples/02.txt create mode 100644 src/bin/02.rs diff --git a/README.md b/README.md index 70af4d3..2562a95 100644 --- a/README.md +++ b/README.md @@ -12,8 +12,9 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www. | Day | Part 1 | Part 2 | | :---: | :---: | :---: | | [Day 1](./src/bin/01.rs) | `113.0µs` | `119.9µs` | +| [Day 2](./src/bin/02.rs) | `54.7ms` | `71.6ms` | -**Total: 0.23ms** +**Total: 126.53ms** --- diff --git a/data/examples/02.txt b/data/examples/02.txt new file mode 100644 index 0000000..871da5e --- /dev/null +++ b/data/examples/02.txt @@ -0,0 +1,2 @@ +11-22,95-115,998-1012,1188511880-1188511890,222220-222224,1698522-1698528,446443-446449,38593856-38593862,565653-565659,824824821-824824827,2121212118-2121212124 + diff --git a/src/bin/02.rs b/src/bin/02.rs new file mode 100644 index 0000000..8d1722c --- /dev/null +++ b/src/bin/02.rs @@ -0,0 +1,110 @@ +advent_of_code::solution!(2); + +/// Check if a number is "invalid" - made of a pattern repeated exactly twice +fn is_invalid_part1(n: u64) -> bool { + let s = n.to_string(); + let len = s.len(); + // Must have even length for pattern to repeat exactly twice + if len % 2 != 0 { + return false; + } + let half = len / 2; + s[..half] == s[half..] +} + +pub fn part_one(input: &str) -> Option { + let mut sum = 0u64; + + // Parse comma-separated ranges, handling potential whitespace/newlines + for part in input.split(',') { + let part = part.trim(); + if part.is_empty() { + continue; + } + + // Parse "start-end" range + let mut range_parts = part.split('-'); + let start: u64 = range_parts.next()?.parse().ok()?; + let end: u64 = range_parts.next()?.parse().ok()?; + + // Check each number in the range + for n in start..=end { + if is_invalid_part1(n) { + sum += n; + } + } + } + + Some(sum) +} + +/// Check if a number is "invalid" - made of a pattern repeated at least twice +fn is_invalid_part2(n: u64) -> bool { + let s = n.to_string(); + let len = s.len(); + + // Try each possible pattern length (1 to len/2) + for pattern_len in 1..=len / 2 { + // Pattern can only work if it divides evenly + if len % pattern_len != 0 { + continue; + } + + let pattern = &s[..pattern_len]; + let mut is_match = true; + + // Check if the entire string is made of this pattern repeated + for i in (pattern_len..len).step_by(pattern_len) { + if &s[i..i + pattern_len] != pattern { + is_match = false; + break; + } + } + + if is_match { + return true; + } + } + + false +} + +pub fn part_two(input: &str) -> Option { + let mut sum = 0u64; + + for part in input.split(',') { + let part = part.trim(); + if part.is_empty() { + continue; + } + + let mut range_parts = part.split('-'); + let start: u64 = range_parts.next()?.parse().ok()?; + let end: u64 = range_parts.next()?.parse().ok()?; + + for n in start..=end { + if is_invalid_part2(n) { + sum += n; + } + } + } + + Some(sum) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_part_one() { + let result = part_one(&advent_of_code::template::read_file("examples", DAY)); + assert_eq!(result, Some(1227775554)); + } + + #[test] + fn test_part_two() { + let result = part_two(&advent_of_code::template::read_file("examples", DAY)); + assert_eq!(result, Some(4174379265)); + } +}