From 6960cc3a99e943ef4a694307dc9204a11f610a43 Mon Sep 17 00:00:00 2001 From: sepia Date: Sat, 7 Dec 2024 08:06:32 -0600 Subject: [PATCH 1/3] 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 { From 3b4d813cffc813abf306f8456854ec82eeecae54 Mon Sep 17 00:00:00 2001 From: sepia Date: Sun, 8 Dec 2024 08:40:57 -0600 Subject: [PATCH 2/3] Day 8 --- src/main.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 2ee5ab4..d324f4a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,10 +10,12 @@ mod day4; mod day5; #[allow(dead_code)] mod day6; +#[allow(dead_code)] mod day7; +mod day8; fn main() { - day7::day7(); + day8::day8(); } pub fn input(day: u8) -> String { From 03126018d08cae46cd40fbc93eae4287b6702013 Mon Sep 17 00:00:00 2001 From: sepia Date: Sun, 8 Dec 2024 08:41:41 -0600 Subject: [PATCH 3/3] Day 8 --- src/day8.rs | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 src/day8.rs diff --git a/src/day8.rs b/src/day8.rs new file mode 100644 index 0000000..a8778b9 --- /dev/null +++ b/src/day8.rs @@ -0,0 +1,57 @@ +use itertools::Itertools; +use std::collections::HashMap; + +const EXTEND: bool = true; + +pub fn day8() { + let (antennae, width, height) = input(); + + let mut antinodes: Vec<(i64, i64)> = antennae + .values() + .flat_map(|antennae_set| { + antennae_set + .iter() + .combinations(2) + .flat_map(|pair| { + let ((x1, y1), (x2, y2)) = (pair[0], pair[1]); + let (dx, dy) = (x2 - x1, y2 - y1); + + if EXTEND { + (0..width.max(height)) + .flat_map(|i| [(x1 - dx * i, y1 - dy * i), (x1 + dx * i, y1 + dy * i)]) + .collect() + } else { + vec![(x1 - dx, y1 - dy), (x2 + dx, y2 + dy)] + } + }) + .collect::>() + }) + .filter(|(x, y)| *x < width && *y < height && *x >= 0 && *y >= 0) + .collect(); + antinodes.sort(); + antinodes.dedup(); + + println!("Unique Antinodes: {}", antinodes.len()); +} + +fn input() -> (HashMap>, i64, i64) { + let input = crate::input(8); + + let unsorted_antennae = input.lines().enumerate().flat_map(|(y, line)| { + line.chars() + .enumerate() + .filter(|(_, c)| *c != '.') + .map(move |(x, c)| (c, (x as i64, y as i64))) + }); + + let mut antennae = HashMap::>::new(); + for (c, p) in unsorted_antennae { + antennae.entry(c).or_default().push(p); + } + + ( + antennae, + input.lines().nth(0).unwrap().len() as i64, + input.lines().count() as i64, + ) +}