diff options
Diffstat (limited to 'day14/src/main.rs')
-rw-r--r-- | day14/src/main.rs | 55 |
1 files changed, 55 insertions, 0 deletions
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 | } | ||