From 9d135c2f25a5ff2b724e9eb23789b72142dc457f Mon Sep 17 00:00:00 2001 From: Marc-Antoine Manningham <marc-antoine.m@outlook.com> Date: Fri, 13 Sep 2024 22:39:16 -0400 Subject: [PATCH] feat: initial commit for an university generic engine --- combinatoric-solver/Cargo.lock | 7 +++ combinatoric-solver/Cargo.toml | 6 +++ combinatoric-solver/src/collection.rs | 67 +++++++++++++++++++++++++++ combinatoric-solver/src/item.rs | 6 +++ combinatoric-solver/src/lib.rs | 6 +++ combinatoric-solver/src/score.rs | 1 + combinatoric-solver/src/solver.rs | 56 ++++++++++++++++++++++ 7 files changed, 149 insertions(+) create mode 100644 combinatoric-solver/Cargo.lock create mode 100644 combinatoric-solver/Cargo.toml create mode 100644 combinatoric-solver/src/collection.rs create mode 100644 combinatoric-solver/src/item.rs create mode 100644 combinatoric-solver/src/lib.rs create mode 100644 combinatoric-solver/src/score.rs create mode 100644 combinatoric-solver/src/solver.rs diff --git a/combinatoric-solver/Cargo.lock b/combinatoric-solver/Cargo.lock new file mode 100644 index 0000000..d5d26d1 --- /dev/null +++ b/combinatoric-solver/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "combinatoric-solver" +version = "0.1.0" diff --git a/combinatoric-solver/Cargo.toml b/combinatoric-solver/Cargo.toml new file mode 100644 index 0000000..cd0e860 --- /dev/null +++ b/combinatoric-solver/Cargo.toml @@ -0,0 +1,6 @@ +[package] +name = "combinatoric-solver" +version = "0.1.0" +edition = "2021" + +[dependencies] diff --git a/combinatoric-solver/src/collection.rs b/combinatoric-solver/src/collection.rs new file mode 100644 index 0000000..f16919c --- /dev/null +++ b/combinatoric-solver/src/collection.rs @@ -0,0 +1,67 @@ +use crate::score::Score; + +#[derive(Clone)] +pub struct Collection<const MAX_ITEMS: usize, S, ItemVariant> +where + S: Score, + ItemVariant: Eq, +{ + pub score: S, + pub item_quantity: usize, + pub item_variant: [ItemVariant; MAX_ITEMS], +} + +impl<const MAX_ITEMS: usize, S: Score, ItemVariant: Eq + Default + Copy> + Collection<MAX_ITEMS, S, ItemVariant> +{ + pub fn push(&self, item_variant: ItemVariant) -> Self { + let mut new = self.clone(); + new.item_variant[self.item_quantity] = item_variant; + new.item_quantity += 1; + new + } +} + +impl<const MAX_ITEMS: usize, S: Score, ItemVariant: Eq + Default + Copy> Default + for Collection<MAX_ITEMS, S, ItemVariant> +{ + fn default() -> Self { + let score = S::default(); + let item_quantity = 0; + let item_variant = [ItemVariant::default(); MAX_ITEMS]; + Self { + score, + item_quantity, + item_variant, + } + } +} + +impl<const MAX_ITEMS: usize, S: Score, ItemVariant: Eq> PartialEq + for Collection<MAX_ITEMS, S, ItemVariant> +{ + fn eq(&self, other: &Self) -> bool { + self.item_variant == other.item_variant + } +} + +impl<const MAX_ITEMS: usize, S: Score, ItemVariant: Eq> PartialOrd + for Collection<MAX_ITEMS, S, ItemVariant> +{ + fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> { + self.score.partial_cmp(&other.score) + } +} + +impl<const MAX_ITEMS: usize, S: Score, ItemVariant: Eq> Eq + for Collection<MAX_ITEMS, S, ItemVariant> +{ +} + +impl<const MAX_ITEMS: usize, S: Score, ItemVariant: Eq> Ord + for Collection<MAX_ITEMS, S, ItemVariant> +{ + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.score.cmp(&other.score) + } +} diff --git a/combinatoric-solver/src/item.rs b/combinatoric-solver/src/item.rs new file mode 100644 index 0000000..a37121c --- /dev/null +++ b/combinatoric-solver/src/item.rs @@ -0,0 +1,6 @@ +pub trait ItemVariant: Eq + Copy + Default {} + +pub trait CombinatoricItem { + type ItemVariant; + fn variants(&self) -> impl IntoIterator<Item = Self::ItemVariant>; +} diff --git a/combinatoric-solver/src/lib.rs b/combinatoric-solver/src/lib.rs new file mode 100644 index 0000000..8d79d25 --- /dev/null +++ b/combinatoric-solver/src/lib.rs @@ -0,0 +1,6 @@ +pub mod collection; +pub mod item; +pub mod score; +pub mod solver; + +pub use crate::solver::Solver; diff --git a/combinatoric-solver/src/score.rs b/combinatoric-solver/src/score.rs new file mode 100644 index 0000000..426175d --- /dev/null +++ b/combinatoric-solver/src/score.rs @@ -0,0 +1 @@ +pub trait Score: Ord + Default + Clone {} diff --git a/combinatoric-solver/src/solver.rs b/combinatoric-solver/src/solver.rs new file mode 100644 index 0000000..863a287 --- /dev/null +++ b/combinatoric-solver/src/solver.rs @@ -0,0 +1,56 @@ +use std::{cmp::Reverse, collections::BinaryHeap}; + +use crate::{ + collection::Collection, + item::{CombinatoricItem, ItemVariant}, + score::Score, +}; + +pub struct Solver<const MAX_ITEMS: usize, S, V, I, Parameters> +where + S: Score, + V: ItemVariant, + I: CombinatoricItem, +{ + top_items: BinaryHeap<Reverse<Collection<MAX_ITEMS, S, V>>>, + max_capacity: usize, + parameters: Parameters, + items: Vec<I>, +} + +impl<'a, const MAX_ITEMS: usize, S, V, I, Parameters> Solver<MAX_ITEMS, S, V, I, Parameters> +where + S: Score, + V: ItemVariant, + I: CombinatoricItem<ItemVariant = V>, +{ + pub fn new(max_capacity: usize, items: Vec<I>, parameters: Parameters) -> Self { + let top_items = BinaryHeap::with_capacity(max_capacity); + Self { + top_items, + max_capacity, + parameters, + items, + } + } + pub fn solve(mut self) -> Vec<I> { + let item = &self.items; + Self::rec_iter(0, Collection::default(), item, &mut self.top_items); + vec![] + } + fn rec_iter( + i: usize, + collection: Collection<MAX_ITEMS, S, V>, + items: &'a [I], + top_items: &mut BinaryHeap<Reverse<Collection<MAX_ITEMS, S, V>>>, + ) { + if i >= items.len() { + return; + } + + for variant in items[i].variants() { + let collections = collection.push(variant); + Self::rec_iter(i + 1, collections, items, top_items); + } + } +} -- GitLab