Compare commits
No commits in common. "7b0d96551ae2a08d14a124b995d2a2071f5629d1" and "e520118ac294e895bb2dc1afabb6da27b6ab4c59" have entirely different histories.
7b0d96551a
...
e520118ac2
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +0,0 @@
|
||||||
???.### 1,1,3
|
|
||||||
.??..??...?##. 1,1,3
|
|
||||||
?#?#?#?#?#?#?#? 1,3,1,6
|
|
||||||
????.#...#... 4,1,1
|
|
||||||
????.######..#####. 1,6,5
|
|
||||||
?###???????? 3,2,1
|
|
|
@ -1,6 +0,0 @@
|
||||||
#[derive(Debug, PartialEq, Clone, Copy, Hash, Eq)]
|
|
||||||
pub enum Spring {
|
|
||||||
O,
|
|
||||||
D,
|
|
||||||
U,
|
|
||||||
}
|
|
|
@ -1,25 +0,0 @@
|
||||||
pub mod part_one;
|
|
||||||
pub mod part_two;
|
|
||||||
pub mod common;
|
|
||||||
|
|
||||||
use crate::utils::solution::Solution;
|
|
||||||
use crate::utils::input_reader;
|
|
||||||
|
|
||||||
pub struct DaySolution ;
|
|
||||||
|
|
||||||
|
|
||||||
impl Solution for DaySolution {
|
|
||||||
|
|
||||||
fn input_path(&self) -> &'static str {
|
|
||||||
"input/2023/day_12/input.txt"
|
|
||||||
}
|
|
||||||
|
|
||||||
fn part_one(&self) -> String {
|
|
||||||
input_reader::read_input_file(self.input_path(), part_one::part_one)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn part_two(&self) -> String {
|
|
||||||
input_reader::read_input_file(self.input_path(), part_two::part_two)
|
|
||||||
//String::from("Not implemented")
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,109 +0,0 @@
|
||||||
use super::common::Spring;
|
|
||||||
|
|
||||||
pub fn part_one(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()));
|
|
||||||
}
|
|
||||||
|
|
||||||
// for i in 0..springs.len() {
|
|
||||||
// println!("{:?} - {:?}", springs[i], values[i]);
|
|
||||||
// }
|
|
||||||
|
|
||||||
let mut res = 0;
|
|
||||||
for i in 0..springs.len() {
|
|
||||||
let search_spring = springs[i].clone();
|
|
||||||
res += unknown_search(search_spring, values[i].clone());
|
|
||||||
}
|
|
||||||
|
|
||||||
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),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
spring_line
|
|
||||||
}
|
|
||||||
|
|
||||||
fn parse_nums(line: String) -> Vec<usize> {
|
|
||||||
let nums: Vec<usize> = line.split(',').map(|x| x.parse().unwrap()).collect();
|
|
||||||
nums
|
|
||||||
}
|
|
||||||
|
|
||||||
fn validate(spring_line: Vec<Spring>, values: Vec<usize>) -> usize {
|
|
||||||
|
|
||||||
let mut validation_vals: Vec<usize> = Vec::new();
|
|
||||||
let mut count: usize = 0;
|
|
||||||
|
|
||||||
// println!("{:?}: {:?}", spring_line, values);
|
|
||||||
|
|
||||||
for i in 0..spring_line.len() {
|
|
||||||
match spring_line[i] {
|
|
||||||
Spring::O => {
|
|
||||||
if count > 0 {
|
|
||||||
validation_vals.push(count);
|
|
||||||
count = 0;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Spring::D => {
|
|
||||||
count += 1;
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
panic!("Invalid spring");
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if count > 0 {
|
|
||||||
validation_vals.push(count);
|
|
||||||
}
|
|
||||||
|
|
||||||
if validation_vals == values {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unknown_search(spring_line: Vec<Spring>, values: Vec<usize>) -> usize {
|
|
||||||
|
|
||||||
// println!("Unknown search: {:?}", spring_line);
|
|
||||||
|
|
||||||
let mut res = 0;
|
|
||||||
|
|
||||||
let unknowns: Vec<usize> = spring_line.iter().enumerate().filter(|(_, x)| **x == Spring::U).map(|(i, _)| i).collect();
|
|
||||||
let i = unknowns.first();
|
|
||||||
|
|
||||||
if i.is_none() {
|
|
||||||
return validate(spring_line, values);
|
|
||||||
}
|
|
||||||
|
|
||||||
let i = i.unwrap();
|
|
||||||
|
|
||||||
let mut op_spring_line = spring_line.clone();
|
|
||||||
op_spring_line[*i] = Spring::O;
|
|
||||||
res += unknown_search(op_spring_line, values.clone());
|
|
||||||
|
|
||||||
let mut dmg_spring_line = spring_line.clone();
|
|
||||||
dmg_spring_line[*i] = Spring::D;
|
|
||||||
res += unknown_search(dmg_spring_line, values.clone());
|
|
||||||
|
|
||||||
|
|
||||||
res
|
|
||||||
}
|
|
|
@ -1,131 +0,0 @@
|
||||||
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
|
|
||||||
}
|
|
|
@ -9,7 +9,6 @@ pub mod day_08_haunted_wasteland;
|
||||||
pub mod day_09_mirage_maintenance;
|
pub mod day_09_mirage_maintenance;
|
||||||
pub mod day_10_pipe_maze;
|
pub mod day_10_pipe_maze;
|
||||||
pub mod day_11_cosmic_expantion;
|
pub mod day_11_cosmic_expantion;
|
||||||
pub mod day_12_hot_springs;
|
|
||||||
|
|
||||||
pub fn run(day: &str) {
|
pub fn run(day: &str) {
|
||||||
let solution: Box<dyn Solution> = match day {
|
let solution: Box<dyn Solution> = match day {
|
||||||
|
@ -22,7 +21,6 @@ pub fn run(day: &str) {
|
||||||
"9" => Box::new(day_09_mirage_maintenance::DaySolution),
|
"9" => Box::new(day_09_mirage_maintenance::DaySolution),
|
||||||
"10" => Box::new(day_10_pipe_maze::DaySolution),
|
"10" => Box::new(day_10_pipe_maze::DaySolution),
|
||||||
"11" => Box::new(day_11_cosmic_expantion::DaySolution),
|
"11" => Box::new(day_11_cosmic_expantion::DaySolution),
|
||||||
"12" => Box::new(day_12_hot_springs::DaySolution),
|
|
||||||
_ => panic!("Invalid day specified"),
|
_ => panic!("Invalid day specified"),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue