1
0
Fork 0

day(22): add solution

Signed-off-by: Matej Focko <me@mfocko.xyz>
This commit is contained in:
Matej Focko 2024-07-07 16:19:10 +02:00
parent 5fd223dfb3
commit b2b2230473
Signed by: mfocko
SSH key fingerprint: SHA256:5YXD7WbPuK60gxnG6DjAwJiS9+swoWj33/HFu8g8JVo
2 changed files with 116 additions and 0 deletions

7
samples/day22.txt Normal file
View file

@ -0,0 +1,7 @@
1,0,1~1,2,1
0,0,2~2,0,2
0,2,3~2,2,3
0,0,4~0,2,4
2,0,5~2,2,5
0,1,6~2,1,6
1,1,8~1,1,9

109
src/bin/day22.rs Normal file
View file

@ -0,0 +1,109 @@
use std::collections::HashMap;
use aoc_2023::*;
type Output1 = usize;
type Output2 = Output1;
type Coord2D = Vector2D<i32>;
type Coord = Vector3D<i32>;
#[derive(Debug, Clone, Copy)]
struct Brick {
min: Coord,
max: Coord,
}
impl Brick {
fn new(min: Coord, max: Coord) -> Self {
Self { min, max }
}
}
struct Day22 {
bricks: Vec<Brick>,
falls: Vec<usize>,
}
impl Day22 {
fn fall(bricks: &mut [Brick]) -> usize {
let mut top = HashMap::<Coord2D, i32>::new();
let mut count = 0;
for b in bricks {
let mut fall = b.min.z();
for x in b.min.x()..=b.max.x() {
for y in b.min.y()..=b.max.y() {
fall = fall.min(b.min.z() - top.get(&Coord2D::new(x, y)).unwrap_or(&0) - 1);
}
}
if fall > 0 {
count += 1;
}
b.min -= Coord::new(0, 0, fall);
b.max -= Coord::new(0, 0, fall);
for x in b.min.x()..=b.max.x() {
for y in b.min.y()..=b.max.y() {
top.insert(Coord2D::new(x, y), b.max.z());
}
}
}
count
}
fn compute(&mut self) {
if !self.falls.is_empty() {
// already been computed
return;
}
// sort them for the solving
self.bricks.sort_by_key(|b| b.min.z());
Self::fall(&mut self.bricks);
self.falls = (0..self.bricks.len())
.map(|i| Self::fall(&mut [&self.bricks[0..i], &self.bricks[i + 1..]].concat()))
.collect_vec();
}
}
impl Solution<Output1, Output2> for Day22 {
fn new<P: AsRef<Path>>(pathname: P) -> Self {
let lines: Vec<String> = file_to_lines(pathname);
let mut bricks = vec![];
for (x0, y0, z0, x1, y1, z1) in lines.iter().map(|l| {
l.split(&[',', '~'])
.map(|c| c.parse::<i32>().unwrap())
.collect_tuple()
.unwrap()
}) {
bricks.push(Brick::new(Coord::new(x0, y0, z0), Coord::new(x1, y1, z1)));
}
Self {
bricks,
falls: vec![],
}
}
fn part_1(&mut self) -> Output1 {
self.compute();
self.falls.iter().filter(|b| **b == 0).count()
}
fn part_2(&mut self) -> Output2 {
self.compute();
self.falls.iter().sum::<usize>()
}
}
fn main() -> Result<()> {
Day22::main()
}
test_sample!(day_22, Day22, 5, 7);