This commit is contained in:
sepia 2024-12-23 18:09:59 -06:00
parent 1aa90ba9db
commit 12fde697d3
2 changed files with 96 additions and 1 deletions

93
src/day23.rs Normal file
View File

@ -0,0 +1,93 @@
use itertools::Itertools;
use std::{
collections::{HashMap, HashSet},
fmt::{Display, Write},
};
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug, Ord, PartialOrd)]
struct Computer(char, char);
pub fn day23() {
let input_connections: Vec<(Computer, Computer)> = parse_input(&crate::input(23));
let connections = {
let mut connections: HashMap<Computer, Vec<Computer>> = HashMap::new();
for &(a, b) in input_connections.iter() {
connections.entry(a).or_insert(vec![]).push(b);
connections.entry(b).or_insert(vec![]).push(a);
}
connections
};
fn collect_cliques(
connections: &HashMap<Computer, Vec<Computer>>,
clique: &Vec<Computer>,
visited: &mut HashSet<Vec<Computer>>,
) -> Vec<Vec<Computer>> {
let mut bigger_cliques: Vec<Vec<Computer>> = vec![];
bigger_cliques.push(clique.clone());
for (computer, friends) in connections.iter() {
if clique.contains(computer) {
continue;
}
if clique.iter().all(|groupie| friends.contains(groupie)) {
let mut new_clique = clique.clone();
new_clique.push(*computer);
new_clique.sort();
if visited.contains(&new_clique) {
continue;
} else {
visited.insert(new_clique.clone());
}
let mut new_bigger_cliques = collect_cliques(connections, &new_clique, visited);
bigger_cliques.append(&mut new_bigger_cliques);
}
}
bigger_cliques
}
let mut visited = HashSet::new();
let mut all_cliques: Vec<Vec<Computer>> = connections
.keys()
.map(|&c| vec![c])
.flat_map(|seed| collect_cliques(&connections, &seed, &mut visited))
.collect();
all_cliques.sort_by_key(|group| group.len());
let mut maximum_clique = all_cliques.last().unwrap().clone();
println!("The biggest clique's size is {}.", maximum_clique.len());
maximum_clique.sort();
println!(
"The biggest clique's password is {}",
maximum_clique.iter().map(|c| format!("{c}")).join(",")
);
let t_trios = all_cliques
.iter()
.filter(|clique| clique.len() == 3)
.filter(|trio| trio.iter().any(|c| c.0 == 't'))
.count();
println!("{t_trios} trios contain a friend who starts with t.");
}
impl Computer {
fn from_string(s: &str) -> Self {
Self(s.chars().nth(0).unwrap(), s.chars().nth(1).unwrap())
}
}
impl Display for Computer {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_char(self.0)?;
f.write_char(self.1)
}
}
fn parse_input(input: &str) -> Vec<(Computer, Computer)> {
input
.lines()
.map(|line| {
line.split("-")
.map(Computer::from_string)
.collect_tuple()
.unwrap()
})
.collect()
}

View File

@ -28,7 +28,9 @@ mod day2;
mod day20;
#[allow(dead_code)]
mod day21;
#[allow(dead_code)]
mod day22;
mod day23;
#[allow(dead_code)]
mod day3;
#[allow(dead_code)]
@ -45,7 +47,7 @@ mod day8;
mod day9;
fn main() {
day22::day22();
day23::day23();
}
pub fn input(day: u8) -> String {