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,
|
|
|
|
};
|
2024-12-19 17:12:39 +01:00
|
|
|
use advent_of_code_macros::include_aoc;
|
2024-12-14 11:48:20 +01:00
|
|
|
use log::*;
|
|
|
|
|
2024-12-19 17:12:39 +01:00
|
|
|
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!();
|
|
|
|
}
|
|
|
|
}
|