From 8d42f5a41537fd599600b0246358843f83d9664f Mon Sep 17 00:00:00 2001 From: Daniel Lin Date: Sat, 7 Dec 2024 03:57:40 -0500 Subject: [PATCH] Day 7: Bridge Repair --- README.md | 2 +- rs/benches/criterion.rs | 8 +++- rs/src/day7.rs | 95 +++++++++++++++++++++++++++++++++++++++++ rs/src/lib.rs | 1 + rs/src/main.rs | 10 ++++- 5 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 rs/src/day7.rs diff --git a/README.md b/README.md index f3aaf501..f00e79b3 100644 --- a/README.md +++ b/README.md @@ -11,4 +11,4 @@ Development occurs in language-specific directories: |[Day4.hs](hs/src/Day4.hs)|[Day4.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day4.kt)|[day4.py](py/aoc2024/day4.py)|[day4.rs](rs/src/day4.rs)| |[Day5.hs](hs/src/Day5.hs)|[Day5.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day5.kt)|[day5.py](py/aoc2024/day5.py)|[day5.rs](rs/src/day5.rs)| |[Day6.hs](hs/src/Day6.hs)|[Day6.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day6.kt)|[day6.py](py/aoc2024/day6.py)|[day6.rs](rs/src/day6.rs)| -|[Day7.hs](hs/src/Day7.hs)|[Day7.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day7.kt)|[day7.py](py/aoc2024/day7.py)|| +|[Day7.hs](hs/src/Day7.hs)|[Day7.kt](kt/aoc2024-lib/src/commonMain/kotlin/com/github/ephemient/aoc2024/Day7.kt)|[day7.py](py/aoc2024/day7.py)|[day7.rs](rs/src/day7.rs)| diff --git a/rs/benches/criterion.rs b/rs/benches/criterion.rs index 72292072..d946b4d9 100644 --- a/rs/benches/criterion.rs +++ b/rs/benches/criterion.rs @@ -1,4 +1,4 @@ -use aoc2024::{day1, day2, day3, day4, day5, day6}; +use aoc2024::{day1, day2, day3, day4, day5, day6, day7}; use criterion::{black_box, Criterion}; use std::env; use std::fs; @@ -50,6 +50,12 @@ fn aoc2024_bench(c: &mut Criterion) -> io::Result<()> { g.bench_function("part 2", |b| b.iter(|| day6::part2(black_box(&data)))); g.finish(); + let data = get_day_input(7)?; + let mut g = c.benchmark_group("day 7"); + g.bench_function("part 1", |b| b.iter(|| day7::part1(black_box(&data)))); + g.bench_function("part 2", |b| b.iter(|| day7::part2(black_box(&data)))); + g.finish(); + Ok(()) } diff --git a/rs/src/day7.rs b/rs/src/day7.rs new file mode 100644 index 00000000..0b4b9b19 --- /dev/null +++ b/rs/src/day7.rs @@ -0,0 +1,95 @@ +fn solve(data: &str, op: F) -> usize +where + F: Fn(usize, usize) -> I, + I: IntoIterator, +{ + data.lines() + .filter_map(|line| { + let (lhs, rhs) = line.split_once(": ")?; + let lhs = lhs.parse::().ok()?; + let rhs = rhs + .split_ascii_whitespace() + .map(|value| value.parse()) + .collect::, _>>() + .ok()?; + let mut stack = vec![(lhs, rhs)]; + while let Some((x, mut rest)) = stack.pop() { + let y = rest.pop()?; + if rest.is_empty() { + if x == y { + return Some(lhs); + } + continue; + } + for z in op(x, y) { + stack.push((z, rest.clone())); + } + } + None + }) + .sum() +} + +pub fn part1(data: &str) -> usize { + solve(data, |x, y| { + let mut values = vec![]; + if let Some(z) = x.checked_sub(y) { + values.push(z); + } + if x % y == 0 { + values.push(x / y); + } + values + }) +} + +pub fn part2(data: &str) -> usize { + solve(data, |x, y| { + let mut values = vec![]; + if let Some(z) = x.checked_sub(y) { + values.push(z); + } + if x % y == 0 { + values.push(x / y); + } + if x > y { + let mut d = 10; + while d <= y { + d *= 10; + } + if x % d == y { + values.push(x / d); + } + } + values + }) +} + +#[cfg(test)] +mod tests { + use super::*; + use indoc::indoc; + use pretty_assertions::assert_eq; + + static EXAMPLE: &str = indoc! {" + 190: 10 19 + 3267: 81 40 27 + 83: 17 5 + 156: 15 6 + 7290: 6 8 6 15 + 161011: 16 10 13 + 192: 17 8 14 + 21037: 9 7 18 13 + 292: 11 6 16 20 + "}; + + #[test] + fn part1_examples() { + assert_eq!(3749, part1(EXAMPLE)); + } + + #[test] + fn part2_examples() { + assert_eq!(11387, part2(EXAMPLE)); + } +} diff --git a/rs/src/lib.rs b/rs/src/lib.rs index d52973ba..da2f9142 100644 --- a/rs/src/lib.rs +++ b/rs/src/lib.rs @@ -4,3 +4,4 @@ pub mod day3; pub mod day4; pub mod day5; pub mod day6; +pub mod day7; diff --git a/rs/src/main.rs b/rs/src/main.rs index 93c985f8..0c506941 100644 --- a/rs/src/main.rs +++ b/rs/src/main.rs @@ -1,5 +1,5 @@ use anyhow::anyhow; -use aoc2024::{day1, day2, day3, day4, day5, day6}; +use aoc2024::{day1, day2, day3, day4, day5, day6, day7}; use std::collections::HashSet; use std::env; use std::fs; @@ -65,5 +65,13 @@ fn main() -> anyhow::Result<()> { println!(); } + if args.is_empty() || args.contains("7") { + println!("Day 7"); + let data = get_day_input(7)?; + println!("{:?}", day7::part1(&data)); + println!("{:?}", day7::part2(&data)); + println!(); + } + Ok(()) }