day(22): add solution
Signed-off-by: Matej Focko <me@mfocko.xyz>
This commit is contained in:
parent
5fd223dfb3
commit
b2b2230473
2 changed files with 116 additions and 0 deletions
7
samples/day22.txt
Normal file
7
samples/day22.txt
Normal 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
109
src/bin/day22.rs
Normal 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);
|
Loading…
Reference in a new issue