Advent of Code 2023 - Day 12
I'ts that time of year again, the Advent of Code! I'm completing the challenges this year using Rust 🦀 Day 12 had a tough part 1, but a tougher part 2.
I have not been able to complete part 2 yet (I really don't think brute forcing this one is viable). But I plan to get back to it once I learn what I deem necessary! 🙌
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 12 Challenge
BTW: Complete Part 1 to have access to Part 2 😉
Solution for Part 1
use std::fs::File;
use std::io::{Read, Result};
use std::path::Path;
use std::str::FromStr;
fn main() {
let input_file_path = "path_to_input_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 line in file.split("\r\n") {
let (combination_base, groups) = line.split_once(' ').unwrap();
let groups : Vec<usize> = groups.split(',')
.map(|c| usize::from_str(c).unwrap())
.collect();
curr_sum += sum_valid_combinations(combination_base, &groups);
}
println!("Sum of valid arrangements: {}", curr_sum)
}
fn sum_valid_combinations(combination: &str, groups: &[usize]) -> usize {
match combination.chars().filter(|c| c == &'?').count() > 0 {
true => {
// Replace first occurrence of wildcard with broken spring
let comb_a = combination.replacen('?', "#", 1);
// Replace first occurrence of wildcard with working spring
let comb_b = combination.replacen('?', ".", 1);
sum_valid_combinations(&comb_a, groups) + sum_valid_combinations(&comb_b, groups)
}
false => {
match combination_matches_groups(combination, groups) {
true => 1,
false => 0,
}
}
}
}
fn combination_matches_groups(comb : &str, groups: &[usize]) -> bool {
let mut new_comb = comb.to_string();
new_comb = new_comb.trim_matches('.').parse().unwrap();
while new_comb.contains("..") {
new_comb = new_comb.replace("..",".")
}
let sections = new_comb.split('.').count();
if sections != groups.len() {
return false
}
for (idx, group) in new_comb.split('.').enumerate() {
if group.len() != groups[idx] {
return false;
}
}
true
}
fn file_as_string<P: AsRef<Path>>(filename: P) -> 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