From faa0608575be3d949274a60fbc4b5a0a5e9e8b70 Mon Sep 17 00:00:00 2001 From: Rushmore75 Date: Wed, 22 Oct 2025 16:17:07 -0600 Subject: [PATCH] multi out --- src/main.rs | 195 +++++++++++++++++++++++++--------------------------- 1 file changed, 93 insertions(+), 102 deletions(-) diff --git a/src/main.rs b/src/main.rs index 648fdfc..76fc449 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,11 +3,11 @@ use std::collections::HashMap; struct BakedGate { - table: Vec + table: Vec> } impl BakedGate { - fn test(&self, input: Vec) -> bool { + fn test(&self, input: &[bool]) -> &[bool] { let mut total = 0; @@ -17,7 +17,7 @@ impl BakedGate { } } - self.table[total] + &self.table[total] } } @@ -28,14 +28,14 @@ struct Gate { } -trait Logic = Fn(Vec) -> bool; +trait Logic = Fn(&[bool]) -> Vec; impl Gate { - fn new(expected_inputs: usize, f: T) -> Self { + fn new(expected_inputs: usize, expected_outputs: usize, f: T) -> Self { Self { function: f, qty_inputs: expected_inputs, - qty_outputs: 1, + qty_outputs: expected_outputs, } } @@ -55,7 +55,7 @@ impl Gate { } inputs.reverse(); - let output = self.tick(inputs); + let output = self.tick(&inputs); // The index is the question, and the item at the index is the answer options.push(output); @@ -66,55 +66,74 @@ impl Gate { } } - fn tick(&self, inputs: Vec) -> bool { + fn tick(&self, inputs: &[bool]) -> Vec { assert!(self.qty_inputs == inputs.len()); - (self.function)(inputs) + let out = (self.function)(&inputs); + + assert!(out.len() == self.qty_outputs); + + out } } +#[test] +fn mimo() { + let gate = Gate::new(2, 2, |f| { + vec![true, f[0] | f[1]] + }); + + assert_eq!(gate.tick(&[true, false]), &[true, true]); + assert_eq!(gate.tick(&[false, false]), &[true, false]); + + let baked = gate.bake(); + + assert_eq!(baked.test(&[true, false]), &[true, true]); + assert_eq!(baked.test(&[false, false]), &[true, false]); +} + #[test] fn baked_gate() { - let and = Gate::new(2, |f| { + let and = Gate::new(2, 1, |f| { let a = f[0]; let b = f[1]; - a && b + vec![a && b] }); let baked = and.bake(); - assert_eq!(baked.test(vec![true, true]), true); - assert_eq!(baked.test(vec![true, false]), false); - assert_eq!(baked.test(vec![false, true]), false); - assert_eq!(baked.test(vec![false, false]), false); + assert_eq!(baked.test(&[true, true])[0], true); + assert_eq!(baked.test(&[true, false])[0], false); + assert_eq!(baked.test(&[false, true])[0], false); + assert_eq!(baked.test(&[false, false])[0], false); - let or = Gate::new(2, |f| { + let or = Gate::new(2, 1, |f| { let a = f[0]; let b = f[1]; - a || b + vec![a || b] }); let baked = or.bake(); - assert_eq!(baked.test(vec![true, true]), true); - assert_eq!(baked.test(vec![true, false]), true); - assert_eq!(baked.test(vec![false, true]), true); - assert_eq!(baked.test(vec![false, false]), false); + assert_eq!(baked.test(&[true, true])[0], true); + assert_eq!(baked.test(&[true, false])[0], true); + assert_eq!(baked.test(&[false, true])[0], true); + assert_eq!(baked.test(&[false, false])[0], false); - let not = Gate::new(1, |f| { - !f[0] + let not = Gate::new(1, 1, |f| { + vec![!f[0]] }); let baked = not.bake(); - assert_eq!(baked.test(vec![true]), false); - assert_eq!(baked.test(vec![false]), true); + assert_eq!(baked.test(&[true])[0], false); + assert_eq!(baked.test(&[false])[0], true); } #[test] fn baked_registry() { let mut registry: HashMap<&str, BakedGate> = HashMap::new(); - let and = Gate::new(2, |f| f[0] && f[1]); - let or = Gate::new(2, |f| f[0] | f[1]); - let not = Gate::new(1, |f| !f[0]); + let and = Gate::new(2, 1, |f| vec![f[0] && f[1]]); + let or = Gate::new(2, 1, |f| vec![f[0] | f[1]]); + let not = Gate::new(1, 1, |f| vec![!f[0]]); registry.insert("AND", and.bake()); registry.insert("OR", or.bake()); @@ -122,18 +141,19 @@ fn baked_registry() { if let (Some(and), Some(not)) = (registry.get("AND"), registry.get("NOT")) { - let nand = Gate::new(2, |f| { - not.test(vec![and.test(f)]) + let nand = Gate::new(2, 1, |f| { + let and_r = and.test(&f); + not.test(and_r).to_vec() }); registry.insert("NAND", nand.bake()); } if let Some(nand) = registry.get("NAND") { - assert_eq!(nand.test(vec![true, true]), false); - assert_eq!(nand.test(vec![false, true]), true); - assert_eq!(nand.test(vec![true, false]), true); - assert_eq!(nand.test(vec![false, false]), true); + assert_eq!(nand.test(&[true, true])[0], false); + assert_eq!(nand.test(&[false, true])[0], true); + assert_eq!(nand.test(&[true, false])[0], true); + assert_eq!(nand.test(&[false, false])[0], true); } else { unreachable!() } @@ -148,110 +168,81 @@ fn unbaked_registry() { let and: Gate> = Gate::new( 2, - Box::new(|f| f[0] && f[1]), + 1, + Box::new(|f| vec![f[0] && f[1]]), ); registry.insert("AND", and); - let not: Gate> = Gate::new(1, Box::new(|f| !f[0])); + let not: Gate> = Gate::new(1, 1, Box::new(|f| vec![!f[0]])); registry.insert("NOT", not); if let (Some(not), Some(and)) = (registry.get("NOT"), registry.get("AND")) { let nand: Gate> = Gate::new( 2, + 1, Box::new(|f| { let a = f[0]; let b = f[1]; - let n = and.tick(vec![a, b]); - not.tick(vec![n]) + let n = and.tick(&[a, b]); + not.tick(&n) }), ); - assert_eq!(not.tick(vec![true]), false); - assert_eq!(not.tick(vec![false]), true); + assert_eq!(not.tick(&[true])[0], false); + assert_eq!(not.tick(&[false])[0], true); - assert_eq!(and.tick(vec![true, true]), true); - assert_eq!(and.tick(vec![true, false]), false); - assert_eq!(and.tick(vec![false, true]), false); - assert_eq!(and.tick(vec![false, false]), false); + assert_eq!(and.tick(&[true, true])[0], true); + assert_eq!(and.tick(&[true, false])[0], false); + assert_eq!(and.tick(&[false, true])[0], false); + assert_eq!(and.tick(&[false, false])[0], false); - assert_eq!(nand.tick(vec![true, true]), false); - assert_eq!(nand.tick(vec![true, false]), true); - assert_eq!(nand.tick(vec![false, true]), true); - assert_eq!(nand.tick(vec![false, false]), true); + assert_eq!(nand.tick(&[true, true])[0], false); + assert_eq!(nand.tick(&[true, false])[0], true); + assert_eq!(nand.tick(&[false, true])[0], true); + assert_eq!(nand.tick(&[false, false])[0], true); }; } -#[test] -fn nand_gate() { - let and = Gate::new(2, |f| { - let a = f[0]; - let b = f[1]; - a && b - }); - let not = Gate::new(1, |f| !f[0]); - - let nand = Gate::new(2, |f| not.tick(vec![and.tick(f)])); - - assert_eq!(nand.tick(vec![true, true]), false); - assert_eq!(nand.tick(vec![true, false]), true); - assert_eq!(nand.tick(vec![false, true]), true); - assert_eq!(nand.tick(vec![false, false]), true); -} - #[test] fn generic_gates() { - let and = Gate::new(2, |f| { + let and = Gate::new(2, 1,|f| { let a = f[0]; let b = f[1]; - a && b + vec![a && b] }); - assert_eq!(and.tick(vec![true, true]), true); - assert_eq!(and.tick(vec![true, false]), false); - assert_eq!(and.tick(vec![false, true]), false); - assert_eq!(and.tick(vec![false, false]), false); + assert_eq!(and.tick(&[true, true])[0], true); + assert_eq!(and.tick(&[true, false])[0], false); + assert_eq!(and.tick(&[false, true])[0], false); + assert_eq!(and.tick(&[false, false])[0], false); - let not = Gate::new(1, |f| !f[0]); + let not = Gate::new(1, 1, |f| vec![!f[0]]); - assert_eq!(not.tick(vec![true]), false); - assert_eq!(not.tick(vec![false]), true); + assert_eq!(not.tick(&[true])[0], false); + assert_eq!(not.tick(&[false])[0], true); - let or = Gate::new(2, |f| { + let or = Gate::new(2, 1, |f| { let a = f[0]; let b = f[1]; - a | b + vec![a | b] }); - assert_eq!(or.tick(vec![true, true]), true); - assert_eq!(or.tick(vec![true, false]), true); - assert_eq!(or.tick(vec![false, true]), true); - assert_eq!(or.tick(vec![false, false]), false); + assert_eq!(or.tick(&[true, true])[0], true); + assert_eq!(or.tick(&[true, false])[0], true); + assert_eq!(or.tick(&[false, true])[0], true); + assert_eq!(or.tick(&[false, false])[0], false); + + let nand = Gate::new(2, 1, |f| not.tick(&and.tick(f))); + + assert_eq!(nand.tick(&[true, true])[0], false); + assert_eq!(nand.tick(&[true, false])[0], true); + assert_eq!(nand.tick(&[false, true])[0], true); + assert_eq!(nand.tick(&[false, false])[0], true); } fn main() { - let g = Gate::new(2, |f| {true}); - - let mut registry: HashMap<&str, BakedGate> = HashMap::new(); - - let and = Gate::new(2, |f| f[0] && f[1]); - let or = Gate::new(2, |f| f[0] | f[1]); - let not = Gate::new(1, |f| !f[0]); - - registry.insert("AND", and.bake()); - registry.insert("OR", or.bake()); - registry.insert("NOT", not.bake()); - - if let (Some(and), Some(not)) = (registry.get("AND"), registry.get("NOT")) { - - let nand = Gate::new(2, |f| { - not.test(vec![and.test(f)]) - }); - - registry.insert("NAND", nand.bake()); - } - - g.bake(); + println!("hello world"); }