This commit is contained in:
Christian
2023-12-22 16:22:55 +01:00
parent 9594c29467
commit 7df1136f3b
2 changed files with 1561 additions and 0 deletions

1488
data/22.in Normal file

File diff suppressed because it is too large Load Diff

73
src/bin/day22.rs Normal file
View File

@@ -0,0 +1,73 @@
use itertools::{iproduct, Itertools};
use std::collections::{HashMap, HashSet};
use anyhow::{Context, Result};
const MALFORMED: &str = "malformed input";
fn main() -> Result<()> {
let filename = std::env::args()
.nth(1)
.context("./day22 <path to puzzle input>")?;
let input = std::fs::read_to_string(filename)?;
let mut blocks = Vec::new();
for line in input.lines() {
let (a, b) = line.split_once(['~']).context(MALFORMED)?;
let mut ai = a.split(',').map(|s| s.parse::<usize>().unwrap());
let mut bi = b.split(',').map(|s| s.parse::<usize>().unwrap());
let (xa, ya, za) = ai.next_tuple().context(MALFORMED)?;
let (xb, yb, zb) = bi.next_tuple().context(MALFORMED)?;
blocks.push([(za, zb), (xa, xb), (ya, yb)]);
}
blocks.sort();
let mut slice = vec![vec![(0, 0); 10]; 10];
let mut bearing = HashSet::new();
let mut support = HashMap::new();
for ([z, x, y], id) in blocks.iter_mut().zip(1..) {
let z_max = iproduct!(x.0..=x.1, y.0..=y.1)
.map(|(x, y)| slice[x][y].1)
.reduce(std::cmp::max)
.unwrap();
let supports = iproduct!(x.0..=x.1, y.0..=y.1)
.filter(|(x, y)| slice[*x][*y].1 == z_max)
.map(|(x, y)| slice[x][y].0)
.collect::<HashSet<_>>();
if supports.len() == 1 {
bearing.insert(*supports.iter().next().unwrap());
}
support.insert(id, supports);
for (x, y) in iproduct!(x.0..=x.1, y.0..=y.1) {
slice[x][y].0 = id;
slice[x][y].1 = z_max + z.1 - z.0 + 1;
}
}
let part1 = blocks.len() - bearing.len() + 1;
let mut bearers = HashMap::from([(0, HashSet::new())]);
for id in 1..=blocks.len() {
let mut b = support[&id]
.iter()
.map(|id| bearers.get(id).unwrap())
.cloned()
.reduce(|a, b| &a & &b)
.unwrap_or_else(|| HashSet::new());
b.insert(id);
bearers.insert(id, b);
}
let part2 = bearers.values().map(|v| v.len()).sum::<usize>() - blocks.len();
println!("1) {}", part1);
println!("2) {}", part2);
Ok(())
}