1
0
Fork 0

day(13): add solution

Signed-off-by: Matej Focko <mfocko@redhat.com>
This commit is contained in:
Matej Focko 2023-12-13 15:43:06 +01:00
parent dab87eeb22
commit 327a2d1df4
Signed by: mfocko
GPG key ID: 7C47D46246790496
2 changed files with 103 additions and 0 deletions

15
samples/day13.txt Normal file
View file

@ -0,0 +1,15 @@
#.##..##.
..#.##.#.
##......#
##......#
..#.##.#.
..##..##.
#.#.##.#.
#...##..#
#....#..#
..##..###
#####.##.
#####.##.
..##..###
#....#..#

88
src/bin/day13.rs Normal file
View file

@ -0,0 +1,88 @@
use std::cmp::min;
use aoc_2023::*;
use itertools::iproduct;
type Output1 = i32;
type Output2 = Output1;
struct Pattern {
map: Vec<Vec<char>>,
}
impl From<&[String]> for Pattern {
fn from(value: &[String]) -> Self {
Self {
map: value.iter().map(|l| l.chars().collect_vec()).collect_vec(),
}
}
}
impl Pattern {
fn check_vertically(&self, allowed_error: usize) -> Option<i32> {
(0..self.map[0].len() - 1)
.find(|&x| {
let d = min(x + 1, self.map[0].len() - x - 1);
iproduct!(0..self.map.len(), (0..d))
.filter(|&(y, dx)| self.map[y][x - dx] != self.map[y][x + dx + 1])
.count()
== allowed_error
})
.map(|x| (x + 1) as i32)
}
fn check_horizontally(&self, allowed_error: usize) -> Option<i32> {
(0..self.map.len() - 1)
.find(|&y| {
let d = min(y + 1, self.map.len() - y - 1);
iproduct!(0..self.map[y].len(), (0..d))
.filter(|&(x, dy)| self.map[y - dy][x] != self.map[y + dy + 1][x])
.count()
== allowed_error
})
.map(|y| 100 * (y + 1) as i32)
}
fn score(&self, allowed_error: usize) -> i32 {
if let Some(s) = self.check_vertically(allowed_error) {
s
} else if let Some(s) = self.check_horizontally(allowed_error) {
s
} else {
unreachable!()
}
}
}
struct Day13 {
patterns: Vec<Pattern>,
}
impl Solution<Output1, Output2> for Day13 {
fn new<P: AsRef<Path>>(pathname: P) -> Self {
let lines: Vec<String> = file_to_lines(pathname);
let patterns = lines
.split(|l| l.is_empty())
.map(|m| m.into())
.collect_vec();
Self { patterns }
}
fn part_1(&mut self) -> Output1 {
self.patterns.iter().map(|p| p.score(0)).sum()
}
fn part_2(&mut self) -> Output2 {
self.patterns.iter().map(|p| p.score(1)).sum()
}
}
fn main() -> Result<()> {
// Day13::run("sample")
Day13::main()
}
test_sample!(day_13, Day13, 405, 400);