Day 22
This commit is contained in:
73
src/bin/day22.rs
Normal file
73
src/bin/day22.rs
Normal 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(())
|
||||
}
|
||||
Reference in New Issue
Block a user