1
0
Fork 0
advent-of-code/2022/src/days/day15.rs

84 lines
2.5 KiB
Rust

use anyhow::Result;
use std::fs;
use std::collections::HashSet;
#[derive(Debug)]
struct Pair {
sensor: Coord,
beacon: Coord,
}
#[derive(Debug, Eq, Hash, PartialEq)]
struct Coord {
x: i32,
y: i32,
}
impl Pair {
fn distance(self: &Self) -> i32 {
(self.sensor.x - self.beacon.x).abs() + (self.sensor.y - self.beacon.y).abs()
}
}
pub fn run() -> Result<()> {
#[cfg(not(feature = "test_input"))]
let file_contents = fs::read_to_string("day15.txt")?;
#[cfg(feature = "test_input")]
let file_contents = fs::read_to_string("tests/day15.txt")?;
let mut pairs: Vec<Pair> = Vec::with_capacity(25);
for line in file_contents.lines() {
let mut parts = line.split(": ");
let spart = parts.next().unwrap().strip_prefix("Sensor at ").unwrap();
let bpart = parts.next().unwrap().strip_prefix("closest beacon is at ").unwrap();
let mut scoords = spart.split(", ");
let sx = scoords.next().unwrap().strip_prefix("x=").unwrap().parse::<i32>().unwrap();
let sy = scoords.next().unwrap().strip_prefix("y=").unwrap().parse::<i32>().unwrap();
let mut bcoords = bpart.split(", ");
let bx = bcoords.next().unwrap().strip_prefix("x=").unwrap().parse::<i32>().unwrap();
let by = bcoords.next().unwrap().strip_prefix("y=").unwrap().parse::<i32>().unwrap();
pairs.push(Pair {
sensor: Coord { x: sx, y: sy },
beacon: Coord { x: bx, y: by },
});
}
#[cfg(not(feature = "test_input"))]
spots_taken_on_row(&pairs, 2000000);
#[cfg(feature = "test_input")]
spots_taken_on_row(&pairs, 10);
// println!("pairs {:?}", pairs);
Ok(())
}
fn spots_taken_on_row(pairs: &Vec<Pair>, row: i32) {
let mut c: HashSet<i32> = HashSet::new();
for p in pairs.iter() {
let d = p.distance();
if row > p.sensor.y && row - p.sensor.y > d {
continue;
} else if row < p.sensor.y && p.sensor.y - row > d {
continue;
}
let remaining_distance = d - (row - p.sensor.y).abs();
let minx = p.sensor.x - remaining_distance;
let maxx = p.sensor.x + remaining_distance;
// println!("{:?} distance {} from {}..={}", p.sensor, d, minx, maxx);
for x in minx..=maxx {
c.insert(x);
}
}
for p in pairs.iter() {
if p.beacon.y == row {
c.remove(&p.beacon.x);
}
}
println!("spots taken on row {} = {}", row, c.len());
}