Sub-optimal recursive solution

This commit is contained in:
Arne Keller 2021-03-13 11:11:40 +01:00
commit 56752a11d4
5 changed files with 126 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

5
Cargo.lock generated Normal file
View File

@ -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"

9
Cargo.toml Normal file
View File

@ -0,0 +1,9 @@
[package]
name = "kv"
version = "0.0.1"
authors = ["Arne Keller <arne.keller@posteo.de>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]

101
src/lib.rs Normal file
View File

@ -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<usize> for Output {
fn from(x: usize) -> Self {
match x {
0 => Zero,
1 => One,
_ => todo!()
}
}
}
pub type FunctionSpec = Vec<Output>;
pub fn find_groups(func: &FunctionSpec, vars: &mut [Variable], typ: Output) -> Vec<Vec<(Variable, Output)>> {
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<Vec<(Variable, Output)>> {
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
}

10
src/main.rs Normal file
View File

@ -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);
}
}