From 6960cc3a99e943ef4a694307dc9204a11f610a43 Mon Sep 17 00:00:00 2001 From: sepia Date: Sat, 7 Dec 2024 08:06:32 -0600 Subject: [PATCH] Day 7 --- Cargo.lock | 10 ++++++++ Cargo.toml | 1 + src/day7.rs | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 9 ++++++- 4 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 src/day7.rs diff --git a/Cargo.lock b/Cargo.lock index 1bb8fc2..220a40a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -22,6 +22,7 @@ name = "advent" version = "0.1.0" dependencies = [ "dotenvy", + "itertools", "rayon", "regex", "reqwest", @@ -586,6 +587,15 @@ version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ddc24109865250148c2e0f3d25d4f0f479571723792d3802153c60922a4fb708" +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.14" diff --git a/Cargo.toml b/Cargo.toml index 6d1775b..68bccab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,6 +5,7 @@ edition = "2021" [dependencies] dotenvy = "0.15.7" +itertools = "0.13.0" rayon = "1.10.0" regex = "1.11.1" reqwest = { version = "0.12.9", features = ["blocking"] } diff --git a/src/day7.rs b/src/day7.rs new file mode 100644 index 0000000..aea8284 --- /dev/null +++ b/src/day7.rs @@ -0,0 +1,67 @@ +use itertools::{repeat_n, Itertools}; +use rayon::prelude::*; +use regex::Regex; + +pub fn day7() { + let lines: Vec<(u64, Vec)> = parse_input(&crate::input(7)); + + let simple_operations = vec![Operation::Add, Operation::Mul]; + let simple_operations_total: u64 = lines + .par_iter() + .filter(|(goal, operands)| possible_totals(operands, &simple_operations).contains(goal)) + .map(|(goal, _)| goal) + .sum(); + + let all_operations = vec![Operation::Add, Operation::Mul, Operation::Cat]; + let all_operations_total: u64 = lines + .par_iter() + .filter(|(goal, operands)| possible_totals(operands, &all_operations).contains(goal)) + .map(|(goal, _)| goal) + .sum(); + + println!("Total for +/*: {}", simple_operations_total); + println!("Total for All: {}", all_operations_total); +} + +fn possible_totals(operands: &Vec, operations: &Vec) -> Vec { + repeat_n(operations, operands.len() - 1) + .multi_cartesian_product() + .map(|operations| { + operands[1..] + .iter() + .zip(operations) + .fold(operands[0], |acc, (e, op)| op.apply(acc, *e)) + }) + .collect() +} + +fn parse_input(input: &str) -> Vec<(u64, Vec)> { + input + .lines() + .map(|line| { + let all: Vec = Regex::new(r"\D+") + .unwrap() + .split(line) + .map(|s| s.parse().unwrap()) + .collect(); + (all[0], all[1..].to_vec()) + }) + .collect() +} + +#[derive(Clone)] +enum Operation { + Add, + Mul, + Cat, +} + +impl Operation { + fn apply(&self, a: u64, b: u64) -> u64 { + match self { + Self::Add => a + b, + Self::Mul => a * b, + Self::Cat => (a.to_string() + &b.to_string()).parse().unwrap(), + } + } +} diff --git a/src/main.rs b/src/main.rs index 28a2dbd..2ee5ab4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,19 @@ +#[allow(dead_code)] mod day1; +#[allow(dead_code)] mod day2; +#[allow(dead_code)] mod day3; +#[allow(dead_code)] mod day4; +#[allow(dead_code)] mod day5; +#[allow(dead_code)] mod day6; +mod day7; fn main() { - day6::day6(); + day7::day7(); } pub fn input(day: u8) -> String {