diff --git a/aoc2023/src/day12.rs b/aoc2023/src/day12.rs index fefbcfe..95e23cb 100644 --- a/aoc2023/src/day12.rs +++ b/aoc2023/src/day12.rs @@ -1,71 +1,74 @@ -use std::fmt::format; +use std::iter; use std::iter::zip; -use std::net::Shutdown::Read; use itertools::Itertools; use shared::{Solution, Answer}; -use regex::Regex; -use shared::Answer::String; pub struct Day12; impl Solution for Day12 { fn part_1(&self, input: &str) -> Answer { let lines = input.lines() - .map(|x| x.split_once(' ').unwrap().0) - .collect::>(); - let groups: Vec> = input.lines() - .map(|x| x.split_once(' ').unwrap().1.split(',').map(|y| y.parse::().unwrap()).collect()) + .map(|x| x.split_once(' ').unwrap().0.chars().collect()) + .collect::>>(); + let groups: Vec> = input.lines() + .map(|x| x.split_once(' ').unwrap().1.split(',').map(|y| y.parse::().unwrap()).collect()) .collect(); let mut out = 0; for (line, group) in zip(lines, groups) { - for pattern in generate_patterns(line.len() as i32, &group) { - if pattern.is_match(line) { - out += 1; - } - } - println!("{out}"); + out += solve(&line, &group) } Answer::from(out) } fn part_2(&self, input: &str) -> Answer { - Answer::Unimplemented - } -} + let lines = input.lines() + .map(|x| iter::repeat(x.split_once(' ').unwrap().0).take(5).join("?").chars().collect()) + .collect::>>(); + let groups: Vec> = input.lines() + .map(|x| iter::repeat( + x.split_once(' ') + .unwrap().1 + .split(',') + .map(|a| a.parse::().unwrap()) + ).take(5) + .flatten() + .collect() + ).collect(); + let mut out = 0; -fn generate_patterns(len_of_str: i32, groups: &Vec) -> Vec { - let uncertain: i32 = len_of_str - groups.iter().sum::() - groups.len() as i32 + 1; - - let mut patterns: Vec = vec![]; - let possible_gaps = get_gaps(uncertain, groups.len() as i32 + 1); - - for gaps in possible_gaps { - let mut pattern = format!("^[.?]{{{}}}[#?]{{{}}}", gaps.first().unwrap(), groups.first().unwrap()); - for i in 1..groups.len() { - pattern.push_str(format!(r"[.?]{{{}}}[#?]{{{}}}", gaps[i] + 1, groups[i]).as_str()) + for (line, group) in zip(lines, groups) { + out += solve(&line, &group) } - pattern.push_str(format!("[.?]{{{}}}$", gaps.last().unwrap()).as_str()); - patterns.push(Regex::new(pattern.as_str()).unwrap()) - } - patterns + Answer::from(out) + } } -fn get_gaps(total: i32, parts: i32) -> Vec> { - if total == 0 { return vec![vec![0; parts as usize]] } - else if parts == 1 { return vec![vec![total]] } +fn solve(springs: &Vec, groups: &Vec) -> u64 { + let n = springs.len(); + let m = groups.len(); - let mut out: Vec> = vec![]; + let mut possibilities: Vec> = vec![vec![0; m+1]; n+1]; - for i in 0..=total { - for mut sub in get_gaps(total - i, parts - 1) { - out.push({ sub.push(i); sub }); + possibilities[0][0] = 1; + + for i in 0..n { + for j in 0..=m { + if springs[i] != '#' { + possibilities[i+1][j] += possibilities[i][j]; + } + if j < m + && (i + groups[j] as usize) <= n + && !springs[i..(i + groups[j] as usize)].contains(&'.') + && (i + groups[j] as usize >= n || springs[i + groups[j] as usize ] != '#') { + possibilities[(i + groups[j] as usize + 1).min(n)][j+1] += possibilities[i][j] + } } } - out + possibilities[n][m] } diff --git a/src/main.rs b/src/main.rs index 84cd62c..2dba061 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,7 +11,7 @@ fn main() { let Ok(data) = load_actual(2023, 12) else { panic!("No Input Data"); }; - let result = aoc2023::day12::Day12.part_1(&data); + let result = aoc2023::day12::Day12.part_2(&data); let elapsed = now.elapsed();