done with 2023
This commit is contained in:
14
2023/day-25/Cargo.toml
Normal file
14
2023/day-25/Cargo.toml
Normal file
@@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "day-25"
|
||||
version.workspace = true
|
||||
edition.workspace = true
|
||||
authors.workspace = true
|
||||
repository.workspace = true
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
nom = { workspace = true }
|
||||
itertools = {workspace = true }
|
||||
petgraph = "0.6.4"
|
||||
rustworkx-core = "0.13.2"
|
||||
4
2023/day-25/src/lib.rs
Normal file
4
2023/day-25/src/lib.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
pub mod part1;
|
||||
pub use crate::part1::*;
|
||||
pub mod part2;
|
||||
pub use crate::part2::*;
|
||||
12
2023/day-25/src/main.rs
Normal file
12
2023/day-25/src/main.rs
Normal file
@@ -0,0 +1,12 @@
|
||||
#![warn(clippy::all, clippy::pedantic)]
|
||||
|
||||
use day_25::part1;
|
||||
use day_25::part2;
|
||||
|
||||
fn main() {
|
||||
let input = include_str!("./input.txt");
|
||||
let part1_result = part1(input);
|
||||
println!("part 1: {part1_result}");
|
||||
let part2_result = part2(input);
|
||||
println!("part 2: {part2_result}");
|
||||
}
|
||||
92
2023/day-25/src/part1.rs
Normal file
92
2023/day-25/src/part1.rs
Normal file
@@ -0,0 +1,92 @@
|
||||
#![warn(clippy::all, clippy::pedantic)]
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use itertools::Itertools;
|
||||
use nom::{
|
||||
bytes::complete::tag,
|
||||
character::complete,
|
||||
multi::separated_list1,
|
||||
sequence::{separated_pair, tuple},
|
||||
IResult,
|
||||
};
|
||||
use petgraph::prelude::*;
|
||||
use rustworkx_core::connectivity::stoer_wagner_min_cut;
|
||||
|
||||
/// day 25 part 1 of aoc 2023
|
||||
///
|
||||
/// # Arguments
|
||||
/// - input the input for today's puzzle
|
||||
///
|
||||
/// # Panics
|
||||
/// panics whne it cannot parse the input OR when ever the number of game numbers is greater than
|
||||
#[must_use]
|
||||
pub fn part1(input: &str) -> String {
|
||||
let (_, initial_map) = parse_input(input).expect("AOC should have valid input");
|
||||
|
||||
let all_node_strings = initial_map
|
||||
.iter()
|
||||
.flat_map(|(key, nodes)| {
|
||||
let mut nodes = nodes.clone();
|
||||
nodes.push(key);
|
||||
nodes
|
||||
})
|
||||
.unique()
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let mut graph = UnGraph::<&str, u32>::default();
|
||||
let node_map = all_node_strings
|
||||
.iter()
|
||||
.map(|&id| (id, graph.add_node(id)))
|
||||
.collect::<HashMap<_, _>>();
|
||||
|
||||
for (&src_id, dest_nodes) in &initial_map {
|
||||
for &dest_id in dest_nodes {
|
||||
graph.add_edge(node_map[src_id], node_map[dest_id], 1);
|
||||
}
|
||||
}
|
||||
let total_nodes = all_node_strings.len();
|
||||
let min_cut_res: rustworkx_core::Result<Option<(usize, Vec<_>)>> =
|
||||
stoer_wagner_min_cut(&graph, |_| Ok(1));
|
||||
let (_mincut, partition) = min_cut_res.unwrap().unwrap();
|
||||
let partition_len = partition.len();
|
||||
let rest_len = total_nodes - partition_len;
|
||||
(partition_len * rest_len).to_string()
|
||||
}
|
||||
|
||||
fn parse_input(input: &str) -> IResult<&str, HashMap<&str, Vec<&str>>> {
|
||||
let (input, nodes_as_array) = separated_list1(
|
||||
complete::line_ending,
|
||||
separated_pair(
|
||||
complete::alpha1,
|
||||
tuple((tag(":"), complete::space0)),
|
||||
separated_list1(complete::space1, complete::alpha1),
|
||||
),
|
||||
)(input)?;
|
||||
Ok((input, nodes_as_array.into_iter().collect()))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
const INPUT: &str = "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_works() {
|
||||
let result = part1(INPUT);
|
||||
assert_eq!(result, "54".to_string());
|
||||
}
|
||||
}
|
||||
19
2023/day-25/src/part2.rs
Normal file
19
2023/day-25/src/part2.rs
Normal file
@@ -0,0 +1,19 @@
|
||||
#![warn(clippy::all, clippy::pedantic)]
|
||||
|
||||
#[must_use]
|
||||
pub fn part2(_input: &str) -> String {
|
||||
"Not Finished".to_string()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
const INPUT: &str = "";
|
||||
|
||||
#[test]
|
||||
fn part2_works() {
|
||||
let result = part2(INPUT);
|
||||
assert_eq!(result, "Not Finished".to_string());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user