-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathday12.rs
70 lines (59 loc) · 2.58 KB
/
day12.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
use std::collections::HashMap;
use std::fs;
pub(crate) fn day12() {
println!("{}", part_a(fs::read_to_string("input/2023/day12/input.txt").unwrap()));
println!("{}", part_b(fs::read_to_string("input/2023/day12/input.txt").unwrap()));
}
fn part_a(input: String) -> usize {
input.lines().map(|line| {
let (springs, r) = line.split_once(" ").unwrap();
let groups: Vec<usize> = r.split(",").map(|n| n.parse::<usize>().unwrap()).collect();
solve(springs, &groups)
}).sum()
}
fn part_b(input: String) -> usize {
input.lines().map(|line| {
let (springs, r) = line.split_once(" ").unwrap();
let groups: Vec<usize> = r.split(",").map(|n| n.parse::<usize>().unwrap()).collect();
let groups_5: Vec<usize> = groups.iter().cycle().take(groups.len() * 5).map(|n| *n).collect();
let springs_5 = format!("{}?{}?{}?{}?{}", springs, springs, springs, springs, springs);
solve(springs_5.as_str(), &groups_5)
}).sum()
}
fn solve(springs: &str, groups: &Vec<usize>) -> usize {
let mut state_space = HashMap::new();
state_space.insert((0, 0), 1);
for si in 0..springs.len() {
let c = springs.chars().nth(si).unwrap();
let mut new_state_space = HashMap::new();
for ((gi, g_size), cardinality) in state_space {
if (c == '.' || c == '?') && g_size > 0 && g_size == groups[gi] {
*new_state_space.entry((gi + 1, 0)).or_insert(0) += cardinality;
} else if (c == '.' || c == '?') && g_size == 0 {
*new_state_space.entry((gi, g_size)).or_insert(0) += cardinality;
}
if (c == '#' || c == '?') && gi < groups.len() && g_size < groups[gi] {
*new_state_space.entry((gi, g_size + 1)).or_insert(0) += cardinality;
}
}
state_space = new_state_space;
}
state_space.iter().filter(|((gi, g_size), _)| {
(*g_size == 0 && *gi == groups.len()) || (*gi == groups.len() - 1 && *g_size == groups[*gi])
}).map(|(_, cardinality)| *cardinality).sum()
}
#[cfg(test)]
mod day12_tests {
use std::fs;
use crate::y2023::day12::{part_a, part_b};
#[test]
fn test_works() {
assert_eq!(21, part_a(fs::read_to_string("input/2023/day12/test.txt").unwrap()));
assert_eq!(525152, part_b(fs::read_to_string("input/2023/day12/test.txt").unwrap()));
}
#[test]
fn input_works() {
assert_eq!(7716, part_a(fs::read_to_string("input/2023/day12/input.txt").unwrap()));
assert_eq!(18716325559999, part_b(fs::read_to_string("input/2023/day12/input.txt").unwrap()));
}
}