|
| 1 | +//! # Reactor |
| 2 | +use crate::util::hash::*; |
| 3 | + |
| 4 | +type Input<'a> = FastMap<&'a str, Vec<&'a str>>; |
| 5 | + |
| 6 | +pub fn parse(input: &str) -> Input<'_> { |
| 7 | + let mut graph = FastMap::new(); |
| 8 | + |
| 9 | + for line in input.lines() { |
| 10 | + let mut tokens: Vec<_> = line.split_ascii_whitespace().collect(); |
| 11 | + let first = tokens.remove(0); |
| 12 | + let key = &first[0..first.len() - 1]; |
| 13 | + graph.insert(key, tokens); |
| 14 | + } |
| 15 | + |
| 16 | + graph |
| 17 | +} |
| 18 | + |
| 19 | +pub fn part1(input: &Input<'_>) -> u64 { |
| 20 | + dfs(input, &mut FastMap::new(), "you", "out") |
| 21 | +} |
| 22 | + |
| 23 | +pub fn part2(input: &Input<'_>) -> u64 { |
| 24 | + let first = dfs(input, &mut FastMap::new(), "svr", "fft") |
| 25 | + * dfs(input, &mut FastMap::new(), "fft", "dac") |
| 26 | + * dfs(input, &mut FastMap::new(), "dac", "out"); |
| 27 | + let second = dfs(input, &mut FastMap::new(), "svr", "dac") |
| 28 | + * dfs(input, &mut FastMap::new(), "dac", "fft") |
| 29 | + * dfs(input, &mut FastMap::new(), "fft", "out"); |
| 30 | + first + second |
| 31 | +} |
| 32 | + |
| 33 | +fn dfs<'a>(graph: &Input<'a>, cache: &mut FastMap<&'a str, u64>, node: &'a str, end: &str) -> u64 { |
| 34 | + if node == end { |
| 35 | + 1 |
| 36 | + } else if node == "out" { |
| 37 | + 0 |
| 38 | + } else if let Some(&previous) = cache.get(&node) { |
| 39 | + previous |
| 40 | + } else { |
| 41 | + let result = graph[&node].iter().map(|&next| dfs(graph, cache, next, end)).sum(); |
| 42 | + cache.insert(node, result); |
| 43 | + result |
| 44 | + } |
| 45 | +} |
0 commit comments