day8, part2

This commit is contained in:
Joe Ardent 2025-01-02 16:43:36 -08:00
parent 49fcba6c4a
commit 75706b14e3

View file

@ -26,7 +26,7 @@ fn pt1(input: &str) -> usize {
if a1 == a2 {
continue;
}
for antinode in board.antinodes(*a1, *a2) {
for antinode in board.antinodes(*a1, *a2, false) {
antinodes.insert(antinode);
}
}
@ -40,9 +40,35 @@ fn pt1(input: &str) -> usize {
}
fn pt2(input: &str) -> usize {
let mut total = 0;
let mut board = Board::new(input);
let mut antinodes = HashSet::new();
total
for f in board.freqs() {
for a1 in board.antennae[&f].iter() {
for a2 in board.antennae[&f].iter() {
if a1 == a2 {
continue;
}
let nodes = board.antinodes(*a1, *a2, true);
antinodes.extend(nodes.into_iter());
}
}
}
for &antinode in antinodes.iter() {
board.set(antinode, Cell::Antinode);
}
println!("{board}");
antinodes.len()
}
fn gcd(mut a: usize, mut b: usize) -> usize {
let mut t = 0;
while b != 0 {
t = b;
b = a % b;
a = t;
}
a
}
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
@ -124,31 +150,61 @@ impl Board {
false
}
fn antinodes(&self, a1: Loc, a2: Loc) -> Vec<Loc> {
let dy = (a1.0 as i64 - a2.0 as i64).unsigned_abs() as usize;
let dx = (a1.1 as i64 - a2.1 as i64).unsigned_abs() as usize;
fn antinodes(&self, a1: Loc, a2: Loc, pt2: bool) -> HashSet<Loc> {
let mut dy = (a1.0 as i64 - a2.0 as i64).unsigned_abs() as usize;
let mut dx = (a1.1 as i64 - a2.1 as i64).unsigned_abs() as usize;
// row 0 is at the top
let (top, bottom) = if a1.0 <= a2.0 { (a1, a2) } else { (a2, a1) };
let (left, right) = if a1.1 <= a2.1 { (a1, a2) } else { (a2, a1) };
let mut antinodes = Vec::new();
let mut antinodes = HashSet::new();
let ny_top = top.0.wrapping_sub(dy);
let ny_bot = bottom.0 + dy;
let nx_left = left.1.wrapping_sub(dx);
let nx_right = right.1 + dx;
let slopes_up = top == right;
let (n1, n2) = match (a1, a2) {
_ if top == left => (Loc(ny_top, nx_left), Loc(ny_bot, nx_right)),
_ if top == right => (Loc(ny_top, nx_right), Loc(ny_bot, nx_left)),
_ if bottom == left => (Loc(ny_bot, nx_left), Loc(ny_top, nx_right)),
_ => (Loc(ny_bot, nx_right), Loc(ny_top, nx_left)),
if pt2 {
let g = gcd(dy, dx);
dy /= g;
dx /= g;
// start at the left and move right
let mut loc = left;
while loc.0 < self.bottom && loc.1 < self.right {
antinodes.insert(loc);
loc.1 += dx;
if slopes_up {
loc.0 = loc.0.wrapping_sub(dy);
} else {
loc.0 += dy;
}
}
// now start at the right and move left
let mut loc = right;
while loc.0 < self.bottom && loc.1 < self.right {
antinodes.insert(loc);
loc.1 = loc.1.wrapping_sub(dx);
if slopes_up {
loc.0 += dy;
} else {
loc.0 = loc.0.wrapping_sub(dy);
}
}
} else {
let (n1, n2) = if slopes_up {
(Loc(ny_bot, nx_left), Loc(ny_top, nx_right))
} else {
(Loc(ny_top, nx_left), Loc(ny_bot, nx_right))
};
if n1.0 < self.bottom && n1.1 < self.right {
antinodes.push(n1);
antinodes.insert(n1);
}
if n2.0 < self.bottom && n2.1 < self.right {
antinodes.push(n2);
antinodes.insert(n2);
}
}
antinodes
@ -203,4 +259,13 @@ mod test {
fn p2() {
assert_eq!(34, pt2(INPUT));
}
#[test]
fn g() {
let a = gcd(12, 30);
assert_eq!(a, 6);
let b = gcd(51, 17);
assert_eq!(b, 17);
}
}