Skip to content

Commit

Permalink
Complete day 25
Browse files Browse the repository at this point in the history
  • Loading branch information
Riari committed Dec 26, 2023
1 parent 2b2fb37 commit e532ac2
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 1 deletion.
54 changes: 54 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,5 @@ regex = "1.10.2"
num = "0.4.1"
itertools = "0.12.0"
colored = "2.1.0"
z3 = "0.12"
rand = "0.8.5"
z3 = "0.12" # only works on Linux
13 changes: 13 additions & 0 deletions data/examples/25.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
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
97 changes: 97 additions & 0 deletions src/bin/25.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
use std::collections::{HashMap, HashSet};

advent_of_code::solution!(25);

type Graph = HashMap<String, Vec<String>>;

fn parse(input: &str) -> Graph {
let mut graph: Graph = HashMap::new();
for line in input.lines() {
let mut parts = line.split(": ");
let key = parts.next().unwrap();
let values: Vec<String> = parts
.next()
.unwrap()
.split_whitespace()
.map(|s| s.to_string())
.collect();

for value in &values {
graph
.entry(value.clone())
.or_insert(vec![])
.push(key.to_string());
graph
.entry(key.to_string())
.or_insert(vec![])
.push(value.clone());
}
}

graph
}

fn find_left_size(graph: &Graph) -> u32 {
let start = graph.keys().next().unwrap();
let mut component = HashSet::from([start.to_string()]);

let mut middle_edges = graph[start]
.iter()
.map(|end| (start.to_string(), end.to_string()))
.collect::<HashSet<_>>();

while middle_edges.len() > 3 {
let next = middle_edges
.iter()
.cloned()
.map(|(_start, end)| end)
.min_by_key(|end| {
graph[end]
.iter()
.filter(|node| !component.contains(*node))
.count()
})
.unwrap();

component.insert(next.to_string());

for neighbour in &graph[&next] {
if component.contains(neighbour) {
middle_edges.remove(&(neighbour.to_string(), next.to_string()));
} else {
middle_edges.insert((next.to_string(), neighbour.to_string()));
}
}
}

component.len() as u32
}

pub fn part_one(input: &str) -> Option<u32> {
let graph = parse(input);

let left_size = find_left_size(&graph);

Some(left_size * (graph.len() as u32 - left_size))
}

pub fn part_two(_: &str) -> Option<u32> {
None
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn test_part_one() {
let result = part_one(&advent_of_code::template::read_file("examples", DAY));
assert_eq!(result, Some(54));
}

#[test]
fn test_part_two() {
let result = part_two(&advent_of_code::template::read_file("examples", DAY));
assert_eq!(result, None);
}
}

0 comments on commit e532ac2

Please sign in to comment.