first two days

This commit is contained in:
Russell Champoux committed 2025-12-02 20:32:01 +00:00
1 parent 539d8f7e54
commit 65265f3489
7 files changed
+209

No files matched your search

Generated
+55
View File
@@ -23,10 +23,21 @@ version = "0.12.0"
dependencies = [ dependencies = [
"chrono", "chrono",
"dhat", "dhat",
"itertools",
"pico-args", "pico-args",
"regex",
"tinyjson", "tinyjson",
] ]
[[package]]
name = "aho-corasick"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301"
dependencies = [
"memchr",
]
[[package]] [[package]]
name = "android-tzdata" name = "android-tzdata"
version = "0.1.1" version = "0.1.1"
@@ -126,6 +137,12 @@ dependencies = [
"thousands", "thousands",
] ]
[[package]]
name = "either"
version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]] [[package]]
name = "gimli" name = "gimli"
version = "0.28.1" version = "0.28.1"
@@ -155,6 +172,15 @@ dependencies = [
"cc", "cc",
] ]
[[package]]
name = "itertools"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285"
dependencies = [
"either",
]
[[package]] [[package]]
name = "itoa" name = "itoa"
version = "1.0.9" version = "1.0.9"
@@ -303,6 +329,35 @@ dependencies = [
"bitflags", "bitflags",
] ]
[[package]]
name = "regex"
version = "1.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58"
[[package]] [[package]]
name = "rustc-demangle" name = "rustc-demangle"
version = "0.1.23" version = "0.1.23"
+2
View File
@@ -24,7 +24,9 @@ test_lib = []
# Template dependencies # Template dependencies
chrono = { version = "0.4.38", optional = true } chrono = { version = "0.4.38", optional = true }
dhat = { version = "0.3.3", optional = true } dhat = { version = "0.3.3", optional = true }
itertools = "0.14.0"
pico-args = "0.5.0" pico-args = "0.5.0"
regex = "1.12.2"
tinyjson = "2.5.1" tinyjson = "2.5.1"
# Solution dependencies # Solution dependencies
+9
View File
@@ -6,6 +6,15 @@ Solutions for [Advent of Code](https://adventofcode.com/) in [Rust](https://www.
<!--- advent_readme_stars table ---> <!--- advent_readme_stars table --->
<!--- benchmarking table --->
## Benchmarks
| Day | Part 1 | Part 2 |
| :---: | :---: | :---: |
| [Day 1](./src/bin/01.rs) | `881.1µs` | `849.0µs` |
| [Day 2](./src/bin/02.rs) | `225.7ms` | `250.4ms` |
**Total: 477.83ms**
<!--- benchmarking table ---> <!--- benchmarking table --->
--- ---
+10
View File
@@ -0,0 +1,10 @@
L68
L30
R48
L5
R60
L55
L1
L99
R14
L82
+1
View File
@@ -0,0 +1 @@
11-22,95-115,998-1012,1188511880-1188511890,222220-222224,1698522-1698528,446443-446449,38593856-38593862,565653-565659,824824821-824824827,2121212118-2121212124
+56
View File
@@ -0,0 +1,56 @@
advent_of_code::solution!(1);
use regex::Regex;
pub fn part_one(input: &str) -> Option<u64> {
let dir_regex = Regex::new(r"(.)(\d+)").unwrap();
let (hits, _total) = dir_regex.captures_iter(input).fold((0u32, 50i32), |(hits, total), cap| {
let (_, [direction, value_str]) = cap.extract();
let value = value_str.parse::<i32>().unwrap();
let new_total = (total + 100 + if direction == "L" { -1i32 } else { 1 } * value) % 100;
let new_hits = if new_total == 0 { hits + 1 } else { hits };
// println!("{} + {} {} = {}", total, direction, value, new_total);
(new_hits, new_total)
});
Some(hits as u64)
}
pub fn part_two(input: &str) -> Option<u64> {
let dir_regex = Regex::new(r"(.)(\d+)").unwrap();
let (hits, _total) = dir_regex.captures_iter(input).fold((0u32, 50i32), |(hits, total), cap| {
let (_, [direction, value_str]) = cap.extract();
let value: i32 = value_str.parse::<i32>().unwrap();
let new_total_unmod = total + if direction == "L" { -1i32 } else { 1 } * value;
let new_total = (new_total_unmod % 100 + 100) % 100;
let clicks_past_zero = (new_total_unmod / 100).abs() as u32 + if total != 0 && new_total_unmod <= 0 { 1 } else { 0 };
// println!("{} + {} {} = {} ({} total clicks, {} new)", total, direction, value, new_total, hits + clicks_past_zero, clicks_past_zero);
(hits + clicks_past_zero, new_total)
});
Some(hits as u64)
}
#[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(3));
}
#[test]
fn test_part_two() {
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
assert_eq!(result, Some(6));
}
}
+76
View File
@@ -0,0 +1,76 @@
advent_of_code::solution!(2);
use itertools::Itertools;
pub fn part_one(input: &str) -> Option<u64> {
let mut sum: u64 = 0;
for range in input.split(',') {
// println!("Range is: {}", range);
let values = range.split('-').map(|v| v.trim().parse::<u64>().unwrap()).collect::<Vec<u64>>();
let start = values[0];
let end = values[1];
// println!("Range: {}-{}", start, end);
for n in start..=end {
let s = n.to_string();
if s.chars().collect_vec().len() % 2 != 0 {
continue;
}
let first_half = &s[0..(s.len() / 2)];
let second_half = &s[(s.len() / 2)..s.len()];
if first_half == second_half {
// println!(" Number: {} ({} | {})", n, first_half, second_half);
sum += n;
}
}
}
Some(sum)
}
pub fn part_two(input: &str) -> Option<u64> {
let mut sum: u64 = 0;
for range in input.split(',') {
// println!("Range is: {}", range);
let values = range.split('-').map(|v| v.trim().parse::<u64>().unwrap()).collect::<Vec<u64>>();
let start = values[0];
let end = values[1];
// println!("Range: {}-{}", start, end);
for n in start..=end {
let s = n.to_string();
let total_chars = s.chars().collect_vec().len();
'takeBy: for take_by in 1..=(total_chars / 2) {
if total_chars % take_by != 0 {
continue;
}
let mut idx = 0;
while idx + 2 * take_by <= total_chars {
let part = &s[idx..(idx + take_by)];
let next_part = &s[(idx + take_by)..(idx + 2 * take_by)];
if part != next_part {
continue 'takeBy;
}
idx += take_by;
}
// println!(" Number: {} (take by {})", n, take_by);
sum += n;
break; // do not continue checking other take_by values
}
}
}
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));
}
}