2023-12: Solve part two

This commit is contained in:
Mathis 2023-12-23 00:10:42 +01:00
parent b0447bed64
commit 7b0d96551a
4 changed files with 146 additions and 15 deletions

View File

@ -1,6 +1,6 @@
#[derive(Debug, PartialEq, Clone, Copy)] #[derive(Debug, PartialEq, Clone, Copy, Hash, Eq)]
pub enum Spring { pub enum Spring {
Operational, O,
Damaged, D,
Unknown, U,
} }

View File

@ -1,5 +1,5 @@
pub mod part_one; pub mod part_one;
// pub mod part_two; pub mod part_two;
pub mod common; pub mod common;
use crate::utils::solution::Solution; use crate::utils::solution::Solution;
@ -19,7 +19,7 @@ impl Solution for DaySolution {
} }
fn part_two(&self) -> String { fn part_two(&self) -> String {
//input_reader::read_input_file(self.input_path(), part_two::part_two) input_reader::read_input_file(self.input_path(), part_two::part_two)
String::from("Not implemented") //String::from("Not implemented")
} }
} }

View File

@ -31,9 +31,9 @@ fn parse_springs(line: String) -> Vec<Spring> {
for c in line.chars() { for c in line.chars() {
match c { match c {
'.' => spring_line.push(Spring::Operational), '.' => spring_line.push(Spring::O),
'#' => spring_line.push(Spring::Damaged), '#' => spring_line.push(Spring::D),
_ => spring_line.push(Spring::Unknown), _ => spring_line.push(Spring::U),
} }
} }
@ -54,13 +54,13 @@ fn validate(spring_line: Vec<Spring>, values: Vec<usize>) -> usize {
for i in 0..spring_line.len() { for i in 0..spring_line.len() {
match spring_line[i] { match spring_line[i] {
Spring::Operational => { Spring::O => {
if count > 0 { if count > 0 {
validation_vals.push(count); validation_vals.push(count);
count = 0; count = 0;
} }
}, },
Spring::Damaged => { Spring::D => {
count += 1; count += 1;
}, },
_ => { _ => {
@ -87,7 +87,7 @@ fn unknown_search(spring_line: Vec<Spring>, values: Vec<usize>) -> usize {
let mut res = 0; let mut res = 0;
let unknowns: Vec<usize> = spring_line.iter().enumerate().filter(|(_, x)| **x == Spring::Unknown).map(|(i, _)| i).collect(); let unknowns: Vec<usize> = spring_line.iter().enumerate().filter(|(_, x)| **x == Spring::U).map(|(i, _)| i).collect();
let i = unknowns.first(); let i = unknowns.first();
if i.is_none() { if i.is_none() {
@ -97,11 +97,11 @@ fn unknown_search(spring_line: Vec<Spring>, values: Vec<usize>) -> usize {
let i = i.unwrap(); let i = i.unwrap();
let mut op_spring_line = spring_line.clone(); let mut op_spring_line = spring_line.clone();
op_spring_line[*i] = Spring::Operational; op_spring_line[*i] = Spring::O;
res += unknown_search(op_spring_line, values.clone()); res += unknown_search(op_spring_line, values.clone());
let mut dmg_spring_line = spring_line.clone(); let mut dmg_spring_line = spring_line.clone();
dmg_spring_line[*i] = Spring::Damaged; dmg_spring_line[*i] = Spring::D;
res += unknown_search(dmg_spring_line, values.clone()); res += unknown_search(dmg_spring_line, values.clone());

View File

@ -0,0 +1,131 @@
use std::collections::HashMap;
use super::common::Spring;
pub fn part_two(input_lines: Vec<String>) -> String {
let mut springs: Vec<Vec<Spring>> = Vec::new();
let mut values: Vec<Vec<usize>> = Vec::new();
for line in input_lines {
let split_line: Vec<&str> = line.split(' ').collect();
springs.push(parse_springs(split_line[0].to_string()));
values.push(parse_nums(split_line[1].to_string()));
}
let mut res = 0;
let mut memory: HashMap<(Vec<Spring>, Vec<usize>), usize> = HashMap::new();
for i in 0..springs.len() {
let search_spring = springs[i].clone();
let val = search(search_spring, values[i].clone(), &mut memory);
res += val;
}
res.to_string()
}
fn parse_springs(line: String) -> Vec<Spring> {
let mut spring_line: Vec<Spring> = Vec::new();
for c in line.chars() {
match c {
'.' => spring_line.push(Spring::O),
'#' => spring_line.push(Spring::D),
_ => spring_line.push(Spring::U),
}
}
let mut spring_res = <Vec<Spring>>::new();
for i in 0..5 {
spring_res.extend_from_slice(&spring_line);
if i != 4 {
spring_res.push(Spring::U);
}
}
spring_res
// spring_line
}
fn parse_nums(line: String) -> Vec<usize> {
let nums: Vec<usize> = line.split(',').map(|x| x.parse().unwrap()).collect();
let mut res_nums: Vec<usize> = Vec::new();
for _ in 0..5 {
res_nums.extend_from_slice(&nums);
}
res_nums
// nums
}
fn search(spring_line: Vec<Spring>, groups: Vec<usize>, memory: &mut HashMap<(Vec<Spring>, Vec<usize>), usize>) -> usize {
if memory.contains_key(&(spring_line.clone(), groups.clone())) {
return memory[&(spring_line.clone(), groups.clone())];
}
let mut res = 0;
if groups.len() == 0 {
let damaged: Vec<usize> = spring_line.iter().enumerate().filter(|(_, x)| **x == Spring::D).map(|(i, _)| i).collect();
if damaged.is_empty(){
return 1;
}
} else if !spring_line.is_empty() && spring_line.len() >= groups[0] {
match spring_line[0] {
Spring::O => {
res += search(spring_line[1..].to_vec(), groups.clone(), memory);
},
Spring::D => {
let group = groups[0];
let mut spring_group = spring_line[0..group].to_vec();
for i in 0..group {
if spring_group[i] == Spring::U {
spring_group[i] = Spring::D;
}
}
let operational: Vec<usize> = spring_group.iter().enumerate().filter(|(_, x)| **x == Spring::O).map(|(i, _)| i).collect();
if operational.len() == 0 {
if spring_line.len() == group {
if groups.len() == 1 {
return 1;
}
} else {
if spring_line[group] == Spring::O || spring_line[group] == Spring::U {
res += search(spring_line[group+1..].to_vec(), groups[1..].to_vec(), memory);
}
}
}
}
_ => {
let mut val;
let mut op_clone = spring_line.clone();
op_clone[0] = Spring::O;
let op_groups = groups.clone();
val = search(op_clone, op_groups, memory);
res += val;
let mut dmg_clone = spring_line.clone();
dmg_clone[0] = Spring::D;
let dmg_groups = groups.clone();
val = search(dmg_clone, dmg_groups, memory);
res += val;
}
}
}
memory.insert((spring_line.clone(), groups.clone()), res);
res
}