adventofcode/days/2024/08.rs

120 Zeilen
3,5 KiB
Rust

2024-12-14 11:48:20 +01:00
use std::collections::HashMap;
use advent_of_code::{
strings::{convert_to_array, line_to_char},
Kartesian, Table,
};
use advent_of_code_macros::include_aoc;
2024-12-14 11:48:20 +01:00
use log::*;
include_aoc!(2024, 08);
2024-12-14 11:48:20 +01:00
const EMPTY: char = '.';
fn get_map(maximum: Kartesian<usize>) -> Vec<Vec<char>> {
let mut resomap = Vec::new();
let mut m = Vec::new();
m.resize(maximum.y, EMPTY);
resomap.resize(maximum.x, m);
resomap
}
fn find_antennas(map: Table) -> HashMap<char, Vec<Kartesian<usize>>> {
let mut positions = HashMap::new();
let mut x = 0;
let mut y;
let len = map[0].len();
for line in map.clone() {
y = 0;
for char in line {
if char != EMPTY {
if !positions.contains_key(&char) {
positions.insert(char, Vec::with_capacity(len));
}
positions.get_mut(&char).unwrap().push(Kartesian::new(x, y));
}
y += 1;
}
x += 1;
}
positions
}
fn get_resonance(points: Vec<Kartesian<usize>>, maximum: Kartesian<usize>, harmonic: bool) -> Vec<Kartesian<usize>> {
let mut resonances = Vec::new();
let mut diff;
let mut direction;
for outer in points.clone() {
for inner in points.clone() {
if outer == inner {
continue;
}
(diff, direction) = inner.diff(outer);
loop {
if let Some(reso) = outer.move_dir(diff, direction) {
if reso.x < maximum.x && reso.y < maximum.y {
debug!("Found Point: {}", reso);
resonances.push(reso);
if !harmonic {
break;
}
} else {
break;
}
} else {
break;
}
}
}
}
resonances
}
fn main() {
let map = convert_to_array::<_, _, '\n'>(DATA, line_to_char);
let maximum = Kartesian::new(map.len(), map[0].len());
let positions = find_antennas(map.clone());
let mut tmp;
let mut resonating_points = Vec::new();
for (group, points) in positions.clone() {
tmp = get_resonance(points.clone(), maximum, false);
println!("Found {} resonances for {} antennas in group {}", tmp.len(), points.len(), group,);
resonating_points.append(&mut tmp);
}
println!("Found {} points before dedup", resonating_points.len());
resonating_points.dedup();
println!("{} after simple dedup", resonating_points.len());
resonating_points = resonating_points
.iter()
.filter(|x| {
for (group, positions) in positions.clone() {
if positions.contains(*x) {
println!("Discarded point {} because it is over an point of group {}", *x, group);
return false;
}
}
true
})
.cloned()
.collect();
let mut resomap = map.clone();
println!("There are {} Resonating points on the map after dedup.", resonating_points.len());
if resonating_points.len() != 305 {
println!("Wrong solution");
}
for point in resonating_points {
resomap[point.x][point.y] = '~';
}
for line in 0..resomap.len() {
print!("{:02}. ", line + 1);
for char in map[line].clone() {
print!("{}", char);
}
print!("|");
for char in resomap[line].clone() {
print!("{}", char);
}
println!();
}
}