2025: day04: part 1
This commit is contained in:
parent
261480afa3
commit
8f2d42bb73
5 changed files with 269 additions and 1 deletions
120
aoc2025/src/day04.rs
Normal file
120
aoc2025/src/day04.rs
Normal 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);
|
||||
//}
|
||||
}
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
pub mod day01;
|
||||
pub mod day02;
|
||||
pub mod day03;
|
||||
pub mod day04;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue