Compare commits
	
		
			1 Commits
		
	
	
		
			master
			...
			multi-outp
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| faa0608575 | 
							
								
								
									
										195
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										195
									
								
								src/main.rs
									
									
									
									
									
								
							@@ -3,11 +3,11 @@
 | 
				
			|||||||
use std::collections::HashMap;
 | 
					use std::collections::HashMap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct BakedGate {
 | 
					struct BakedGate {
 | 
				
			||||||
    table: Vec<bool>
 | 
					    table: Vec<Vec<bool>>
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl BakedGate {
 | 
					impl BakedGate {
 | 
				
			||||||
    fn test(&self, input: Vec<bool>) -> bool {
 | 
					    fn test(&self, input: &[bool]) -> &[bool] {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut total = 0;
 | 
					        let mut total = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -17,7 +17,7 @@ impl BakedGate {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.table[total]
 | 
					        &self.table[total]
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -28,14 +28,14 @@ struct Gate<T> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
trait Logic = Fn(Vec<bool>) -> bool;
 | 
					trait Logic = Fn(&[bool]) -> Vec<bool>;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl<T: Logic> Gate<T> {
 | 
					impl<T: Logic> Gate<T> {
 | 
				
			||||||
    fn new(expected_inputs: usize, f: T) -> Self {
 | 
					    fn new(expected_inputs: usize, expected_outputs: usize, f: T) -> Self {
 | 
				
			||||||
        Self {
 | 
					        Self {
 | 
				
			||||||
            function: f,
 | 
					            function: f,
 | 
				
			||||||
            qty_inputs: expected_inputs,
 | 
					            qty_inputs: expected_inputs,
 | 
				
			||||||
            qty_outputs: 1,
 | 
					            qty_outputs: expected_outputs,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -55,7 +55,7 @@ impl<T: Logic> Gate<T> {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            inputs.reverse();
 | 
					            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
 | 
					            // The index is the question, and the item at the index is the answer
 | 
				
			||||||
            options.push(output);
 | 
					            options.push(output);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -66,55 +66,74 @@ impl<T: Logic> Gate<T> {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn tick(&self, inputs: Vec<bool>) -> bool {
 | 
					    fn tick(&self, inputs: &[bool]) -> Vec<bool> {
 | 
				
			||||||
        assert!(self.qty_inputs == inputs.len());
 | 
					        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]
 | 
					#[test]
 | 
				
			||||||
fn baked_gate() {
 | 
					fn baked_gate() {
 | 
				
			||||||
    let and = Gate::new(2, |f| {
 | 
					    let and = Gate::new(2, 1, |f| {
 | 
				
			||||||
        let a = f[0];
 | 
					        let a = f[0];
 | 
				
			||||||
        let b = f[1];
 | 
					        let b = f[1];
 | 
				
			||||||
        a && b
 | 
					        vec![a && b]
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    let baked = and.bake();
 | 
					    let baked = and.bake();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert_eq!(baked.test(vec![true, true]), true);
 | 
					    assert_eq!(baked.test(&[true, true])[0], true);
 | 
				
			||||||
    assert_eq!(baked.test(vec![true, false]), false);
 | 
					    assert_eq!(baked.test(&[true, false])[0], false);
 | 
				
			||||||
    assert_eq!(baked.test(vec![false, true]), false);
 | 
					    assert_eq!(baked.test(&[false, true])[0], false);
 | 
				
			||||||
    assert_eq!(baked.test(vec![false, false]), 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 a = f[0];
 | 
				
			||||||
        let b = f[1];
 | 
					        let b = f[1];
 | 
				
			||||||
        a || b
 | 
					        vec![a || b]
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    let baked = or.bake();
 | 
					    let baked = or.bake();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert_eq!(baked.test(vec![true, true]), true);
 | 
					    assert_eq!(baked.test(&[true, true])[0], true);
 | 
				
			||||||
    assert_eq!(baked.test(vec![true, false]), true);
 | 
					    assert_eq!(baked.test(&[true, false])[0], true);
 | 
				
			||||||
    assert_eq!(baked.test(vec![false, true]), true);
 | 
					    assert_eq!(baked.test(&[false, true])[0], true);
 | 
				
			||||||
    assert_eq!(baked.test(vec![false, false]), false);
 | 
					    assert_eq!(baked.test(&[false, false])[0], false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let not = Gate::new(1, |f| {
 | 
					    let not = Gate::new(1, 1, |f| {
 | 
				
			||||||
        !f[0]
 | 
					        vec![!f[0]]
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
    let baked = not.bake();
 | 
					    let baked = not.bake();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert_eq!(baked.test(vec![true]), false);
 | 
					    assert_eq!(baked.test(&[true])[0], false);
 | 
				
			||||||
    assert_eq!(baked.test(vec![false]), true);
 | 
					    assert_eq!(baked.test(&[false])[0], true);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[test]
 | 
					#[test]
 | 
				
			||||||
fn baked_registry() {
 | 
					fn baked_registry() {
 | 
				
			||||||
    let mut registry: HashMap<&str, BakedGate> = HashMap::new();
 | 
					    let mut registry: HashMap<&str, BakedGate> = HashMap::new();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let and = Gate::new(2, |f| f[0] && f[1]);
 | 
					    let and = Gate::new(2, 1,  |f| vec![f[0] && f[1]]);
 | 
				
			||||||
    let or = Gate::new(2, |f| f[0] | f[1]);
 | 
					    let or = Gate::new(2, 1, |f| vec![f[0] | f[1]]);
 | 
				
			||||||
    let not = Gate::new(1, |f| !f[0]);
 | 
					    let not = Gate::new(1, 1, |f| vec![!f[0]]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    registry.insert("AND", and.bake());
 | 
					    registry.insert("AND", and.bake());
 | 
				
			||||||
    registry.insert("OR", or.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")) {
 | 
					    if let (Some(and), Some(not)) = (registry.get("AND"), registry.get("NOT")) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let nand = Gate::new(2, |f| {
 | 
					        let nand = Gate::new(2, 1, |f| {
 | 
				
			||||||
            not.test(vec![and.test(f)])
 | 
					            let and_r = and.test(&f);
 | 
				
			||||||
 | 
					            not.test(and_r).to_vec()
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        registry.insert("NAND", nand.bake());
 | 
					        registry.insert("NAND", nand.bake());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if let Some(nand) = registry.get("NAND") {
 | 
					    if let Some(nand) = registry.get("NAND") {
 | 
				
			||||||
        assert_eq!(nand.test(vec![true, true]), false);
 | 
					        assert_eq!(nand.test(&[true, true])[0], false);
 | 
				
			||||||
        assert_eq!(nand.test(vec![false, true]), true);
 | 
					        assert_eq!(nand.test(&[false, true])[0], true);
 | 
				
			||||||
        assert_eq!(nand.test(vec![true, false]), true);
 | 
					        assert_eq!(nand.test(&[true, false])[0], true);
 | 
				
			||||||
        assert_eq!(nand.test(vec![false, false]), true);
 | 
					        assert_eq!(nand.test(&[false, false])[0], true);
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        unreachable!()
 | 
					        unreachable!()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -148,110 +168,81 @@ fn unbaked_registry() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    let and: Gate<Box<dyn Logic>> = Gate::new(
 | 
					    let and: Gate<Box<dyn Logic>> = Gate::new(
 | 
				
			||||||
        2,
 | 
					        2,
 | 
				
			||||||
        Box::new(|f| f[0] && f[1]),
 | 
					        1,
 | 
				
			||||||
 | 
					        Box::new(|f| vec![f[0] && f[1]]),
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    registry.insert("AND", and);
 | 
					    registry.insert("AND", and);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let not: Gate<Box<dyn Logic>> = Gate::new(1, Box::new(|f| !f[0]));
 | 
					    let not: Gate<Box<dyn Logic>> = Gate::new(1, 1, Box::new(|f| vec![!f[0]]));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    registry.insert("NOT", not);
 | 
					    registry.insert("NOT", not);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if let (Some(not), Some(and)) = (registry.get("NOT"), registry.get("AND")) {
 | 
					    if let (Some(not), Some(and)) = (registry.get("NOT"), registry.get("AND")) {
 | 
				
			||||||
        let nand: Gate<Box<dyn Logic>> = Gate::new(
 | 
					        let nand: Gate<Box<dyn Logic>> = Gate::new(
 | 
				
			||||||
            2,
 | 
					            2,
 | 
				
			||||||
 | 
					            1,
 | 
				
			||||||
            Box::new(|f| {
 | 
					            Box::new(|f| {
 | 
				
			||||||
                let a = f[0];
 | 
					                let a = f[0];
 | 
				
			||||||
                let b = f[1];
 | 
					                let b = f[1];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                let n = and.tick(vec![a, b]);
 | 
					                let n = and.tick(&[a, b]);
 | 
				
			||||||
                not.tick(vec![n])
 | 
					                not.tick(&n)
 | 
				
			||||||
            }),
 | 
					            }),
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assert_eq!(not.tick(vec![true]), false);
 | 
					        assert_eq!(not.tick(&[true])[0], false);
 | 
				
			||||||
        assert_eq!(not.tick(vec![false]), true);       
 | 
					        assert_eq!(not.tick(&[false])[0], true);       
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assert_eq!(and.tick(vec![true, true]), true);
 | 
					        assert_eq!(and.tick(&[true, true])[0], true);
 | 
				
			||||||
        assert_eq!(and.tick(vec![true, false]), false);
 | 
					        assert_eq!(and.tick(&[true, false])[0], false);
 | 
				
			||||||
        assert_eq!(and.tick(vec![false, true]), false);
 | 
					        assert_eq!(and.tick(&[false, true])[0], false);
 | 
				
			||||||
        assert_eq!(and.tick(vec![false, false]), false);       
 | 
					        assert_eq!(and.tick(&[false, false])[0], false);       
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        assert_eq!(nand.tick(vec![true, true]), false);
 | 
					        assert_eq!(nand.tick(&[true, true])[0], false);
 | 
				
			||||||
        assert_eq!(nand.tick(vec![true, false]), true);
 | 
					        assert_eq!(nand.tick(&[true, false])[0], true);
 | 
				
			||||||
        assert_eq!(nand.tick(vec![false, true]), true);
 | 
					        assert_eq!(nand.tick(&[false, true])[0], true);
 | 
				
			||||||
        assert_eq!(nand.tick(vec![false, false]), 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]
 | 
					#[test]
 | 
				
			||||||
fn generic_gates() {
 | 
					fn generic_gates() {
 | 
				
			||||||
    let and = Gate::new(2, |f| {
 | 
					    let and = Gate::new(2, 1,|f| {
 | 
				
			||||||
        let a = f[0];
 | 
					        let a = f[0];
 | 
				
			||||||
        let b = f[1];
 | 
					        let b = f[1];
 | 
				
			||||||
        a && b
 | 
					        vec![a && b]
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert_eq!(and.tick(vec![true, true]), true);
 | 
					    assert_eq!(and.tick(&[true, true])[0], true);
 | 
				
			||||||
    assert_eq!(and.tick(vec![true, false]), false);
 | 
					    assert_eq!(and.tick(&[true, false])[0], false);
 | 
				
			||||||
    assert_eq!(and.tick(vec![false, true]), false);
 | 
					    assert_eq!(and.tick(&[false, true])[0], false);
 | 
				
			||||||
    assert_eq!(and.tick(vec![false, false]), 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(&[true])[0], false);
 | 
				
			||||||
    assert_eq!(not.tick(vec![false]), true);
 | 
					    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 a = f[0];
 | 
				
			||||||
        let b = f[1];
 | 
					        let b = f[1];
 | 
				
			||||||
        a | b
 | 
					        vec![a | b]
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    assert_eq!(or.tick(vec![true, true]), true);
 | 
					    assert_eq!(or.tick(&[true, true])[0], true);
 | 
				
			||||||
    assert_eq!(or.tick(vec![true, false]), true);
 | 
					    assert_eq!(or.tick(&[true, false])[0], true);
 | 
				
			||||||
    assert_eq!(or.tick(vec![false, true]), true);
 | 
					    assert_eq!(or.tick(&[false, true])[0], true);
 | 
				
			||||||
    assert_eq!(or.tick(vec![false, false]), false);
 | 
					    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() {
 | 
					fn main() {
 | 
				
			||||||
    let g = Gate::new(2, |f| {true});
 | 
					    println!("hello world");
 | 
				
			||||||
 | 
					 | 
				
			||||||
    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();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user