use std::collections::{HashMap, HashSet}; static DAY: u8 = 8; fn main() { let input = advent::read_lines(DAY); println!("{DAY}a: {}", Map::new(&input).count_antinodes()); println!("{DAY}b: {}", 0); } #[derive(Eq, PartialEq, Hash)] struct Position { x: isize, y: isize, } impl Position { fn add_position(&self, other: &Position) -> Position { Position { x: self.x + (self.x - other.x), y: self.y + (self.y - other.y) } } } struct Map { antennas: HashMap, dimensions: Position, } impl Map { fn new(input: &[String]) -> Map { let mut antennas = HashMap::new(); for (y, line) in input.iter().enumerate() { for (x, c) in line.chars().enumerate() { if c != '.' { let pos = Position { x: x as isize, y: y as isize }; antennas.insert(pos, c); } } } let dimensions = Position { x: input[0].len() as isize, y: input.len() as isize }; Map { antennas, dimensions } } fn inside_map(&self, pos: &Position) -> bool { pos.x >= 0 && pos.y >= 0 && pos.x < self.dimensions.x && pos.y < self.dimensions.y } fn count_antinodes(&self) -> usize { let mut antinodes = HashSet::new(); for (pos1, antenna) in &self.antennas { for (pos2, _) in self.antennas.iter().filter(|&(_, a)| a == antenna).filter(|&(p, _)| p != pos1) { let antinode_pos = pos1.add_position(pos2); if self.inside_map(&antinode_pos) { antinodes.insert(antinode_pos); } } } antinodes.len() } } #[cfg(test)] mod tests { use super::*; #[test] fn test() { let input = [ "............", "........0...", ".....0......", ".......0....", "....0.......", "......A.....", "............", "............", "........A...", ".........A..", "............", "............", ].iter().map(|&x| String::from(x)).collect::>(); assert_eq!(Map::new(&input).count_antinodes(), 14); } }