diff options
author | Federico Igne <git@federicoigne.com> | 2021-12-17 15:45:14 +0000 |
---|---|---|
committer | Federico Igne <git@federicoigne.com> | 2021-12-17 15:45:14 +0000 |
commit | caadd3b46c95caf433881ea9a1cd2e98c87f5e56 (patch) | |
tree | c0cae1533ba2a7ed511b74b4cef5a89a56778898 | |
parent | cce9b6e60d5f70078d6fc608636201a7934418e1 (diff) | |
download | aoc-caadd3b46c95caf433881ea9a1cd2e98c87f5e56.tar.gz aoc-caadd3b46c95caf433881ea9a1cd2e98c87f5e56.zip |
Day 14
-rw-r--r-- | day14/Cargo.toml | 9 | ||||
-rw-r--r-- | day14/resources/input.txt | 102 | ||||
-rw-r--r-- | day14/src/main.rs | 55 |
3 files changed, 166 insertions, 0 deletions
diff --git a/day14/Cargo.toml b/day14/Cargo.toml new file mode 100644 index 0000000..d2891da --- /dev/null +++ b/day14/Cargo.toml | |||
@@ -0,0 +1,9 @@ | |||
1 | [package] | ||
2 | name = "day14" | ||
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/day14/resources/input.txt b/day14/resources/input.txt new file mode 100644 index 0000000..5074877 --- /dev/null +++ b/day14/resources/input.txt | |||
@@ -0,0 +1,102 @@ | |||
1 | SCVHKHVSHPVCNBKBPVHV | ||
2 | |||
3 | SB -> B | ||
4 | HH -> P | ||
5 | VF -> N | ||
6 | BS -> S | ||
7 | NC -> C | ||
8 | BF -> H | ||
9 | BN -> H | ||
10 | SP -> H | ||
11 | BK -> H | ||
12 | FF -> N | ||
13 | VN -> B | ||
14 | FN -> C | ||
15 | FS -> S | ||
16 | PP -> F | ||
17 | ON -> H | ||
18 | FV -> F | ||
19 | KO -> F | ||
20 | PK -> H | ||
21 | VB -> S | ||
22 | HS -> B | ||
23 | NV -> O | ||
24 | PN -> S | ||
25 | VH -> B | ||
26 | OS -> P | ||
27 | BP -> H | ||
28 | OV -> B | ||
29 | HK -> S | ||
30 | NN -> K | ||
31 | SV -> C | ||
32 | PB -> F | ||
33 | SK -> F | ||
34 | FB -> S | ||
35 | NB -> K | ||
36 | HF -> P | ||
37 | FK -> K | ||
38 | KV -> P | ||
39 | PV -> F | ||
40 | BC -> S | ||
41 | FO -> N | ||
42 | HC -> F | ||
43 | CP -> B | ||
44 | KK -> F | ||
45 | PC -> S | ||
46 | HN -> O | ||
47 | SH -> H | ||
48 | CK -> P | ||
49 | CO -> F | ||
50 | HP -> K | ||
51 | PS -> C | ||
52 | KP -> F | ||
53 | OF -> K | ||
54 | KS -> F | ||
55 | NO -> V | ||
56 | CB -> K | ||
57 | NF -> N | ||
58 | SF -> F | ||
59 | SC -> P | ||
60 | FC -> V | ||
61 | BV -> B | ||
62 | SS -> O | ||
63 | KC -> K | ||
64 | FH -> C | ||
65 | OP -> C | ||
66 | CF -> K | ||
67 | VO -> V | ||
68 | VK -> H | ||
69 | KH -> O | ||
70 | NP -> V | ||
71 | NH -> O | ||
72 | NS -> V | ||
73 | BH -> C | ||
74 | CH -> S | ||
75 | CC -> F | ||
76 | CS -> P | ||
77 | SN -> F | ||
78 | BO -> S | ||
79 | NK -> S | ||
80 | OO -> P | ||
81 | VV -> F | ||
82 | FP -> V | ||
83 | OK -> C | ||
84 | SO -> H | ||
85 | KN -> P | ||
86 | HO -> O | ||
87 | PO -> H | ||
88 | VS -> N | ||
89 | PF -> N | ||
90 | CV -> F | ||
91 | BB -> H | ||
92 | VC -> H | ||
93 | HV -> B | ||
94 | CN -> S | ||
95 | OH -> K | ||
96 | KF -> K | ||
97 | HB -> S | ||
98 | OC -> H | ||
99 | KB -> P | ||
100 | OB -> C | ||
101 | VP -> C | ||
102 | PH -> K | ||
diff --git a/day14/src/main.rs b/day14/src/main.rs new file mode 100644 index 0000000..6cca304 --- /dev/null +++ b/day14/src/main.rs | |||
@@ -0,0 +1,55 @@ | |||
1 | use std::fs; | ||
2 | use std::path::Path; | ||
3 | use std::collections::HashMap; | ||
4 | use std::iter::FromIterator; | ||
5 | |||
6 | type Expand = (char,char); | ||
7 | type Rules = HashMap<(char,char),char>; | ||
8 | type Frequency = HashMap<char,u128>; | ||
9 | type FrequencyMap = HashMap<Expand,Frequency>; | ||
10 | |||
11 | /* AOC21 Day 14: https://adventofcode.com/2021/day/14 */ | ||
12 | fn main() { | ||
13 | let input = Path::new("resources").join("input.txt"); | ||
14 | let content = fs::read_to_string(input).expect("Unable to read input file"); | ||
15 | let (template,rules) = content.split_once("\n\n").expect("Malformed input"); | ||
16 | let rules = Rules::from_iter(rules.lines().map(|l| { | ||
17 | let (from,to) = l.split_once(" -> ").expect("Malformed input"); | ||
18 | let chars = from.chars().collect::<Vec<char>>(); | ||
19 | ((chars[0],chars[1]),to.parse().unwrap()) | ||
20 | })); | ||
21 | let mut frequency = FrequencyMap::new(); | ||
22 | rules.iter().for_each(|(&(a,b),&c)| { | ||
23 | let mut map = HashMap::new(); map.insert(c,1); | ||
24 | frequency.insert((a,b),map); | ||
25 | }); | ||
26 | (1..10).for_each(|_| frequency = expand(&frequency, &rules)); | ||
27 | println!("Ex1: the result is {}", template_frequency(template, &frequency)); | ||
28 | (0..30).for_each(|_| frequency = expand(&frequency, &rules)); | ||
29 | println!("Ex2: the result is {}", template_frequency(template, &frequency)); | ||
30 | } | ||
31 | |||
32 | fn expand(frequency: &FrequencyMap, rules: &Rules) -> FrequencyMap { | ||
33 | let mut freq2 = FrequencyMap::new(); | ||
34 | rules.iter().for_each(|(&(a,b),&c)| { | ||
35 | let mut map = merge(frequency.get(&(a,c)).unwrap(), frequency.get(&(c,b)).unwrap()); | ||
36 | *map.entry(c).or_default() += 1; | ||
37 | *freq2.entry((a,b)).or_default() = map; | ||
38 | }); | ||
39 | freq2 | ||
40 | } | ||
41 | |||
42 | fn template_frequency(template: &str, frequency: &FrequencyMap) -> u128 { | ||
43 | let mut freq = HashMap::new(); | ||
44 | template.chars().for_each(|c| *freq.entry(c).or_default() += 1); | ||
45 | freq = template.chars().collect::<Vec<char>>() | ||
46 | .as_slice().windows(2) | ||
47 | .fold(freq, |acc, w| merge(&acc, frequency.get(&(w[0],w[1])).unwrap()) ); | ||
48 | freq.values().max().unwrap() - freq.values().min().unwrap() | ||
49 | } | ||
50 | |||
51 | fn merge(a: &Frequency, b: &Frequency) -> Frequency { | ||
52 | let mut map = a.clone(); | ||
53 | b.iter().for_each(|(&k,&v)| *map.entry(k).or_default() += v); | ||
54 | map | ||
55 | } | ||