2022 rust day 15 wip

This commit is contained in:
Maciej Jur 2022-12-15 13:21:02 +01:00
parent 25c441bbf4
commit 0a53a19147
3 changed files with 195 additions and 0 deletions

View file

@ -0,0 +1,137 @@
use std::collections::HashMap;
use regex::Regex;
use crate::utils;
use crate::utils::matrix::Matrix;
pub fn run() -> () {
let data = parse_data(&utils::read_lines(utils::Source::Day(-1)));
println!("Day 15");
println!("Part 1: {}", solve1(&data));
println!("Part 2: {}", solve2(&data));
}
type Data = [((usize, usize), (isize, isize))];
fn distance(a: (usize, usize), b: (isize, isize)) -> usize {
(a.0 as isize).abs_diff(b.0) + (a.1 as isize).abs_diff(b.1)
}
fn find_ranges(data: &Data) -> HashMap<(usize, usize), usize> {
data.iter()
.map(|&(sensor, beacon)|
(sensor, distance(sensor, beacon))
)
.collect()
}
fn find_bounds(data: &Data) -> (usize, usize) {
data.iter()
.fold((0, 0), |acc, &(sensor, beacon)| {
(
acc.0.max(sensor.0.max(beacon.0.max(0) as usize)),
acc.1.max(sensor.0.max(beacon.1.max(0) as usize)),
)
})
}
fn solve1(data: &Data) -> usize {
let ranges = find_ranges(data);
let (rows, cols) = find_bounds(data);
let max_range = *ranges.values().max().unwrap();
let buffer = 2 * max_range;
let mut grid = Matrix::with_bounds(
(0, 0),
(rows + buffer, cols + buffer),
'.'
);
let mut view = grid.view_translated((-(max_range as isize), -(max_range as isize)));
for index in view.cell_indices().collect::<Vec<_>>() {
for (&sensor, &max_dist) in ranges.iter() {
if distance(sensor, index) <= max_dist {
view[index] = '#';
}
}
}
grid.iter_rows().for_each(|row| {
let xd = row.iter().filter(|&&x| x == '#').count();
println!("{xd}");
});
println!("{grid}");
grid.slice_row(max_range + 10).iter().filter(|&&x| x == '#').count()
}
fn solve2(data: &Data) -> i32 {
2
}
fn parse_data<T: AsRef<str>>(data: &[T]) -> Vec<((usize, usize), (isize, isize))> {
let re = Regex::new(r#"x=(-?\d+), y=(-?\d+)"#).unwrap();
data.iter()
.map(|line| {
let mut iter = re.captures_iter(line.as_ref());
let sensor = iter.next()
.map(|c| {
let mut cap = c.iter();
let x = cap.nth(1).unwrap().unwrap().as_str().parse::<usize>().unwrap();
let y = cap.next().unwrap().unwrap().as_str().parse::<usize>().unwrap();
(y, x)
})
.unwrap();
let beacon = iter.next()
.map(|c| {
let mut cap = c.iter();
let x = cap.nth(1).unwrap().unwrap().as_str().parse::<isize>().unwrap();
let y = cap.next().unwrap().unwrap().as_str().parse::<isize>().unwrap();
(y, x)
})
.unwrap();
(sensor, beacon)
})
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
static DATA: &[&str] = &[
// "Sensor at x=2, y=18: closest beacon is at x=-2, y=15",
// "Sensor at x=9, y=16: closest beacon is at x=10, y=16",
// "Sensor at x=13, y=2: closest beacon is at x=15, y=3",
// "Sensor at x=12, y=14: closest beacon is at x=10, y=16",
// "Sensor at x=10, y=20: closest beacon is at x=10, y=16",
// "Sensor at x=14, y=17: closest beacon is at x=10, y=16",
"Sensor at x=8, y=7: closest beacon is at x=2, y=10",
// "Sensor at x=2, y=0: closest beacon is at x=2, y=10",
// "Sensor at x=0, y=11: closest beacon is at x=2, y=10",
// "Sensor at x=20, y=14: closest beacon is at x=25, y=17",
// "Sensor at x=17, y=20: closest beacon is at x=21, y=22",
// "Sensor at x=16, y=7: closest beacon is at x=15, y=3",
// "Sensor at x=14, y=3: closest beacon is at x=15, y=3",
// "Sensor at x=20, y=1: closest beacon is at x=15, y=3",
];
#[test]
fn part1() {
assert_eq!(26, solve1(&parse_data(DATA)));
}
#[test]
fn part2() {
let data = parse_data(DATA);
assert_eq!(2, solve2(&data));
}
}

View file

@ -12,3 +12,4 @@ pub mod day11;
pub mod day12; pub mod day12;
pub mod day13; pub mod day13;
pub mod day14; pub mod day14;
pub mod day15;

View file

@ -85,6 +85,12 @@ impl<T> Matrix<T> {
.flat_map(move |row| col_range.clone().into_iter().map(move |col| (row, col))) .flat_map(move |row| col_range.clone().into_iter().map(move |col| (row, col)))
} }
pub fn slice_row(&self, row: usize) -> &[T] {
let start = row * self.cols;
let end = start + self.cols;
&self.array[start..end]
}
#[inline(always)] #[inline(always)]
fn get_offset(&self, row: usize, col: usize) -> usize { fn get_offset(&self, row: usize, col: usize) -> usize {
(row - self.offset_r) * self.cols + (col - self.offset_c) (row - self.offset_r) * self.cols + (col - self.offset_c)
@ -155,3 +161,54 @@ impl<T> fmt::Display for Matrix<T> where T: fmt::Display {
} }
} }
pub struct TranslatedViewMut<'a, T> {
matrix: &'a mut Matrix<T>,
tl_row: isize,
tl_col: isize,
}
impl<T> Matrix<T> {
pub fn view_translated(&mut self, (rows, cols): (isize, isize)) -> TranslatedViewMut<'_, T> {
TranslatedViewMut { matrix: self, tl_row: rows, tl_col: cols }
}
}
impl<'a, T> TranslatedViewMut<'a, T> {
fn tl(&self, (row, col): (usize, usize)) -> (isize, isize) {
let row = row as isize + self.tl_row;
let col = col as isize + self.tl_col;
(row, col)
}
fn undo_tl(&self, (row, col): (isize, isize)) -> (usize, usize) {
let row = (row - self.tl_row) as usize;
let col = (col - self.tl_col) as usize;
(row, col)
}
pub fn cell_indices(&self) -> impl Iterator<Item = (isize, isize)> + '_ {
self.matrix.cell_indices().map(|index| self.tl(index))
}
pub fn slice_row(&self, row: isize) -> &[T] {
let row = row - self.tl_row;
self.slice_row(row)
}
}
impl<'a, T> Index<(isize, isize)> for TranslatedViewMut<'a, T> {
type Output = T;
fn index(&self, index: (isize, isize)) -> &Self::Output {
let index = self.undo_tl(index);
&self.matrix[index]
}
}
impl<'a, T> IndexMut<(isize, isize)> for TranslatedViewMut<'a, T> {
fn index_mut(&mut self, index: (isize, isize)) -> &mut Self::Output {
let index = self.undo_tl(index);
&mut self.matrix[index]
}
}