diff options
Diffstat (limited to '2021/day12')
-rw-r--r-- | 2021/day12/Cargo.toml | 9 | ||||
-rw-r--r-- | 2021/day12/resources/input.txt | 21 | ||||
-rw-r--r-- | 2021/day12/src/main.rs | 54 |
3 files changed, 84 insertions, 0 deletions
diff --git a/2021/day12/Cargo.toml b/2021/day12/Cargo.toml new file mode 100644 index 0000000..d1c136c --- /dev/null +++ b/2021/day12/Cargo.toml | |||
@@ -0,0 +1,9 @@ | |||
1 | [package] | ||
2 | name = "day12" | ||
3 | version = "0.1.0" | ||
4 | authors = ["Federico Igne <git@federicoigne.com>"] | ||
5 | edition = "2018" | ||
6 | |||
7 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
8 | |||
9 | [dependencies] | ||
diff --git a/2021/day12/resources/input.txt b/2021/day12/resources/input.txt new file mode 100644 index 0000000..5a75dd8 --- /dev/null +++ b/2021/day12/resources/input.txt | |||
@@ -0,0 +1,21 @@ | |||
1 | mx-IQ | ||
2 | mx-HO | ||
3 | xq-start | ||
4 | start-HO | ||
5 | IE-qc | ||
6 | HO-end | ||
7 | oz-xq | ||
8 | HO-ni | ||
9 | ni-oz | ||
10 | ni-MU | ||
11 | sa-IE | ||
12 | IE-ni | ||
13 | end-sa | ||
14 | oz-sa | ||
15 | MU-start | ||
16 | MU-sa | ||
17 | oz-IE | ||
18 | HO-xq | ||
19 | MU-xq | ||
20 | IE-end | ||
21 | MU-mx | ||
diff --git a/2021/day12/src/main.rs b/2021/day12/src/main.rs new file mode 100644 index 0000000..504a97a --- /dev/null +++ b/2021/day12/src/main.rs | |||
@@ -0,0 +1,54 @@ | |||
1 | use std::fs; | ||
2 | use std::path::Path; | ||
3 | use std::collections::HashMap; | ||
4 | |||
5 | /* AOC21 Day 12: https://adventofcode.com/2021/day/12 */ | ||
6 | fn main() { | ||
7 | let input = Path::new("resources").join("input.txt"); | ||
8 | let content = fs::read_to_string(input).expect("Unable to read input file"); | ||
9 | let mut adj = HashMap::<&str,Vec<&str>>::new(); | ||
10 | content.lines() | ||
11 | .map(|l| l.split_once('-').expect("Malformed input")) | ||
12 | .for_each(|(from,to)| { | ||
13 | adj.entry(from).or_default().push(to); | ||
14 | adj.entry(to).or_default().push(from); | ||
15 | }); | ||
16 | println!("Ex1: the result is {}", genpath(&mut vec!["start"], &adj)); | ||
17 | println!("Ex2: the result is {}", genpath_rep(&mut vec!["start"], &adj)); | ||
18 | } | ||
19 | |||
20 | fn genpath<'a>(path: &mut Vec<&'a str>, adj: &HashMap<&str,Vec<&'a str>>) -> u32 { | ||
21 | let last = path.last().unwrap(); | ||
22 | if *last == "end" { 1 } else { | ||
23 | let mut paths = 0; | ||
24 | if let Some(vec) = adj.get(last) { | ||
25 | let next: Vec<&str> = vec.iter().filter(|n| n.chars().all(|c| c.is_uppercase()) || !path.contains(&n)).cloned().collect(); | ||
26 | for n in next { | ||
27 | path.push(n); | ||
28 | paths += genpath(path, adj); | ||
29 | path.pop(); | ||
30 | } | ||
31 | } | ||
32 | paths | ||
33 | } | ||
34 | } | ||
35 | |||
36 | fn genpath_rep<'a>(path: &mut Vec<&'a str>, adj: &HashMap<&str,Vec<&'a str>>) -> u32 { | ||
37 | let last = path.last().unwrap(); | ||
38 | if *last == "end" { 1 } else { | ||
39 | let mut paths = 0; | ||
40 | if let Some(vec) = adj.get(last) { | ||
41 | for n in vec.iter().filter(|&n| *n != "start") { | ||
42 | if n.chars().all(|c| c.is_lowercase()) && path.contains(n) { | ||
43 | path.push(n); | ||
44 | paths += genpath(path, adj); | ||
45 | } else { | ||
46 | path.push(n); | ||
47 | paths += genpath_rep(path, adj); | ||
48 | } | ||
49 | path.pop(); | ||
50 | } | ||
51 | } | ||
52 | paths | ||
53 | } | ||
54 | } | ||