From b86bcdda47db4a41cbc123c57c3d19189a5444cc Mon Sep 17 00:00:00 2001 From: structix Date: Sun, 8 Dec 2024 19:05:08 +0100 Subject: [PATCH] Add day8 --- 2024/day8/.gitignore | 2 + 2024/day8/Cargo.lock | 16 ++++++ 2024/day8/Cargo.toml | 7 +++ 2024/day8/src/main.rs | 115 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 140 insertions(+) create mode 100644 2024/day8/.gitignore create mode 100644 2024/day8/Cargo.lock create mode 100644 2024/day8/Cargo.toml create mode 100644 2024/day8/src/main.rs diff --git a/2024/day8/.gitignore b/2024/day8/.gitignore new file mode 100644 index 0000000..2ac37a0 --- /dev/null +++ b/2024/day8/.gitignore @@ -0,0 +1,2 @@ +target +input.txt diff --git a/2024/day8/Cargo.lock b/2024/day8/Cargo.lock new file mode 100644 index 0000000..cd54943 --- /dev/null +++ b/2024/day8/Cargo.lock @@ -0,0 +1,16 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "day8" +version = "0.1.0" +dependencies = [ + "gcd", +] + +[[package]] +name = "gcd" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d758ba1b47b00caf47f24925c0074ecb20d6dfcffe7f6d53395c0465674841a" diff --git a/2024/day8/Cargo.toml b/2024/day8/Cargo.toml new file mode 100644 index 0000000..2a3c188 --- /dev/null +++ b/2024/day8/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "day8" +version = "0.1.0" +edition = "2021" + +[dependencies] +gcd = "2.3.0" diff --git a/2024/day8/src/main.rs b/2024/day8/src/main.rs new file mode 100644 index 0000000..5e494e0 --- /dev/null +++ b/2024/day8/src/main.rs @@ -0,0 +1,115 @@ +use std::{ + collections::{HashMap, HashSet}, + fs, + time::Instant, +}; + +use gcd::Gcd; + +fn main() { + let file = fs::read_to_string("./input.txt").unwrap(); + + let mut map = Vec::new(); + let mut antenna_locations: HashMap> = HashMap::new(); + + for (r_idx, line) in file.lines().enumerate() { + map.push(line.as_bytes()); + + for (c_idx, ch) in line.chars().enumerate() { + if ch != '.' { + antenna_locations + .entry(ch) + .or_default() + .push(Point::new(r_idx as i32, c_idx as i32)); + } + } + } + + let start = Instant::now(); + println!("Solution 1: {}", puzzle1(&map, &antenna_locations)); + let end = Instant::now() - start; + println!("Solution 1 time: {}", end.as_micros()); + + let start = Instant::now(); + println!("Solution 2: {}", puzzle2(&map, &antenna_locations)); + let end = Instant::now() - start; + println!("Solution 2 time: {}", end.as_micros()); +} + +#[derive(Debug, PartialEq, Eq, Hash, Clone, Copy)] +struct Point { + row: i32, + col: i32, +} + +impl Point { + fn new(row: i32, col: i32) -> Self { + Self { row, col } + } + + fn is_in_map(&self, map: &[&[u8]]) -> bool { + !(self.col >= map[0].len() as i32 + || self.row >= map.len() as i32 + || self.col < 0 + || self.row < 0) + } +} + +fn puzzle1(map: &[&[u8]], antenna_locations: &HashMap>) -> i32 { + let mut antinodes = HashSet::new(); + + for (_, loc) in antenna_locations.iter() { + for i in 0..loc.len() { + for j in (i + 1)..loc.len() { + let diff = Point::new(loc[i].row - loc[j].row, loc[i].col - loc[j].col); + let an1 = Point::new(loc[i].row + diff.row, loc[i].col + diff.col); + let an2 = Point::new(loc[j].row - diff.row, loc[j].col - diff.col); + + if an1.is_in_map(map) { + antinodes.insert(an1); + } + if an2.is_in_map(map) { + antinodes.insert(an2); + } + } + } + } + + antinodes.len() as i32 +} + +fn puzzle2(map: &[&[u8]], antenna_locations: &HashMap>) -> i32 { + let mut antinodes = HashSet::new(); + + for (_, loc) in antenna_locations.iter() { + for i in 0..loc.len() { + for j in (i + 1)..loc.len() { + let mut diff = Point::new(loc[i].row - loc[j].row, loc[i].col - loc[j].col); + let gcd = diff.row.unsigned_abs().gcd_binary(diff.col.unsigned_abs()) as i32; + diff.row /= gcd; + diff.col /= gcd; + + let mut add = true; + let mut n = 0; + + while add { + add = false; + let an1 = Point::new(loc[i].row + n * diff.row, loc[i].col + n * diff.col); + let an2 = Point::new(loc[j].row - n * diff.row, loc[j].col - n * diff.col); + + if an1.is_in_map(map) { + antinodes.insert(an1); + add = true; + } + if an2.is_in_map(map) { + antinodes.insert(an2); + add = true; + } + n += 1; + } + } + } + } + + antinodes.len() as i32 +}