2023: Day 13, part 1

This commit is contained in:
Wesley Moore 2023-12-13 20:01:24 +10:00
parent 2f04763e1c
commit 663fc5bc6e
No known key found for this signature in database
5 changed files with 1455 additions and 0 deletions

7
2023/day13/Cargo.lock generated Normal file
View file

@ -0,0 +1,7 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "day13"
version = "0.1.0"

8
2023/day13/Cargo.toml Normal file
View file

@ -0,0 +1,8 @@
[package]
name = "day13"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

85
2023/day13/src/main.rs Normal file
View file

@ -0,0 +1,85 @@
use std::string::FromUtf8Error;
use std::{env, fs};
type BoxError = Box<dyn std::error::Error>;
fn main() -> Result<(), BoxError> {
let input_path = env::args_os()
.skip(1)
.next()
.ok_or("missing input file path")?;
let input = fs::read_to_string(&input_path)?;
let mut vertical = Vec::new();
let mut horizontal = Vec::new();
for pattern in input.split("\n\n") {
if pattern.is_empty() {
continue;
}
println!("{pattern}");
let lines = pattern.lines().collect::<Vec<_>>();
if let Some(i) = find_mirror_point(&lines) {
horizontal.push(i);
continue;
}
// transpose the lines to try to a vertical mirror point
let transposed = transpose(&lines)?;
if let Some(i) = find_mirror_point(&transposed) {
vertical.push(i);
} else {
return Err("no vertical or horizontal split".into());
}
println!()
}
let part1 = vertical.iter().sum::<usize>() + horizontal.iter().map(|h| *h * 100).sum::<usize>();
println!("Part 1: {part1}");
Ok(())
}
fn find_mirror_point<T: AsRef<str>>(lines: &[T]) -> Option<usize> {
let mut prev: Option<&str> = None;
for (i, line) in lines.iter().enumerate() {
match prev {
Some(prev) if prev == line.as_ref() => {
print!("possible mirror point at {i}: ");
// split the array in half, see if they're the same
let (first, second) = lines.split_at(i);
// ensure they're the same length
let len = first.len().min(second.len());
let start = first.len() - len;
let (first, second) = (&first[start..], &second[..len]);
if first
.iter()
.rev()
.zip(second.iter())
.all(|(l, r)| l.as_ref() == r.as_ref())
{
println!("seems to be mirror point");
return Some(i);
} else {
println!("no match");
}
}
Some(_) | None => {}
}
prev = Some(line.as_ref())
}
None
}
fn transpose(lines: &[&str]) -> Result<Vec<String>, FromUtf8Error> {
let mut transposed = Vec::new();
for i in 0..lines[0].len() {
let mut col = Vec::new();
for line in lines.iter() {
col.push(line.as_bytes()[i])
}
transposed.push(String::from_utf8(col)?);
}
Ok(transposed)
}

16
2023/input/day13.sample Normal file
View file

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

1339
2023/input/day13.txt Normal file

File diff suppressed because it is too large Load diff