Day 7
This commit is contained in:
parent
36008a5622
commit
47c7362687
2 changed files with 128 additions and 0 deletions
120
src/bin/day7.rs
Normal file
120
src/bin/day7.rs
Normal file
|
|
@ -0,0 +1,120 @@
|
||||||
|
use std::time::Instant;
|
||||||
|
|
||||||
|
use aoc_2025::{Grid, load, print_res};
|
||||||
|
use bstr::{BString, ByteSlice};
|
||||||
|
use color_eyre::eyre::ContextCompat;
|
||||||
|
|
||||||
|
#[derive(PartialEq, Eq, Debug)]
|
||||||
|
pub enum ManifoldEntry {
|
||||||
|
Start,
|
||||||
|
Empty,
|
||||||
|
Splitter,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Display for ManifoldEntry {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
ManifoldEntry::Start => write!(f, "S"),
|
||||||
|
ManifoldEntry::Empty => write!(f, "."),
|
||||||
|
ManifoldEntry::Splitter => write!(f, "^"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Parsed = Grid<ManifoldEntry>;
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
|
pub fn parsing(input: &BString) -> color_eyre::Result<Parsed> {
|
||||||
|
let line_len = input.find(b"\n").with_context(|| "No newline found")?;
|
||||||
|
|
||||||
|
Ok(Grid::new(
|
||||||
|
input
|
||||||
|
.iter()
|
||||||
|
.filter(|&&v| v != b'\n')
|
||||||
|
.map(|&v| match v {
|
||||||
|
b'S' => Ok(ManifoldEntry::Start),
|
||||||
|
b'.' => Ok(ManifoldEntry::Empty),
|
||||||
|
b'^' => Ok(ManifoldEntry::Splitter),
|
||||||
|
_ => color_eyre::eyre::bail!("Invalid splitter entry: {}", v as char),
|
||||||
|
})
|
||||||
|
.collect::<Result<_, _>>()?,
|
||||||
|
line_len,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn manifold_traversal(manifold: &Grid<ManifoldEntry>) -> (u64, u64) {
|
||||||
|
let mut lines = manifold.lines();
|
||||||
|
let start_line = lines.next().unwrap();
|
||||||
|
let start = start_line
|
||||||
|
.iter()
|
||||||
|
.position(|v| *v == ManifoldEntry::Start)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut split_count = 0;
|
||||||
|
|
||||||
|
let mut beams = vec![0; start_line.len()];
|
||||||
|
beams[start] = 1;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let Some(line) = lines.next() else {
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
assert!(line.iter().all(|v| *v == ManifoldEntry::Empty));
|
||||||
|
|
||||||
|
let Some(line) = lines.next() else {
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut new_beams = vec![0; start_line.len()];
|
||||||
|
|
||||||
|
for (beam, count) in beams.iter().enumerate().filter(|&(_, &v)| v != 0) {
|
||||||
|
match &line[beam] {
|
||||||
|
ManifoldEntry::Start => panic!("Multiple starts"),
|
||||||
|
ManifoldEntry::Empty => new_beams[beam] += count,
|
||||||
|
ManifoldEntry::Splitter => {
|
||||||
|
split_count += 1;
|
||||||
|
new_beams[beam - 1] += count;
|
||||||
|
new_beams[beam + 1] += count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
beams = new_beams;
|
||||||
|
}
|
||||||
|
|
||||||
|
(split_count, beams.iter().sum())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
|
pub fn part1(input: Parsed) {
|
||||||
|
let (split_count, _) = manifold_traversal(&input);
|
||||||
|
print_res!("Split count: {split_count}");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(never)]
|
||||||
|
pub fn part2(input: Parsed) {
|
||||||
|
let (_, path_count) = manifold_traversal(&input);
|
||||||
|
print_res!("Path count: {path_count}");
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main() -> color_eyre::Result<()> {
|
||||||
|
let context = load()?;
|
||||||
|
|
||||||
|
let start = Instant::now();
|
||||||
|
let parsed = parsing(&context.input)?;
|
||||||
|
let elapsed = humantime::format_duration(start.elapsed());
|
||||||
|
|
||||||
|
let start = Instant::now();
|
||||||
|
if context.part == 1 {
|
||||||
|
part1(parsed);
|
||||||
|
} else {
|
||||||
|
part2(parsed);
|
||||||
|
}
|
||||||
|
let elapsed_part = humantime::format_duration(start.elapsed());
|
||||||
|
|
||||||
|
println!(" Parsing: {elapsed}");
|
||||||
|
println!(" Solving: {elapsed_part}");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
@ -41,6 +41,14 @@ impl<T> Grid<T> {
|
||||||
|
|
||||||
(0..line_len).flat_map(move |l| (0..col_len).map(move |c| (l, c)))
|
(0..line_len).flat_map(move |l| (0..col_len).map(move |c| (l, c)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn line(&self, index: usize) -> &[T] {
|
||||||
|
&self.values[index * self.line_len..(index + 1) * self.line_len]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn lines(&self) -> impl Iterator<Item = &[T]> {
|
||||||
|
(0..self.col_len).map(|i| self.line(i))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: PartialEq + Eq> Grid<T> {
|
impl<T: PartialEq + Eq> Grid<T> {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue