AoC 2023 day 13
The snippet can be accessed without any authentication.
Authored by
s91149
Edited
main.rs 3.84 KiB
fn main() {
let input = std::fs::read_to_string("../inputs/input.txt").unwrap();
let blocks: Vec<Block> = input
.split("\n\n")
.map(|block| {
let block: Vec<Vec<char>> = block
.lines()
.map(|line| line.chars().collect::<Vec<char>>())
.collect();
Block(block)
})
.collect();
part_1(&blocks);
part_2(&blocks);
}
#[derive(Clone)]
struct Block(Vec<Vec<char>>);
impl Block {
fn transpose(&self) -> Self {
let block = &self.0;
let mut transposed: Vec<Vec<char>> = Vec::new();
let block_height = block.len();
let block_width = block[1].len();
for x in 0..block_width {
let mut v = Vec::with_capacity(block_height);
for y in 0..block_height {
v.push(block[y][x]);
}
transposed.push(v);
}
Block(transposed)
}
fn count_above_reflect_point(&self) -> u32 {
let block = &self.0;
for i in 1..block.len() {
if block[i] == block[i - 1] {
let before = &block[..i];
let after = &block[i..];
if before.iter().rev().zip(after.iter()).all(|(a, b)| a == b) {
return i as u32;
}
}
}
0
}
fn find_all_reflection_points(&self) -> Vec<u32> {
let block = &self.0;
let mut v = Vec::new();
for i in 1..block.len() {
if block[i] == block[i - 1] {
let before = &block[..i];
let after = &block[i..];
if before.iter().rev().zip(after.iter()).all(|(a, b)| a == b) {
v.push(i as u32);
}
}
}
v
}
}
fn part_1(blocks: &[Block]) {
let mut above_sum = 0;
let mut left_sum = 0;
for block in blocks.iter() {
above_sum += block.count_above_reflect_point();
let transposed = block.transpose();
left_sum += transposed.count_above_reflect_point();
}
println!("part 1: {}", left_sum + 100 * above_sum);
}
fn part_2(blocks: &[Block]) {
let mut above_sum = 0;
let mut left_sum = 0;
'outer: for block in blocks.iter() {
let block_height = block.0.len();
let block_width = block.0[0].len();
let n_above = block.find_all_reflection_points();
let transposed = block.transpose();
let n_left = transposed.find_all_reflection_points();
for y in 0..block_height {
for x in 0..block_width {
let mut modified_block: Block = block.clone();
modified_block.0[y][x] = match modified_block.0[y][x] {
'#' => '.',
'.' => '#',
_ => unreachable!(),
};
let modified_n_above = modified_block.find_all_reflection_points();
let transposed_modified_block = modified_block.transpose();
let modified_n_left = transposed_modified_block.find_all_reflection_points();
if !modified_n_above.is_empty() && modified_n_above != n_above {
let new_res = modified_n_above
.iter()
.find(|&item| !n_above.contains(item))
.unwrap();
above_sum += new_res;
continue 'outer;
}
if !modified_n_left.is_empty() && modified_n_left != n_left {
let new_res = modified_n_left
.iter()
.find(|&item| !n_left.contains(item))
.unwrap();
left_sum += new_res;
continue 'outer;
}
}
}
}
println!("part 2: {}", left_sum + 100 * above_sum);
}
Please register or sign in to comment