Day 11: Reactor

Megathread guidelines

  • Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
  • You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL

FAQ

  • EnEnCode@programming.dev
    link
    fedilink
    English
    arrow-up
    1
    ·
    3 days ago

    Rust

    Somehow got the right answer for part 1 iteratively, but it wasn’t actually correct at all, so switched to the standard recursion + memoisation. Gotta love just chucking an iterator into the value type of a HashMap and going BRRRR (1.2 ms).

    solution
    pub fn day11(input: &str) -> (u64, u64) {
        let array = input.trim().lines();
        let mut conns = HashMap::new();
        for line in array {
            let mut iter = line.split_whitespace();
            conns.insert(&iter.next().unwrap()[0..3], iter);
        }
    
        fn find_path<'a>(
            start: &'a str,
            end: &'a str,
            conns: &HashMap<&'a str, SplitWhitespace<'a>>,
            devices: &mut HashMap<&'a str, u64>,
        ) -> u64 {
            let mut sum = 0;
            let Some(list) = conns.get(start) else {
                return 0;
            };
            for i in list.clone() {
                if i == end {
                    sum += 1;
                } else if let Some(precomp) = devices.get(i) {
                    sum += precomp;
                } else {
                    sum += find_path(i, end, conns, devices);
                }
            }
            devices.insert(start, sum);
            sum
        }
    
        let part1 = find_path("you", "out", &conns, &mut HashMap::new());
        // If dac -> fft and fft -> dac are both non-zero, then there are loops. That makes an
        // infinite number of paths so the question posed would be meaningless.
        let dac_to_fft = find_path("dac", "fft", &conns, &mut HashMap::new());
        let part2 = if dac_to_fft == 0 {
            find_path("svr", "fft", &conns, &mut HashMap::new())
                * find_path("fft", "dac", &conns, &mut HashMap::new())
                * find_path("dac", "out", &conns, &mut HashMap::new())
        } else {
            find_path("svr", "dac", &conns, &mut HashMap::new())
                * dac_to_fft
                * find_path("fft", "out", &conns, &mut HashMap::new())
        };
        (part1, part2)
    }