day8, part2
This commit is contained in:
parent
49fcba6c4a
commit
75706b14e3
1 changed files with 83 additions and 18 deletions
|
@ -26,7 +26,7 @@ fn pt1(input: &str) -> usize {
|
||||||
if a1 == a2 {
|
if a1 == a2 {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for antinode in board.antinodes(*a1, *a2) {
|
for antinode in board.antinodes(*a1, *a2, false) {
|
||||||
antinodes.insert(antinode);
|
antinodes.insert(antinode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,9 +40,35 @@ fn pt1(input: &str) -> usize {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pt2(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)]
|
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
|
||||||
|
@ -124,31 +150,61 @@ impl Board {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
fn antinodes(&self, a1: Loc, a2: Loc) -> Vec<Loc> {
|
fn antinodes(&self, a1: Loc, a2: Loc, pt2: bool) -> HashSet<Loc> {
|
||||||
let dy = (a1.0 as i64 - a2.0 as i64).unsigned_abs() as usize;
|
let mut 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;
|
let mut dx = (a1.1 as i64 - a2.1 as i64).unsigned_abs() as usize;
|
||||||
|
|
||||||
// row 0 is at the top
|
// row 0 is at the top
|
||||||
let (top, bottom) = if a1.0 <= a2.0 { (a1, a2) } else { (a2, a1) };
|
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 (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_top = top.0.wrapping_sub(dy);
|
||||||
let ny_bot = bottom.0 + dy;
|
let ny_bot = bottom.0 + dy;
|
||||||
let nx_left = left.1.wrapping_sub(dx);
|
let nx_left = left.1.wrapping_sub(dx);
|
||||||
let nx_right = right.1 + dx;
|
let nx_right = right.1 + dx;
|
||||||
|
let slopes_up = top == right;
|
||||||
|
|
||||||
let (n1, n2) = match (a1, a2) {
|
if pt2 {
|
||||||
_ if top == left => (Loc(ny_top, nx_left), Loc(ny_bot, nx_right)),
|
let g = gcd(dy, dx);
|
||||||
_ if top == right => (Loc(ny_top, nx_right), Loc(ny_bot, nx_left)),
|
dy /= g;
|
||||||
_ if bottom == left => (Loc(ny_bot, nx_left), Loc(ny_top, nx_right)),
|
dx /= g;
|
||||||
_ => (Loc(ny_bot, nx_right), Loc(ny_top, nx_left)),
|
|
||||||
};
|
|
||||||
|
|
||||||
if n1.0 < self.bottom && n1.1 < self.right {
|
// start at the left and move right
|
||||||
antinodes.push(n1);
|
let mut loc = left;
|
||||||
}
|
while loc.0 < self.bottom && loc.1 < self.right {
|
||||||
if n2.0 < self.bottom && n2.1 < self.right {
|
antinodes.insert(loc);
|
||||||
antinodes.push(n2);
|
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.insert(n1);
|
||||||
|
}
|
||||||
|
if n2.0 < self.bottom && n2.1 < self.right {
|
||||||
|
antinodes.insert(n2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
antinodes
|
antinodes
|
||||||
|
@ -203,4 +259,13 @@ mod test {
|
||||||
fn p2() {
|
fn p2() {
|
||||||
assert_eq!(34, pt2(INPUT));
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue