year2025/
day12.rs

1use utils::prelude::*;
2
3/// Checking region sizes.
4///
5/// The solution assumes that each present shape can be treated as a solid 3x3 square. This makes
6/// the implementation trivial and much faster than a general solution to 2D bin packing (which is
7/// NP-complete).
8#[derive(Clone, Debug)]
9pub struct Day12 {
10    part1: usize,
11}
12
13impl Day12 {
14    pub fn new(input: &str, _: InputType) -> Result<Self, InputError> {
15        let part1 = parser::u32()
16            .repeat_n::<2, _>(b'x')
17            .with_suffix(": ")
18            .then(parser::u32().repeat_fold(b' ', 1, 0u32, |acc, x| acc + x))
19            .repeat_fold(
20                parser::eol(),
21                1,
22                0usize,
23                |acc, ([width, height], shapes)| {
24                    acc + usize::from((width / 3) * (height / 3) >= shapes)
25                },
26            )
27            .with_prefix(
28                // Discard the present shapes at the start of the input
29                parser::u32()
30                    .with_suffix(b':')
31                    .with_eol()
32                    .then(
33                        parser::byte_map!(b'.' => (), b'#' => ())
34                            .repeat_n::<3, _>(parser::noop())
35                            .repeat_n::<3, _>(parser::eol()),
36                    )
37                    .repeat_fold(parser::eol().with_eol(), 1, (), |_, _| ())
38                    .with_eol()
39                    .with_eol(),
40            )
41            .parse_complete(input)?;
42
43        Ok(Self { part1 })
44    }
45
46    #[must_use]
47    pub fn part1(&self) -> usize {
48        self.part1
49    }
50
51    #[must_use]
52    pub fn part2(&self) -> &'static str {
53        "🎄"
54    }
55}
56
57// The examples require actual bin packing, not just counting regions
58examples!(Day12 -> (usize, &'static str) []);