2023 - Day 13
This commit is contained in:
parent
86202a10e6
commit
a9fe2fa9be
1385
2023/input/13/input
Normal file
1385
2023/input/13/input
Normal file
File diff suppressed because it is too large
Load Diff
15
2023/input/13/test-1
Normal file
15
2023/input/13/test-1
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
#.##..##.
|
||||||
|
..#.##.#.
|
||||||
|
##......#
|
||||||
|
##......#
|
||||||
|
..#.##.#.
|
||||||
|
..##..##.
|
||||||
|
#.#.##.#.
|
||||||
|
|
||||||
|
#...##..#
|
||||||
|
#....#..#
|
||||||
|
..##..###
|
||||||
|
#####.##.
|
||||||
|
#####.##.
|
||||||
|
..##..###
|
||||||
|
#....#..#
|
197
2023/src/bin/day13.rs
Normal file
197
2023/src/bin/day13.rs
Normal file
|
@ -0,0 +1,197 @@
|
||||||
|
#![feature(test)]
|
||||||
|
use anyhow::Result;
|
||||||
|
use aoc::Solver;
|
||||||
|
|
||||||
|
// -- Runners --
|
||||||
|
fn main() -> Result<()> {
|
||||||
|
Day::solve()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part1_test1() -> Result<()> {
|
||||||
|
Day::test(Day::part1, "test-1", 405)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part1_solution() -> Result<()> {
|
||||||
|
Day::test(Day::part1, "input", 36448)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2_test1() -> Result<()> {
|
||||||
|
Day::test(Day::part2, "test-1", 400)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn part2_solution() -> Result<()> {
|
||||||
|
Day::test(Day::part2, "input", 35799)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Benchmarks
|
||||||
|
extern crate test;
|
||||||
|
#[bench]
|
||||||
|
#[ignore]
|
||||||
|
fn part1_bench(b: &mut test::Bencher) {
|
||||||
|
Day::benchmark(Day::part1, b)
|
||||||
|
}
|
||||||
|
#[bench]
|
||||||
|
#[ignore]
|
||||||
|
fn part2_bench(b: &mut test::Bencher) {
|
||||||
|
Day::benchmark(Day::part2, b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
|
enum Ground {
|
||||||
|
Ash,
|
||||||
|
Rocks,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ground {
|
||||||
|
fn flip(&self) -> Self {
|
||||||
|
match self {
|
||||||
|
Ground::Ash => Ground::Rocks,
|
||||||
|
Ground::Rocks => Ground::Ash,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<char> for Ground {
|
||||||
|
fn from(c: char) -> Self {
|
||||||
|
match c {
|
||||||
|
'.' => Self::Ash,
|
||||||
|
'#' => Self::Rocks,
|
||||||
|
_ => unreachable!("Invalid input"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- Solution --
|
||||||
|
pub struct Day;
|
||||||
|
impl aoc::Solver for Day {
|
||||||
|
type Output1 = usize;
|
||||||
|
type Output2 = usize;
|
||||||
|
|
||||||
|
fn day() -> u8 {
|
||||||
|
13
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part1(input: &str) -> Self::Output1 {
|
||||||
|
input
|
||||||
|
.split("\n\n")
|
||||||
|
.map(|block| {
|
||||||
|
block
|
||||||
|
.lines()
|
||||||
|
.map(|line| line.chars().map(|c| c.into()).collect::<Vec<Ground>>())
|
||||||
|
.collect::<Vec<Vec<_>>>()
|
||||||
|
})
|
||||||
|
.map(|block| {
|
||||||
|
let height = block.len();
|
||||||
|
let width = block[0].len();
|
||||||
|
|
||||||
|
if let Some(y) = (1..height).find(|&y| {
|
||||||
|
let top = block[0..y].iter().rev();
|
||||||
|
let bottom = block[y..height].iter();
|
||||||
|
|
||||||
|
top.zip(bottom).all(|(a, b)| a == b)
|
||||||
|
}) {
|
||||||
|
100 * y
|
||||||
|
} else if let Some(x) = (1..width).find(|&x| {
|
||||||
|
block.iter().all(|line| {
|
||||||
|
let left = line[0..x].iter().rev();
|
||||||
|
let right = line[x..width].iter();
|
||||||
|
|
||||||
|
left.zip(right).all(|(a, b)| a == b)
|
||||||
|
})
|
||||||
|
}) {
|
||||||
|
x
|
||||||
|
} else {
|
||||||
|
unreachable!("Their is always a mirror line")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.sum()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn part2(input: &str) -> Self::Output2 {
|
||||||
|
input
|
||||||
|
.split("\n\n")
|
||||||
|
.map(|block| {
|
||||||
|
block
|
||||||
|
.lines()
|
||||||
|
.map(|line| line.chars().map(|c| c.into()).collect::<Vec<Ground>>())
|
||||||
|
.collect::<Vec<Vec<_>>>()
|
||||||
|
})
|
||||||
|
.map(|mut block| {
|
||||||
|
let height = block.len();
|
||||||
|
let width = block[0].len();
|
||||||
|
|
||||||
|
// Get the row/column of the old mirror line
|
||||||
|
let (x_old, y_old) = if let Some(y) = (1..height).find(|&y| {
|
||||||
|
let top = block[0..y].iter().rev();
|
||||||
|
let bottom = block[y..height].iter();
|
||||||
|
|
||||||
|
top.zip(bottom).all(|(a, b)| a == b)
|
||||||
|
}) {
|
||||||
|
(None, Some(y))
|
||||||
|
} else if let Some(x) = (1..width).find(|&x| {
|
||||||
|
block.iter().all(|line| {
|
||||||
|
let left = line[0..x].iter().rev();
|
||||||
|
let right = line[x..width].iter();
|
||||||
|
|
||||||
|
left.zip(right).all(|(a, b)| a == b)
|
||||||
|
})
|
||||||
|
}) {
|
||||||
|
(Some(x), None)
|
||||||
|
} else {
|
||||||
|
unreachable!("Their is always a mirror line")
|
||||||
|
};
|
||||||
|
|
||||||
|
// Try every possible smudge location
|
||||||
|
for j in 0..width {
|
||||||
|
for i in 0..height {
|
||||||
|
// Flip one
|
||||||
|
block[i][j] = block[i][j].flip();
|
||||||
|
|
||||||
|
if let Some(y) = (1..height).find(|&y| {
|
||||||
|
// The mirror line can not be the old one
|
||||||
|
if y_old == Some(y) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let top = block[0..y].iter().rev();
|
||||||
|
let bottom = block[y..height].iter();
|
||||||
|
|
||||||
|
top.zip(bottom).all(|(a, b)| a == b)
|
||||||
|
}) {
|
||||||
|
return 100 * y;
|
||||||
|
} else if let Some(x) = (1..width).find(|&x| {
|
||||||
|
// The mirror line can not be the old one
|
||||||
|
if x_old == Some(x) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
block.iter().all(|line| {
|
||||||
|
let left = line[0..x].iter().rev();
|
||||||
|
let right = line[x..width].iter();
|
||||||
|
|
||||||
|
left.zip(right).all(|(a, b)| a == b)
|
||||||
|
})
|
||||||
|
}) {
|
||||||
|
return x;
|
||||||
|
} else {
|
||||||
|
// Revert flip
|
||||||
|
block[i][j] = block[i][j].flip();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unreachable!("Their should always be a mirror line")
|
||||||
|
})
|
||||||
|
.sum()
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user