#[path = "../lib.rs"] mod lib; fn parse_input() -> ([Vec<(usize, usize)>; 256], usize, usize) { let mut x = 0; let mut y = 0; let mut antennas = core::array::from_fn(|_| vec![]); for line in lib::iter_input() { x = 0; for b in line.bytes() { if b != b'.' { antennas[b as usize].push((x, y)); } x += 1; } y += 1; } return (antennas, x, y); } fn gcd(a: usize, b: usize) -> usize { let mut x = a.max(b); let mut y = a.min(b); while y > 0 { (x, y) = (y, x % y); } return x; } fn main() { let mut sum1 = 0; let mut sum2 = 0; let (antennas, w, h) = parse_input(); let mut points1 = vec![vec![false; w]; h]; let mut points2 = vec![vec![false; w]; h]; for set in antennas.iter() { for i in 0..set.len() { for j in 0..set.len() { if i != j { let (x1, y1) = set[i]; let (x2, y2) = set[j]; if 2 * x1 >= x2 && 2 * x1 < w + x2 && 2 * y1 >= y2 && 2 * y1 < h + y2 { // p3 = (1 - (-1)) * p1 + (-1) * p2 let x3 = 2 * x1 - x2; let y3 = 2 * y1 - y2; if !points1[y3][x3] { points1[y3][x3] = true; sum1 += 1; } } let d = gcd(x1.abs_diff(x2), y1.abs_diff(y2)); for t in 0.. { if (d + t) * x1 < t * x2 || (d + t) * y1 < t * y2 || (d + t) * x1 >= w * d + t * x2 || (d + t) * y1 >= h * d + t * y2 { break; } // p3 = (1 - (-t/d)) * p1 + (-t/d) * p2 let x3 = ((d + t) * x1 - t * x2) / d; let y3 = ((d + t) * y1 - t * y2) / d; if !points2[y3][x3] { points2[y3][x3] = true; sum2 += 1; } } } } } } println!("part1: {}", sum1); println!("part2: {}", sum2); }