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)))
|
||||
}
|
||||
|
||||
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> {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue