diff options
Diffstat (limited to 'src/gate.rs')
| -rw-r--r-- | src/gate.rs | 96 |
1 files changed, 69 insertions, 27 deletions
diff --git a/src/gate.rs b/src/gate.rs index 87ae219..d88f729 100644 --- a/src/gate.rs +++ b/src/gate.rs @@ -1,6 +1,7 @@ use crate::pin::*; use crate::types::*; use std::collections::HashMap; +use std::collections::HashSet; #[derive(Debug)] pub enum GateType { @@ -140,8 +141,8 @@ pub struct AndGate { impl AndGate { fn new(input: Vec<PinValue>, id: usize, kind: PinType) -> Self { if input.is_empty() { - let pin_1 = Pin::new(PinType::Undetermined, id, 42); - let pin_2 = Pin::new(PinType::Undetermined, id, 42); + let pin_1 = Pin::new(PinType::GateInput, id, 42); + let pin_2 = Pin::new(PinType::GateInput, id, 42); Self { id, input: vec![pin_1, pin_2], @@ -169,6 +170,7 @@ impl AndGate { let res = (self.input[0].val.unwrap() & self.input[1].val.unwrap()) == 1; self.output.val = Some(res as u8); self.output.kind = PinType::GateOutput; + println!("{:?}", self); res } } @@ -260,7 +262,7 @@ impl BufferGate { #[derive(Debug, Clone, PartialEq)] pub struct Chip { - gates: Gates, + pub gates: Gates, pub connections: Connections, input: Pins, output: Pins, @@ -291,16 +293,11 @@ impl Chip { } pub fn connect_gate(&mut self, from: &mut Gate, to: &mut Gate, to_pin_idx: usize) { + to.input_mut()[to_pin_idx] = Pin::new(PinType::GateInput, to.id(), 42); self.connections .entry(to.input()[to_pin_idx]) .and_modify(|val| val.push(*from.output())) .or_insert_with(|| vec![*from.output()]); - // self.connections - // .entry(to.input()[to_pin_idx].id) - // .or_insert(vec![from.output().id]); - from.evaluate(); - to.input_mut()[to_pin_idx] = - Pin::new(PinType::GateInput, to.id(), from.output().val.unwrap()); if !self.gates.contains(&from) { // TODO: Remove this clone self.add_gate(from.clone()); @@ -311,30 +308,75 @@ impl Chip { } } - pub fn pins(&self) -> Vec<&Pin> { - let mut pins = vec![]; + pub fn pins(&self) -> HashMap<usize, Vec<&Pin>> { + let mut pins = HashMap::new(); for gate in &self.gates { for pin in gate.input() { - pins.push(pin); + pins.entry(pin.id) + .and_modify(|val: &mut Vec<&Pin>| val.push(pin)) + .or_insert_with(|| vec![pin]); } - pins.push(gate.output()); + pins.entry(gate.output().id) + .and_modify(|val: &mut Vec<&Pin>| val.push(gate.output())) + .or_insert_with(|| vec![gate.output()]); } pins } - // fn gate_dag(&self) -> HashMap<&Pin, Vec<&Pin>> { - // let mut dag = HashMap::new(); - // for connection in &self.connections { - // for pin in *connection.1 { - // dag.entry(*connection.0) - // .and_modify(|val: &mut Vec<&Pin>| val.push(pin)) - // .or_insert_with(|| vec![pin]); - // } - // } - // dag - // } - - fn simulate(&self) -> bool { - todo!() + pub fn gate_dag(&self) -> HashMap<usize, Vec<usize>> { + let mut dag = HashMap::new(); + for connection in &self.connections { + for pin in connection.1 { + dag.entry(connection.0.gate_id) + .and_modify(|val: &mut Vec<usize>| val.push(pin.gate_id)) + .or_insert_with(|| vec![pin.gate_id]); + } + } + dag + } + + pub fn pin_dag(&self) -> HashMap<usize, Vec<usize>> { + let mut gate_dag = self.gate_dag(); + let mut dag = HashMap::new(); + for (id, children) in gate_dag { + // dag.entry() + // .and_modify(|val: &mut Vec<usize>| val.push(pin.gate_id)) + // .or_insert_with(|| vec![pin.gate_id]); + } + dag + } + + fn simulate_helper( + &mut self, + gate: usize, + visited: &mut HashSet<usize>, + dag: &HashMap<usize, Vec<usize>>, + ) { + visited.insert(gate); + if dag.contains_key(&gate) { + for child in dag.get(&gate).unwrap() { + if !visited.contains(child) { + self.simulate_helper(*child, visited, dag); + } + } + let pos = self.gates.iter().position(|g| g.id() == gate).unwrap(); + self.gates[pos].evaluate(); + println!("{}", gate); + } else { + println!("{}", gate); + let pos = self.gates.iter().position(|g| g.id() == gate).unwrap(); + self.gates[pos].evaluate(); + } + } + + pub fn simulate(&mut self) -> bool { + let dag = self.gate_dag(); + let mut visited = HashSet::new(); + for child in dag.get(&8).unwrap() { + if !visited.contains(child) { + self.simulate_helper(*child, &mut visited, &dag); + } + } + false } } |
