Day 4
This commit is contained in:
parent
6fd57bcc6d
commit
92a66b3d5f
1 changed files with 157 additions and 0 deletions
157
src/bin/day4.rs
Normal file
157
src/bin/day4.rs
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
use std::time::Instant;
|
||||
|
||||
use aoc_2025::{load, print_res};
|
||||
use bstr::{BString, ByteSlice};
|
||||
use color_eyre::eyre::ContextCompat;
|
||||
|
||||
type Parsed = Grid;
|
||||
|
||||
pub struct Grid {
|
||||
values: Vec<bool>,
|
||||
line_len: usize,
|
||||
col_len: usize,
|
||||
}
|
||||
|
||||
impl Grid {
|
||||
fn get(&self, line: isize, col: isize) -> Option<bool> {
|
||||
if line < 0 || col < 0 || line as usize >= self.line_len || col as usize >= self.col_len {
|
||||
None
|
||||
} else {
|
||||
Some(self[(line as usize, col as usize)])
|
||||
}
|
||||
}
|
||||
|
||||
fn neighbours(&self, line: usize, col: usize) -> usize {
|
||||
let mut sum = 0;
|
||||
for l in -1..=1 {
|
||||
for c in -1..=1 {
|
||||
if l == 0 && c == 0 {
|
||||
continue;
|
||||
}
|
||||
|
||||
if self
|
||||
.get(line as isize + l, col as isize + c)
|
||||
.unwrap_or(false)
|
||||
{
|
||||
sum += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
sum
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Index<(usize, usize)> for Grid {
|
||||
type Output = bool;
|
||||
|
||||
fn index(&self, (line, col): (usize, usize)) -> &Self::Output {
|
||||
&self.values[line * self.line_len + col]
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::IndexMut<(usize, usize)> for Grid {
|
||||
fn index_mut(&mut self, (line, col): (usize, usize)) -> &mut Self::Output {
|
||||
&mut self.values[line * self.line_len + col]
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Grid {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
for line in self.values.chunks_exact(self.line_len) {
|
||||
line.iter().try_for_each(|v| {
|
||||
write!(
|
||||
f,
|
||||
"{}",
|
||||
match v {
|
||||
true => '@',
|
||||
false => '.',
|
||||
}
|
||||
)
|
||||
})?;
|
||||
writeln!(f)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn parsing(input: &BString) -> color_eyre::Result<Parsed> {
|
||||
let line_len = input.find(b"\n").with_context(|| "No newline found")?;
|
||||
let values: Vec<_> = input
|
||||
.iter()
|
||||
.filter(|&&v| v != b'\n')
|
||||
.map(|&v| v == b'@')
|
||||
.collect();
|
||||
|
||||
assert_eq!(
|
||||
values.len() % line_len,
|
||||
0,
|
||||
"Line length does not divide the grid size"
|
||||
);
|
||||
Ok(Grid {
|
||||
line_len,
|
||||
col_len: values.len() / line_len,
|
||||
values,
|
||||
})
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn part1(input: Parsed) {
|
||||
let mut count = 0;
|
||||
|
||||
for line in 0..input.line_len {
|
||||
for col in 0..input.line_len {
|
||||
if input[(line, col)] && input.neighbours(line, col) < 4 {
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print_res!("Accessible roll count: {count}");
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
pub fn part2(mut input: Parsed) {
|
||||
let mut count = 0;
|
||||
|
||||
loop {
|
||||
let mut found = false;
|
||||
for line in 0..input.line_len {
|
||||
for col in 0..input.line_len {
|
||||
if input[(line, col)] && input.neighbours(line, col) < 4 {
|
||||
input[(line, col)] = false;
|
||||
found = true;
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
print_res!("Total removed: {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(())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue