Zytkowski's Thought Dumpster

Advent of Code 2023 - Day 13

I'ts that time of year again, the Advent of Code! I'm completing the challenges this year using Rust 🦀 Day 13 was a real downer as well, was not in a good state of mind to make part 2, so we'll settle for part 1 only 🙈

I'll be posting my solutions here, just to document how I'm solving each challenge, and I highly encourage you to check them out before reading my solutions!

Here's the Day 13 Challenge

BTW: Complete Part 1 to have access to Part 2 😉

Solution for Part 1

use std::fs::File;
use std::io::{Read};
use std::path::Path;

#[derive(PartialEq, Debug)]
enum Reflection {
    Horizontal(i32),
    Vertical(i32),
}

fn main() {
    let input_file_path = "path_to_file";
    let mut curr_sum = 0;
    let file = file_as_string(input_file_path)
        .unwrap_or_else(|_| panic!("Could not find input file {}", input_file_path));
    for (id, pattern) in file.split("\r\n\r\n").enumerate() {
        let pattern: Vec<&str> = pattern.split("\r\n").collect();
        let reflection : Reflection = process_pattern(pattern).unwrap_or_else(|_| {
            panic!("Failed to process pattern {}", id)
        });
        match reflection {
            Reflection::Horizontal(result) => {
                curr_sum += result
            }
            Reflection::Vertical(result) => {
                curr_sum += result
            }
        }
    }
    println!("Sum of summarized data: {}", curr_sum)
}

fn process_pattern(pattern: Vec<&str>) -> Result<Reflection, &'static str> {
    for (idx, rows) in pattern.windows(2).enumerate() {
        if rows[0] == rows[1] {
            let mut a_slice = &pattern[0..=idx];
            let mut b_slice = &pattern[idx + 1..];
            if b_slice.len() > a_slice.len() {
                b_slice = &pattern[idx + 1..idx + 1 + a_slice.len()]
            }
            if a_slice.len() > b_slice.len() {
                a_slice = &a_slice[a_slice.len()- b_slice.len()..]
            }
            let mut a_slice = a_slice.to_vec();
            a_slice.reverse();
            if b_slice == a_slice {
                return Ok(Reflection::Horizontal(((idx + 1) * 100) as i32))
            }
        }
    }
    let transposed_pattern : Vec<String> = transpose_pattern(&pattern);
    for (idx, rows) in transposed_pattern.windows(2).enumerate() {
        if rows[0] == rows[1] {
            let mut a_slice = &transposed_pattern[0..=idx];
            let mut b_slice = &transposed_pattern[idx + 1..];
            if b_slice.len() > a_slice.len() {
                b_slice = &transposed_pattern[idx + 1..idx + 1 + a_slice.len()]
            }
            if a_slice.len() > b_slice.len() {
                a_slice = &a_slice[a_slice.len()- b_slice.len()..]
            }
            let mut a_slice = a_slice.to_vec();
            a_slice.reverse();
            if b_slice == a_slice {
                return Ok(Reflection::Vertical((idx + 1) as i32))
            }
        }
    }
    Err("Could not determine pattern.")
}

fn transpose_pattern(pattern: &[&str]) -> Vec<String> {
    let mut result : Vec<String> = Vec::new();
    for idx in 0..pattern.first().unwrap().len() {
        let col : Vec<char> = pattern.iter().map(|row| row.chars().nth(idx).unwrap()).collect();
        let row_as_str : String = col.iter().rev().collect();
        result.push(row_as_str);
    }
    result
}

fn file_as_string<P: AsRef<Path>>(filename: P) -> std::io::Result<String> {
    let mut file = File::open(filename)?;
    let mut file_as_str = String::new();
    File::read_to_string(&mut file, &mut file_as_str)?;
    Ok(file_as_str)
}

Solution for Part 2

// I will do this. One day. :P