use itertools::Itertools; use std::collections::HashMap; const EXTEND: bool = true; pub fn day8() { let (antennae, width, height) = input(); let mut antinodes: Vec<(i64, i64)> = antennae .values() .flat_map(|antennae_set| { antennae_set .iter() .combinations(2) .flat_map(|pair| { let ((x1, y1), (x2, y2)) = (pair[0], pair[1]); let (dx, dy) = (x2 - x1, y2 - y1); if EXTEND { (0..width.max(height)) .flat_map(|i| [(x1 - dx * i, y1 - dy * i), (x1 + dx * i, y1 + dy * i)]) .collect() } else { vec![(x1 - dx, y1 - dy), (x2 + dx, y2 + dy)] } }) .collect::>() }) .filter(|(x, y)| *x < width && *y < height && *x >= 0 && *y >= 0) .collect(); antinodes.sort(); antinodes.dedup(); println!("Unique Antinodes: {}", antinodes.len()); } fn input() -> (HashMap>, i64, i64) { let input = crate::input(8); let unsorted_antennae = input.lines().enumerate().flat_map(|(y, line)| { line.chars() .enumerate() .filter(|(_, c)| *c != '.') .map(move |(x, c)| (c, (x as i64, y as i64))) }); let mut antennae = HashMap::>::new(); for (c, p) in unsorted_antennae { antennae.entry(c).or_default().push(p); } ( antennae, input.lines().nth(0).unwrap().len() as i64, input.lines().count() as i64, ) }