Day 15, puzzle 1

This commit is contained in:
jazzpi 2022-12-16 10:47:17 +01:00
parent d05780e64a
commit 619c77aab7
4 changed files with 126 additions and 0 deletions

39
src/bin/d15p1.rs Normal file
View File

@ -0,0 +1,39 @@
use aoc22::{day15, util};
use itertools::Itertools;
const ROW: isize = 2000000;
pub fn main() {
let sensors = day15::parse_sensors(&util::parse_input());
let covered = sensors
.iter()
.map(|s| s.covered(ROW))
.filter(|r| !r.is_empty())
.sorted_by_key(|r| *r.start());
let mut max_x = isize::MIN;
let mut total_covered = 0;
for range in covered {
let (min, max) = range.into_inner();
if min > max_x {
total_covered += max - min + 1;
} else if max > max_x {
total_covered += max - max_x;
}
max_x = max_x.max(max);
}
let n_beacons = sensors
.iter()
.map(|s| s.loc_b)
.filter(|b| b.0 == ROW)
.unique()
.count() as isize;
println!(
"Impossible positions in row {}: {}",
ROW,
total_covered - n_beacons
);
}

50
src/day15.rs Normal file
View File

@ -0,0 +1,50 @@
use std::ops::RangeInclusive;
use regex::Regex;
use crate::util::{Coordinate, SignedCoord};
#[derive(Debug)]
pub struct Sensor {
pub loc_s: SignedCoord,
pub loc_b: SignedCoord,
pub range: usize,
}
impl Sensor {
pub fn covered(&self, y: isize) -> RangeInclusive<isize> {
let dy = self.loc_s.0.abs_diff(y);
if dy > self.range {
1..=0
} else {
let range_x = (self.range - dy) as isize;
(self.loc_s.1 - range_x)..=(self.loc_s.1 + range_x)
}
}
}
pub fn parse_sensors(input: &String) -> Vec<Sensor> {
let mut result = Vec::new();
let re =
Regex::new(r"^Sensor at x=(-?\d+), y=(-?\d+): closest beacon is at x=(-?\d+), y=(-?\d+)$")
.unwrap();
for line in input.lines() {
let captures = re.captures(line).unwrap();
let loc_s: SignedCoord = (
captures.get(2).unwrap().as_str().parse().unwrap(),
captures.get(1).unwrap().as_str().parse().unwrap(),
);
let loc_b: SignedCoord = (
captures.get(4).unwrap().as_str().parse().unwrap(),
captures.get(3).unwrap().as_str().parse().unwrap(),
);
result.push(Sensor {
loc_s,
loc_b,
range: loc_s.manhattan(&loc_b),
});
}
result
}

View File

@ -4,6 +4,7 @@ pub mod day11;
pub mod day12; pub mod day12;
pub mod day13; pub mod day13;
pub mod day14; pub mod day14;
pub mod day15;
pub mod day2; pub mod day2;
pub mod day3; pub mod day3;
pub mod day4; pub mod day4;

View File

@ -37,3 +37,39 @@ pub fn max_n<T: Ord + Copy>(slice: &[T], n: usize) -> Result<Vec<T>, ()> {
} }
pub type Coord = (usize, usize); pub type Coord = (usize, usize);
pub trait Coordinate {
fn manhattan(&self, other: &Self) -> usize;
fn to_signed(&self) -> SignedCoord;
fn to_unsigned(&self) -> Coord;
}
impl Coordinate for Coord {
fn manhattan(&self, other: &Self) -> usize {
return self.0.abs_diff(other.0) + self.1.abs_diff(other.1);
}
fn to_signed(&self) -> SignedCoord {
(self.0 as isize, self.1 as isize)
}
fn to_unsigned(&self) -> Coord {
*self
}
}
pub type SignedCoord = (isize, isize);
impl Coordinate for SignedCoord {
fn manhattan(&self, other: &Self) -> usize {
return self.0.abs_diff(other.0) + self.1.abs_diff(other.1);
}
fn to_signed(&self) -> SignedCoord {
*self
}
fn to_unsigned(&self) -> Coord {
(self.0 as usize, self.1 as usize)
}
}