From 1277882310430e4914201b9fd9fdea8066f1d98d Mon Sep 17 00:00:00 2001 From: Jan-Bulthuis Date: Sun, 8 Dec 2024 10:54:48 +0100 Subject: [PATCH] day8 --- aoc_2024/Cargo.lock | 80 +++++++++++++++++++++++++++++ aoc_2024/Cargo.toml | 1 + aoc_2024/src/day3.rs | 8 +++ aoc_2024/src/day8.rs | 117 +++++++++++++++++++++++++++++++++++++++++++ aoc_2024/src/lib.rs | 1 + 5 files changed, 207 insertions(+) create mode 100644 aoc_2024/src/day8.rs diff --git a/aoc_2024/Cargo.lock b/aoc_2024/Cargo.lock index 65e034a..54509ae 100644 --- a/aoc_2024/Cargo.lock +++ b/aoc_2024/Cargo.lock @@ -47,10 +47,17 @@ dependencies = [ "aoc-runner", "aoc-runner-derive", "nom", + "num", "regex", "topological-sort", ] +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + [[package]] name = "itoa" version = "1.0.14" @@ -79,6 +86,79 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + [[package]] name = "proc-macro2" version = "1.0.92" diff --git a/aoc_2024/Cargo.toml b/aoc_2024/Cargo.toml index 70f6aa1..ab25eaf 100644 --- a/aoc_2024/Cargo.toml +++ b/aoc_2024/Cargo.toml @@ -7,5 +7,6 @@ edition = "2021" aoc-runner = "0.3.0" aoc-runner-derive = "0.3.0" nom = "7.1.3" +num = "0.4.3" regex = "1.11.1" topological-sort = "0.2.2" diff --git a/aoc_2024/src/day3.rs b/aoc_2024/src/day3.rs index 6496cc5..ea94695 100644 --- a/aoc_2024/src/day3.rs +++ b/aoc_2024/src/day3.rs @@ -52,6 +52,10 @@ mod tests { )), 161 ); + assert_eq!( + part1(&parse(include_str!("../input/2024/day3.txt"))), + 191183308 + ); } #[test] @@ -62,5 +66,9 @@ mod tests { )), 48 ); + assert_eq!( + part2(&parse(include_str!("../input/2024/day3.txt"))), + 92082041 + ); } } diff --git a/aoc_2024/src/day8.rs b/aoc_2024/src/day8.rs new file mode 100644 index 0000000..98bb43c --- /dev/null +++ b/aoc_2024/src/day8.rs @@ -0,0 +1,117 @@ +use std::collections::{HashMap, HashSet}; + +use aoc_runner_derive::{aoc, aoc_generator}; +use num::integer::gcd; + +type Input = ((isize, isize), Vec>); + +#[aoc_generator(day8)] +fn parse(input: &str) -> Input { + let mut map = HashMap::new(); + let h = input.lines().count(); + let w = input.lines().find(|_| true).unwrap().len(); + input.lines().enumerate().for_each(|(y, line)| { + line.chars() + .enumerate() + .filter(|(_, c)| c != &'.') + .for_each(|(x, c)| { + if let std::collections::hash_map::Entry::Vacant(e) = map.entry(c) { + e.insert(vec![(x as isize, y as isize)]); + } else { + map.get_mut(&c).unwrap().push((x as isize, y as isize)); + } + }); + }); + let vec = map.into_values().collect(); + ((w as isize, h as isize), vec) +} + +#[aoc(day8, part1)] +fn part1(input: &Input) -> usize { + let mut set = HashSet::new(); + input.1.iter().for_each(|vec| { + for l in 0..vec.len() { + for r in l + 1..vec.len() { + let a1 = vec[l]; + let a2 = vec[r]; + let c1 = (2 * a1.0 - a2.0, 2 * a1.1 - a2.1); + let c2 = (2 * a2.0 - a1.0, 2 * a2.1 - a1.1); + if c1.0 >= 0 && c1.0 < input.0 .0 && c1.1 >= 0 && c1.1 < input.0 .1 { + set.insert(c1); + } + if c2.0 >= 0 && c2.0 < input.0 .0 && c2.1 >= 0 && c2.1 < input.0 .1 { + set.insert(c2); + } + } + } + }); + set.len() +} + +#[aoc(day8, part2)] +fn part2(input: &Input) -> usize { + let mut set = HashSet::new(); + input.1.iter().for_each(|vec| { + for l in 0..vec.len() { + for r in l + 1..vec.len() { + let a1 = vec[l]; + let a2 = vec[r]; + let s = a1; + let v = (a2.0 - a1.0, a2.1 - a1.1); + let v = (v.0 / gcd(v.0, v.1), v.1 / gcd(v.0, v.1)); + let mut d = 0; + loop { + let c = (s.0 + d * v.0, s.1 + d * v.1); + d += 1; + if c.0 >= 0 && c.0 < input.0 .0 && c.1 >= 0 && c.1 < input.0 .1 { + set.insert(c); + } else { + break; + } + } + let mut d = 0; + loop { + let c = (s.0 + d * v.0, s.1 + d * v.1); + d -= 1; + if c.0 >= 0 && c.0 < input.0 .0 && c.1 >= 0 && c.1 < input.0 .1 { + set.insert(c); + } else { + break; + } + } + } + } + }); + // for y in 0..input.0 .1 { + // println!(); + // for x in 0..input.0 .0 { + // print!("{}", if set.contains(&(x, y)) { '#' } else { '.' }) + // } + // } + set.len() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn part1_example() { + assert_eq!( + part1(&parse( + "............\n........0...\n.....0......\n.......0....\n....0.......\n......A.....\n............\n............\n........A...\n.........A..\n............\n............" + )), + 14 + ); + } + + #[test] + fn part2_example() { + assert_eq!( + part2(&parse( + "............\n........0...\n.....0......\n.......0....\n....0.......\n......A.....\n............\n............\n........A...\n.........A..\n............\n............" + )), + 34 + ); + } +} diff --git a/aoc_2024/src/lib.rs b/aoc_2024/src/lib.rs index 06ec462..38d6a05 100644 --- a/aoc_2024/src/lib.rs +++ b/aoc_2024/src/lib.rs @@ -1,3 +1,4 @@ +mod day8; mod day1; mod day2; mod day3;