This commit is contained in:
2024-12-08 19:05:08 +01:00
parent 6ebb9f8307
commit b86bcdda47
4 changed files with 140 additions and 0 deletions

2
2024/day8/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
target
input.txt

16
2024/day8/Cargo.lock generated Normal file
View File

@@ -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"

7
2024/day8/Cargo.toml Normal file
View File

@@ -0,0 +1,7 @@
[package]
name = "day8"
version = "0.1.0"
edition = "2021"
[dependencies]
gcd = "2.3.0"

115
2024/day8/src/main.rs Normal file
View File

@@ -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<char, Vec<Point>> = 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<char, Vec<Point>>) -> 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<char, Vec<Point>>) -> 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
}