Day 12
This commit is contained in:
parent
a3bb9bbbb3
commit
c41f9df243
@ -46,3 +46,7 @@ path = "src/day10.rs"
|
||||
[[bin]]
|
||||
name = "day11"
|
||||
path = "src/day11.rs"
|
||||
|
||||
[[bin]]
|
||||
name = "day12"
|
||||
path = "src/day12.rs"
|
||||
|
21
inputs/day12.txt
Normal file
21
inputs/day12.txt
Normal file
@ -0,0 +1,21 @@
|
||||
TR-start
|
||||
xx-JT
|
||||
xx-TR
|
||||
hc-dd
|
||||
ab-JT
|
||||
hc-end
|
||||
dd-JT
|
||||
ab-dd
|
||||
TR-ab
|
||||
vh-xx
|
||||
hc-JT
|
||||
TR-vh
|
||||
xx-start
|
||||
hc-ME
|
||||
vh-dd
|
||||
JT-bm
|
||||
end-ab
|
||||
dd-xx
|
||||
end-TR
|
||||
hc-TR
|
||||
start-vh
|
151
src/day12.rs
Normal file
151
src/day12.rs
Normal file
@ -0,0 +1,151 @@
|
||||
use std::collections::HashMap;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct CavePath {
|
||||
caves: (String, String),
|
||||
}
|
||||
|
||||
impl CavePath {
|
||||
fn from(&self, cave: &str) -> Option<&str> {
|
||||
if cave == self.caves.0 {
|
||||
Some(&self.caves.1)
|
||||
} else if cave == self.caves.1 {
|
||||
Some(&self.caves.0)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for CavePath {
|
||||
type Err = ();
|
||||
|
||||
fn from_str(s: &str) -> Result<CavePath, Self::Err> {
|
||||
let caves = s.split_once('-').unwrap();
|
||||
Ok(CavePath {
|
||||
caves: (caves.0.to_string(), caves.1.to_string()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn is_small_cave(cave: &str) -> bool {
|
||||
if cave == "start" {
|
||||
false
|
||||
} else {
|
||||
cave.chars().all(|c| matches!(c, 'a'..='z'))
|
||||
}
|
||||
}
|
||||
|
||||
fn count_paths(input: &str, allow_twice: bool) -> usize {
|
||||
let paths = input
|
||||
.lines()
|
||||
.map(|line| line.parse().unwrap())
|
||||
.collect::<Vec<CavePath>>();
|
||||
count_paths_recursive("start", &paths, &HashMap::from([("start", 2)]), allow_twice)
|
||||
}
|
||||
|
||||
fn count_paths_recursive(
|
||||
root: &str,
|
||||
paths: &[CavePath],
|
||||
visited: &HashMap<&str, usize>,
|
||||
allow_twice: bool,
|
||||
) -> usize {
|
||||
if root == "end" {
|
||||
return 1;
|
||||
}
|
||||
|
||||
let mut new_visited = visited.clone();
|
||||
if is_small_cave(root) {
|
||||
let counter = new_visited.entry(root).or_insert(0);
|
||||
*counter += 1;
|
||||
}
|
||||
|
||||
let mut sum = 0;
|
||||
for path in paths {
|
||||
if let Some(cave) = path.from(root) {
|
||||
let visited_count = visited.get(cave);
|
||||
let is_twice = allow_twice && is_small_cave(cave) && visited_count == Some(&1);
|
||||
if visited_count.is_none() || is_twice {
|
||||
sum += count_paths_recursive(cave, paths, &new_visited, allow_twice && !is_twice);
|
||||
}
|
||||
}
|
||||
}
|
||||
sum
|
||||
}
|
||||
|
||||
fn main() {
|
||||
const INPUT: &str = include_str!("../inputs/day12.txt");
|
||||
println!("solution {}", count_paths(INPUT, false));
|
||||
println!("solution {}", count_paths(INPUT, true));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_count_single_paths() {
|
||||
const INPUT: &str = "start-A
|
||||
start-b
|
||||
A-c
|
||||
A-b
|
||||
b-d
|
||||
A-end
|
||||
b-end";
|
||||
assert_eq!(count_paths(INPUT, false), 10);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_count_double_paths() {
|
||||
const INPUT: &str = "start-A
|
||||
start-b
|
||||
A-c
|
||||
A-b
|
||||
b-d
|
||||
A-end
|
||||
b-end";
|
||||
assert_eq!(count_paths(INPUT, true), 36);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_count_larger_single_paths() {
|
||||
const INPUT: &str = "fs-end
|
||||
he-DX
|
||||
fs-he
|
||||
start-DX
|
||||
pj-DX
|
||||
end-zg
|
||||
zg-sl
|
||||
zg-pj
|
||||
pj-he
|
||||
RW-he
|
||||
fs-DX
|
||||
pj-RW
|
||||
zg-RW
|
||||
start-pj
|
||||
he-WI
|
||||
zg-he
|
||||
pj-fs
|
||||
start-RW";
|
||||
assert_eq!(count_paths(INPUT, false), 226);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_count_larger_double_paths() {
|
||||
const INPUT: &str = "fs-end
|
||||
he-DX
|
||||
fs-he
|
||||
start-DX
|
||||
pj-DX
|
||||
end-zg
|
||||
zg-sl
|
||||
zg-pj
|
||||
pj-he
|
||||
RW-he
|
||||
fs-DX
|
||||
pj-RW
|
||||
zg-RW
|
||||
start-pj
|
||||
he-WI
|
||||
zg-he
|
||||
pj-fs
|
||||
start-RW";
|
||||
assert_eq!(count_paths(INPUT, true), 3509);
|
||||
}
|
Loading…
Reference in New Issue
Block a user