mirror of
https://github.com/wezm/advent-of-code.git
synced 2024-09-08 00:39:35 +00:00
2023: Day 13, part 1
This commit is contained in:
parent
2f04763e1c
commit
663fc5bc6e
5 changed files with 1455 additions and 0 deletions
7
2023/day13/Cargo.lock
generated
Normal file
7
2023/day13/Cargo.lock
generated
Normal 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
8
2023/day13/Cargo.toml
Normal 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
85
2023/day13/src/main.rs
Normal 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
16
2023/input/day13.sample
Normal file
|
@ -0,0 +1,16 @@
|
|||
#.##..##.
|
||||
..#.##.#.
|
||||
##......#
|
||||
##......#
|
||||
..#.##.#.
|
||||
..##..##.
|
||||
#.#.##.#.
|
||||
|
||||
#...##..#
|
||||
#....#..#
|
||||
..##..###
|
||||
#####.##.
|
||||
#####.##.
|
||||
..##..###
|
||||
#....#..#
|
||||
|
1339
2023/input/day13.txt
Normal file
1339
2023/input/day13.txt
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue