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