From 1c9a690572608227ba930d128f8435910baa62d3 Mon Sep 17 00:00:00 2001 From: SebastianStork Date: Tue, 2 Dec 2025 11:40:26 +0100 Subject: [PATCH] Solve 2025 day 2 in rust --- 2025/rust/day-02/Cargo.lock | 7 ++ 2025/rust/day-02/Cargo.toml | 6 ++ 2025/rust/day-02/src/main.rs | 126 +++++++++++++++++++++++++++++++++++ flake.lock | 6 +- 4 files changed, 142 insertions(+), 3 deletions(-) create mode 100644 2025/rust/day-02/Cargo.lock create mode 100644 2025/rust/day-02/Cargo.toml create mode 100644 2025/rust/day-02/src/main.rs diff --git a/2025/rust/day-02/Cargo.lock b/2025/rust/day-02/Cargo.lock new file mode 100644 index 0000000..5de1616 --- /dev/null +++ b/2025/rust/day-02/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "day-02" +version = "0.1.0" diff --git a/2025/rust/day-02/Cargo.toml b/2025/rust/day-02/Cargo.toml new file mode 100644 index 0000000..89fee24 --- /dev/null +++ b/2025/rust/day-02/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "day-02" +version = "0.1.0" +edition = "2024" + +[dependencies] diff --git a/2025/rust/day-02/src/main.rs b/2025/rust/day-02/src/main.rs new file mode 100644 index 0000000..24bad1d --- /dev/null +++ b/2025/rust/day-02/src/main.rs @@ -0,0 +1,126 @@ +use std::fs; + +fn main() { + let ranges = parse_input(&fs::read_to_string("../../inputs/02.txt").unwrap()); + + println!("Sum1: {}", sum_of_invalid_ids(&ranges, is_mirrored_number)); + println!( + "Sum2: {}", + sum_of_invalid_ids(&ranges, is_repeating_pattern) + ); +} + +fn parse_input(contents: &str) -> Vec<(u64, u64)> { + contents + .trim() + .split(",") + .map(|part: &str| { + let (num1, num2) = part.split_once("-").unwrap(); + (num1.parse::().unwrap(), num2.parse::().unwrap()) + }) + .collect() +} + +fn sum_of_invalid_ids(ranges: &[(u64, u64)], is_invalid: fn(u64) -> bool) -> u64 { + let mut sum = 0; + + for (first, last) in ranges { + for num in *first..=*last { + if is_invalid(num) { + sum += num; + } + } + } + + sum +} + +fn is_mirrored_number(num: u64) -> bool { + let digits = number_of_digits(num); + if !digits.is_multiple_of(2) { + return false; + } + + let divisor = 10_u64.pow((digits / 2) as u32); + + let left = num / divisor; + let right = num % divisor; + + left == right +} + +fn is_repeating_pattern(num: u64) -> bool { + let digits = number_of_digits(num); + if digits == 1 { + return false; + } + + let chunk_sizes = factorization(digits); + + for chunk_size in &chunk_sizes { + let divisor = 10_u64.pow(*chunk_size as u32); + let pattern = num % divisor; + + let mut remainder = num / divisor; + let mut ok = true; + + let chunks_left: u64 = digits / chunk_size - 1; + for _ in 0..chunks_left { + if remainder % divisor != pattern { + ok = false; + break; + } + remainder /= divisor; + } + + if ok { + return true; + } + } + + false +} + +fn number_of_digits(num: u64) -> u64 { + (num.ilog10() as u64) + 1 +} + +fn factorization(num: u64) -> Vec { + let primes = [2, 3, 5, 7]; + if primes.contains(&num) { + return vec![1]; + } + + let mut factors = vec![]; + + for factor in (2..=num / 2).rev() { + if num.is_multiple_of(factor) && num != factor { + factors.push(factor); + } + } + + factors +} + +#[cfg(test)] +mod tests { + use super::*; + + const TEST_INPUT: &str = "11-22,95-115,998-1012,1188511880-1188511890,222220-222224,1698522-1698528,446443-446449,38593856-38593862,565653-565659,824824821-824824827,2121212118-2121212124"; + + #[test] + fn test_part1() { + assert_eq!( + sum_of_invalid_ids(&parse_input(TEST_INPUT), is_mirrored_number), + 1227775554 + ); + } + + #[test] + fn test_part2() { + assert_eq!( + sum_of_invalid_ids(&parse_input(TEST_INPUT), is_repeating_pattern), + 4174379265 + ); + } +} diff --git a/flake.lock b/flake.lock index 94895f4..f6b4705 100644 --- a/flake.lock +++ b/flake.lock @@ -3,10 +3,10 @@ "inputs": { "flake": false, "locked": { - "lastModified": 1764611941, - "narHash": "sha256-GEVJK9tSeNnGgYYRbjtYE/su75nxRvOm8h0Sf5GD70A=", + "lastModified": 1764662864, + "narHash": "sha256-PZStjjkkc1p4qCdVBoPpkpWeINSfq1yPilw/slK9E8k=", "ref": "refs/heads/main", - "rev": "5390449be22f56739e0840e35e46d54b1166886c", + "rev": "2e87000c9541f3b52db15834366cfb487c6cc523", "shallow": true, "type": "git", "url": "ssh://git@github.com/SebastianStork/advent-of-code-inputs.git"