diff --git a/2024/day7/.gitignore b/2024/day7/.gitignore new file mode 100644 index 0000000..2ac37a0 --- /dev/null +++ b/2024/day7/.gitignore @@ -0,0 +1,2 @@ +target +input.txt diff --git a/2024/day7/Cargo.lock b/2024/day7/Cargo.lock new file mode 100644 index 0000000..d76aa5d --- /dev/null +++ b/2024/day7/Cargo.lock @@ -0,0 +1,61 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + +[[package]] +name = "day7" +version = "0.1.0" +dependencies = [ + "rayon", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] diff --git a/2024/day7/Cargo.toml b/2024/day7/Cargo.toml new file mode 100644 index 0000000..8d90871 --- /dev/null +++ b/2024/day7/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "day7" +version = "0.1.0" +edition = "2021" + +[dependencies] +rayon = "1.10.0" diff --git a/2024/day7/src/main.rs b/2024/day7/src/main.rs new file mode 100644 index 0000000..e2e5db8 --- /dev/null +++ b/2024/day7/src/main.rs @@ -0,0 +1,62 @@ +use std::{fs, time::Instant}; + +use rayon::prelude::*; + +fn main() { + let file = fs::read_to_string("./input.txt").unwrap(); + + let data = file + .lines() + .map(|line| { + line.replace(":", "") + .split_whitespace() + .filter_map(|x| x.parse::().ok()) + .collect::>() + }) + .collect::>>(); + + let ops = vec![ + |a: u64, b: u64| a + b, + |a: u64, b: u64| a * b, + |a: u64, b: u64| a * 10u64.pow(b.ilog10() + 1) + b, + ]; + + let start = Instant::now(); + println!("Solution 1: {}", puzzle1(&data, &ops[..2])); + let end = Instant::now() - start; + println!("Solution 1 time: {}", end.as_micros()); + + let start = Instant::now(); + println!("Solution 2: {}", puzzle2(&data, &ops)); + let end = Instant::now() - start; + println!("Solution 2 time: {}", end.as_micros()); +} + +fn puzzle1(input: &[Vec], ops: &[fn(u64, u64) -> u64]) -> u64 { + input.par_iter().map(|nums| solve(nums, ops)).sum::() +} + +fn puzzle2(input: &[Vec], ops: &[fn(u64, u64) -> u64]) -> u64 { + input.par_iter().map(|nums| solve(nums, ops)).sum::() +} + +fn solve(nums: &[u64], ops: &[fn(u64, u64) -> u64]) -> u64 { + if nums.len() == 2 { + return (nums[0] == nums[1]) as u64; + } + + let (total, rest) = nums.split_first().unwrap(); + let (a, rest) = rest.split_first().unwrap(); + let (b, rest) = rest.split_first().unwrap(); + + for op in ops { + let mut new_nums = vec![*total, op(*a, *b)]; + new_nums.extend_from_slice(rest); + + if solve(&new_nums, ops) != 0 { + return *total; + } + } + + 0 +}