2025: day04: part 1

This commit is contained in:
Antoine Martin 2025-12-08 16:14:58 +01:00
parent 261480afa3
commit 8f2d42bb73
5 changed files with 269 additions and 1 deletions

120
aoc2025/src/day04.rs Normal file
View file

@ -0,0 +1,120 @@
use std::{fmt::Write, str::FromStr};
use anyhow::{bail, Result};
const INPUT: &str = include_str!("../input/day04.txt");
pub fn run() -> Result<String> {
let mut res = String::with_capacity(128);
writeln!(res, "part 1: {}", part1(INPUT)?)?;
Ok(res)
}
struct PaperRollsMap(Vec<Vec<bool>>);
impl FromStr for PaperRollsMap {
type Err = anyhow::Error;
fn from_str(s: &str) -> Result<Self> {
let mut grid = Vec::new();
let mut width = None;
for line in s.lines() {
match width {
Some(size) => assert_eq!(size, line.len()),
None => width = Some(line.len()),
}
grid.push(
line.chars()
.map(|c| match c {
'@' => Ok(true),
'.' => Ok(false),
_ => bail!("unknown character `{}' while parsing grid", c),
})
.collect::<Result<Vec<_>>>()?,
);
}
Ok(Self(grid))
}
}
impl PaperRollsMap {
fn width(&self) -> usize {
self.0[0].len()
}
fn len(&self) -> usize {
self.0.len()
}
fn count_accessible_rolls(&self) -> usize {
let mut count = 0;
for y in 0..self.len() {
for x in 0..self.width() {
if self.0[y][x] && self.roll_is_accessible(x, y) {
count += 1
}
}
}
count
}
fn roll_is_accessible(&self, x: usize, y: usize) -> bool {
let mut count = 0;
for dy in [-1, 0, 1] {
match y.checked_add_signed(dy) {
None => continue,
Some(yval) if yval == self.len() => continue,
Some(yval) => {
for dx in [-1, 0, 1] {
match x.checked_add_signed(dx) {
None => continue,
Some(xval) if xval == self.width() => continue,
Some(xval) => {
if self.0[yval][xval] {
count += 1
}
}
}
}
}
}
}
count <= 4
}
}
fn part1(input: &str) -> Result<usize> {
let grid: PaperRollsMap = input.parse()?;
Ok(grid.count_accessible_rolls())
}
#[cfg(test)]
mod tests {
use super::*;
const PROVIDED: &str = include_str!("../input/day04_provided.txt");
#[test]
fn part1_provided() {
assert_eq!(part1(PROVIDED).unwrap(), 13);
}
#[test]
fn part1_real() {
assert_eq!(part1(INPUT).unwrap(), 1393);
}
//#[test]
//fn part2_provided() {
// assert_eq!(part2(PROVIDED).unwrap(), 3121910778619);
//}
//#[test]
//fn part2_real() {
// assert_eq!(part2(INPUT).unwrap(), 168798209663590);
//}
}

View file

@ -1,3 +1,4 @@
pub mod day01;
pub mod day02;
pub mod day03;
pub mod day04;

View file

@ -5,9 +5,10 @@ use aoc::DayFunc;
use aoc2025::day01;
use aoc2025::day02;
use aoc2025::day03;
use aoc2025::day04;
fn main() -> Result<()> {
let days: &[DayFunc] = &[day01::run, day02::run, day03::run];
let days: &[DayFunc] = &[day01::run, day02::run, day03::run, day04::run];
aoc::run(days)
}