day25
This commit is contained in:
120
src/day25.rs
Normal file
120
src/day25.rs
Normal file
@@ -0,0 +1,120 @@
|
||||
use std::collections::{HashSet, HashMap};
|
||||
use rand::Rng;
|
||||
|
||||
use aoc_runner_derive::{aoc, aoc_generator};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct Graph {
|
||||
edges: Vec<(String, String)>,
|
||||
vertex_count: usize
|
||||
}
|
||||
|
||||
impl Graph {
|
||||
fn cut(&mut self) -> (usize, usize, usize) {
|
||||
let mut contracted_edges = self.edges.clone();
|
||||
let mut contracted_vertex_count = self.vertex_count;
|
||||
let mut contracted: HashMap<String, Vec<String>> = HashMap::new();
|
||||
|
||||
//for _ in 0..contracted_vertex_count {
|
||||
while contracted_vertex_count > 2 {
|
||||
let random = rand::thread_rng().gen_range(0..contracted_edges.len());
|
||||
let edge_to_contract = contracted_edges[random].clone();
|
||||
if contracted.contains_key(&edge_to_contract.0) {
|
||||
contracted.get_mut(&edge_to_contract.0.clone()).unwrap().push(edge_to_contract.1.clone());
|
||||
} else {
|
||||
contracted.insert(edge_to_contract.0.clone(), vec![edge_to_contract.1.clone()]);
|
||||
}
|
||||
|
||||
if contracted.contains_key(&edge_to_contract.1) {
|
||||
let mut to_append = contracted.clone().get_mut(&edge_to_contract.1).unwrap().clone();
|
||||
contracted.get_mut(&edge_to_contract.0).unwrap().append(&mut to_append);
|
||||
contracted.remove(&edge_to_contract.1);
|
||||
}
|
||||
|
||||
let mut new_edges: Vec<(String, String)> = vec![];
|
||||
|
||||
for edge in contracted_edges {
|
||||
if edge.1 == edge_to_contract.1 {
|
||||
new_edges.push((edge.0.clone(), edge_to_contract.0.clone()));
|
||||
} else if edge.0 == edge_to_contract.1 {
|
||||
new_edges.push((edge_to_contract.0.clone(), edge.1.clone()));
|
||||
} else {
|
||||
new_edges.push(edge.clone());
|
||||
}
|
||||
}
|
||||
|
||||
let tmp = new_edges.iter().cloned().filter(|x| x.0 != x.1).collect::<Vec<_>>();
|
||||
|
||||
contracted_edges = tmp;
|
||||
contracted_vertex_count -= 1;
|
||||
|
||||
}
|
||||
|
||||
let counts = contracted.iter().map(|x| x.1.len() + 1).collect::<Vec<_>>();
|
||||
|
||||
return (contracted_edges.len(), counts[0], *counts.last().unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
#[aoc_generator(day25)]
|
||||
fn parse(input: &str) -> Graph {
|
||||
let input = input.lines().flat_map(|line| {
|
||||
let line = line.split(' ').map(|x| x.trim_end_matches(':').to_string()).collect::<Vec<_>>();
|
||||
line[1..].iter().cloned().map(|x| (line[0].clone(), x)).collect::<Vec<_>>()
|
||||
}).collect::<Vec<_>>();
|
||||
|
||||
let vertex_count = input.clone().into_iter().flat_map(|x| vec![x.0, x.1]).collect::<HashSet<_>>().len();
|
||||
Graph {
|
||||
edges: input,
|
||||
vertex_count
|
||||
}
|
||||
}
|
||||
|
||||
#[aoc(day25, part1)]
|
||||
fn part1(graph: &Graph) -> usize {
|
||||
let graph = &mut graph.clone();
|
||||
let mut min_cut = usize::MAX;
|
||||
let mut count1 = 0;
|
||||
let mut count2 = 0;
|
||||
|
||||
while min_cut != 3 {
|
||||
(min_cut, count1, count2) = graph.cut();
|
||||
}
|
||||
|
||||
count1 * count2
|
||||
}
|
||||
|
||||
// #[aoc(day25, part2)]
|
||||
// fn part2(input: &str) -> String {
|
||||
// todo!()
|
||||
// }
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
const EX: &str = r"jqt: rhn xhk nvd
|
||||
rsh: frs pzl lsr
|
||||
xhk: hfx
|
||||
cmg: qnr nvd lhk bvb
|
||||
rhn: xhk bvb hfx
|
||||
bvb: xhk hfx
|
||||
pzl: lsr hfx nvd
|
||||
qnr: nvd
|
||||
ntq: jqt hfx bvb xhk
|
||||
nvd: lhk
|
||||
lsr: lhk
|
||||
rzs: qnr cmg lsr rsh
|
||||
frs: qnr lhk lsr";
|
||||
|
||||
#[test]
|
||||
fn part1_example() {
|
||||
assert_eq!(part1(&parse(EX)), 54);
|
||||
}
|
||||
|
||||
// #[test]
|
||||
// fn part2_example() {
|
||||
// assert_eq!(part2(&parse("<EXAMPLE>")), "<RESULT>");
|
||||
// }
|
||||
}
|
@@ -1,3 +1,4 @@
|
||||
mod day25;
|
||||
mod day24;
|
||||
mod day23;
|
||||
mod day22;
|
||||
|
Reference in New Issue
Block a user