/// Build a new factory based on a given list of instructions.
Build a new factory based on a given list of instructions.
Build a new factory based on a given list of instructions .
pub fn build_from(instructions: &Vec<Instruction>) -> Factory {
            // While our `Robot` struct must be fully defined (inputs and outputs), its parameters
            // may be provided across as much as three non-consecutive instructions (two inputs,
            // one for its outputs). We work around this by looping a first time to build hashes of
            // theses parameters and then build the robots.
            //
            // On the other hand, output `Bin` may be created from a single instruction (defining
            // its only input) so we do it directly in the first loop.
            let mut factory = Factory::new();
            // robots id to its input, the vectors are expected to be of size two once we're done
            // with the first processing loop.
            let mut robots_inputs:  HashMap<Id, Vec<Gift>> = HashMap::new();
            // robots id and weight to outputs.
            let mut robots_outputs: HashMap<(Id, MicrochipWeight), Output> = HashMap::new();
            // first processing loop: create the output bins and fill in both `robots_inputs` and
            // `robots_outputs`
            for &instruction in instructions.iter() {
                match instruction {
                    Instruction::Take { robot_id: receiver_id, chip } => {
                        let inputs = robots_inputs.entry(receiver_id).or_insert_with(|| Vec::new());
                        inputs.push(Gift::Input { chip });
                    },
                    Instruction::Donate { robot_id: from_robot_id, low, high } => {
                        let receivers = [(MicrochipWeight::Lower, low), (MicrochipWeight::Higher, high)];
                        for &(weight, output) in receivers.iter() {
                            robots_outputs.insert((from_robot_id, weight), output);
                            match output {
                                Output::Robot(robot_id) => {
                                    let inputs = robots_inputs.entry(robot_id).or_insert_with(|| Vec::new());
                                    inputs.push(Gift::Donation { from_robot_id, weight });
                                },
                                Output::Bin(bin_id) => {
                                    factory.bins.insert(bin_id, Bin {
                                        id: bin_id,
                                        from: Gift::Donation { from_robot_id, weight },
                                    });
                                },
                            }
                        }
                    },
                }
            }
            // second loop, create the all the `Robot` from `robots_inputs` and `robots_outputs`.
            for (&rid, ref froms) in robots_inputs.iter() {
                assert_eq!(froms.len(), 2); // sanity check
                let &low_to  = robots_outputs.get(&(rid, MicrochipWeight::Lower)).unwrap();
                let &high_to = robots_outputs.get(&(rid, MicrochipWeight::Higher)).unwrap();
                factory.robots.insert(rid, Robot {
                    id: rid,
                    from: (froms[0], froms[1]),
                    low_to,
                    high_to,
                });
            }
            // we're done
            return factory;
        }
pub fn build_from ( instructions : & Vec < Instruction > ) -> Factory { // While our `Robot` struct must be fully defined (inputs and outputs), its parameters // may be provided across as much as three non-consecutive instructions (two inputs, // one for its outputs). We work around this by looping a first time to build hashes of // theses parameters and then build the robots. // // On the other hand, output `Bin` may be created from a single instruction (defining // its only input) so we do it directly in the first loop. let mut factory = Factory :: new ( ) ; // robots id to its input, the vectors are expected to be of size two once we're done // with the first processing loop. let mut robots_inputs : HashMap < Id , Vec < Gift > > = HashMap :: new ( ) ; // robots id and weight to outputs. let mut robots_outputs : HashMap < ( Id , MicrochipWeight ) , Output > = HashMap :: new ( ) ; // first processing loop: create the output bins and fill in both `robots_inputs` and // `robots_outputs` for & instruction in instructions . iter ( ) { match instruction { Instruction :: Take { robot_id : receiver_id , chip } => { let inputs = robots_inputs . entry ( receiver_id ) . or_insert_with ( | | Vec :: new ( ) ) ; inputs . push ( Gift :: Input { chip } ) ; } , Instruction :: Donate { robot_id : from_robot_id , low , high } => { let receivers = [ ( MicrochipWeight :: Lower , low ) , ( MicrochipWeight :: Higher , high ) ] ; for & ( weight , output ) in receivers . iter ( ) { robots_outputs . insert ( ( from_robot_id , weight ) , output ) ; match output { Output :: Robot ( robot_id ) => { let inputs = robots_inputs . entry ( robot_id ) . or_insert_with ( | | Vec :: new ( ) ) ; inputs . push ( Gift :: Donation { from_robot_id , weight } ) ; } , Output :: Bin ( bin_id ) => { factory . bins . insert ( bin_id , Bin { id : bin_id , from : Gift :: Donation { from_robot_id , weight } , } ) ; } , } } } , } } // second loop, create the all the `Robot` from `robots_inputs` and `robots_outputs`. for ( & rid , ref froms ) in robots_inputs . iter ( ) { assert_eq ! ( froms len ( ) 2 ) ; // sanity check let & low_to = robots_outputs . get ( & ( rid , MicrochipWeight :: Lower ) ) . unwrap ( ) ; let & high_to = robots_outputs . get ( & ( rid , MicrochipWeight :: Higher ) ) . unwrap ( ) ; factory . robots . insert ( rid , Robot { id : rid , from : ( froms [ 0 ] , froms [ 1 ] ) , low_to , high_to , } ) ; } // we're done return factory ; }
Build a new factory based on a given list of instructions.
Build a new factory based on a given list of instructions .
instructions
&Vec<Instruction>