this post was submitted on 23 Dec 2024
14 points (88.9% liked)

Advent Of Code

920 readers
1 users here now

An unofficial home for the advent of code community on programming.dev!

Advent of Code is an annual Advent calendar of small programming puzzles for a variety of skill sets and skill levels that can be solved in any programming language you like.

AoC 2024

Solution Threads

M T W T F S S
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25

Rules/Guidelines

Relevant Communities

Relevant Links

Credits

Icon base by Lorc under CC BY 3.0 with modifications to add a gradient

console.log('Hello World')

founded 1 year ago
MODERATORS
 

Day 23: LAN Party

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

you are viewing a single comment's thread
view the rest of the comments
[โ€“] [email protected] 2 points 3 weeks ago* (last edited 3 weeks ago)

Rust

Part2 works, and is fast enough, but still feels kinda gross. No idea if this is a known algorithm or not.

Edit: Having looked at the Bron-Kerbosch wiki page, I have no idea how that works, and its way too much math for me. I'm more happy with my result now :D

Edit2: Because the code is messy, i'll try summarise pt2 here:

  • From pt1, I already have a list of all nodes and their peers.
  • For each node, I then have the potential network.
    • For each node in the potential network, count the links to the other network nodes.
    • Filter network to the N nodes with at least N-1 peers

Presumably this is a known algorithm, and I just naively ran into it. I don't think it can fail, but maybe on some more exotic graphs? Might not scale well either, but given the networks are small, its probably okay here?

#[cfg(test)]
mod tests {
    use std::collections::HashMap;

    #[test]
    fn day23_part1_test() {
        let input = std::fs::read_to_string("src/input/day_23.txt").unwrap();
        let links = input
            .lines()
            .map(|l| l.split_once('-').unwrap())
            .collect::<Vec<(&str, &str)>>();

        let mut peer_map = HashMap::new();

        for pair in links {
            peer_map.entry(pair.0).or_insert(Vec::new()).push(pair.1);
            peer_map.entry(pair.1).or_insert(Vec::new()).push(pair.0);
        }

        let mut rings = vec![];
        for (pc, peers) in &peer_map {
            if !pc.starts_with('t') {
                continue;
            }
            for (i, first) in peers.iter().enumerate() {
                for second in peers[i..].iter() {
                    if first == second {
                        continue;
                    }
                    if !peer_map.get(first).unwrap().contains(second) {
                        continue;
                    }
                    let mut set = vec![pc, second, first];
                    set.sort();
                    if !rings.contains(&set) {
                        rings.push(set);
                    }
                }
            }
        }

        println!("{}", rings.len());
    }

    #[test]
    fn day23_part2_test() {
        let input = std::fs::read_to_string("src/input/day_23.txt").unwrap();
        let links = input
            .lines()
            .map(|l| l.split_once('-').unwrap())
            .collect::<Vec<(&str, &str)>>();

        let mut peer_map = HashMap::new();

        for pair in links {
            let p1 = peer_map.entry(pair.0).or_insert(Vec::new());
            if !p1.contains(&pair.1) {
                p1.push(pair.1);
            }
            let p2 = peer_map.entry(pair.1).or_insert(Vec::new());
            if !p2.contains(&pair.0) {
                p2.push(pair.0);
            }
        }

        let mut biggest_network = String::new();

        for (pc, peers) in &peer_map {
            let mut network = HashMap::new();
            network.insert(pc, peers.len());

            for first in peers {
                let mut total = 1;
                for second in peers.iter() {
                    if first == second {
                        continue;
                    }
                    if peer_map.get(first).unwrap().contains(second) {
                        total += 1;
                    }
                }
                network.insert(first, total);
            }

            let mut network_size = peers.len();
            loop {
                if network_size == 0 {
                    break;
                }
                let mut out = network
                    .iter()
                    .filter_map(|(k, v)| {
                        if v >= &network_size {
                            return Some(**k);
                        }
                        None
                    })
                    .collect::<Vec<_>>();
                if out.len() == network_size + 1 {
                    out.sort();
                    let pw = out.join(",");
                    // println!("{}", pw);
                    if pw.len() > biggest_network.len() {
                        biggest_network = pw;
                    }
                    break;
                }

                network_size -= 1;
            }
        }

        println!("{}", biggest_network);
    }
}