From 56752a11d4b0b3bec73096b417d4be8627ed46ea Mon Sep 17 00:00:00 2001 From: Arne Keller Date: Sat, 13 Mar 2021 11:11:40 +0100 Subject: [PATCH] Sub-optimal recursive solution --- .gitignore | 1 + Cargo.lock | 5 +++ Cargo.toml | 9 +++++ src/lib.rs | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 10 ++++++ 5 files changed, 126 insertions(+) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/lib.rs create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..da6aa0e --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,5 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "kv" +version = "0.0.1" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..581c07e --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "kv" +version = "0.0.1" +authors = ["Arne Keller "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..a490061 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,101 @@ +pub type Variable = usize; + +pub const A: Variable = 1 << 0; +pub const B: Variable = 1 << 1; +pub const C: Variable = 1 << 2; + +#[derive(Clone, Copy, Debug, PartialEq, Eq)] +pub enum Output { + Zero, + One, + Any +} + +use Output::*; + +impl Output { + fn to_num(self) -> usize { + match self { + Zero => 0, + One => 1, + Any => todo!() + } + } + + fn invert(self) -> Self { + match self { + Zero => One, + One => Zero, + Any => Any + } + } +} + +impl From for Output { + fn from(x: usize) -> Self { + match x { + 0 => Zero, + 1 => One, + _ => todo!() + } + } +} + +pub type FunctionSpec = Vec; + +pub fn find_groups(func: &FunctionSpec, vars: &mut [Variable], typ: Output) -> Vec> { + find_recursive(func, vars, typ, vec![], 0, !0) +} + +fn find_recursive(func: &FunctionSpec, vars: &mut [Variable], typ: Output, set: Vec<(Variable, Output)>, mask: Variable, inv_mask: Variable) -> Vec> { + let mut groups = Vec::new(); + for i in 0..vars.len() { + let var = vars[i]; + if var == 0 { + continue; // already set + } + let mut fits_var_1 = true; + let mut fits_var_0 = true; + for input in 0..func.len() { + if !(input & inv_mask == input && input | mask == input) { + continue; + } + if input & var != 0 { + if func[input] == typ.invert() { + fits_var_1 = false; + } + } else { + if func[input] == typ.invert() { + fits_var_0 = false; + } + } + if !fits_var_0 && !fits_var_1 { + break; + } + } + if fits_var_1 { + let mut new_group = set.clone(); + new_group.push((var, One)); + groups.push(new_group); + } else { + let mut set2 = set.clone(); + set2.push((var, One)); + vars[i] = 0; + groups.extend(find_recursive(func, vars, typ, set2, mask | var, inv_mask)); + vars[i] = var; + } + + if fits_var_0 { + let mut new_group = set.clone(); + new_group.push((var, Zero)); + groups.push(new_group); + } else { + let mut set2 = set.clone(); + set2.push((var, Zero)); + vars[i] = 0; + groups.extend(find_recursive(func, vars, typ, set2, mask, inv_mask ^ var)); + vars[i] = var; + } + } + groups +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..8110cdf --- /dev/null +++ b/src/main.rs @@ -0,0 +1,10 @@ +use kv::*; +use kv::Output::*; + +fn main() { + let function = vec![0, 0, 1, 0, 0, 1, 1, 1].into_iter().map(Into::into).collect(); + let groups = find_groups(&function, &mut [A, B, C], Zero); + for x in groups { + println!("{:?}", x); + } +}