done with 2023

This commit is contained in:
Dylan Thies
2023-12-28 20:26:01 -05:00
parent e034f6b859
commit c05ab694ab
6 changed files with 354 additions and 27 deletions

14
2023/day-25/Cargo.toml Normal file
View 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
View 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
View 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
View 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
View 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());
}
}