pub fn simulate_rounds(
    template: &[char],
    rules: &HashMap<(char, char), char>,
    rounds: usize,
) -> u64 {
    // map of pairs to number of occurances of those
    let mut pairs: HashMap<_, u64> = HashMap::new();
    for (c1, c2) in template.iter().zip(template.iter().skip(1)) {
        *pairs.entry((*c1, *c2)).or_insert(0) += 1;
    }

    // in each round, update pairs
    for _ in 0..rounds {
        let mut upd = HashMap::new();
        for ((c1, c2), cnt0) in &pairs {
            if let Some(d) = rules.get(&(*c1, *c2)) {
                // if pair is found in rules, replace (c1, c2) by (c1, d) and (d, c2)
                *upd.entry((*c1, *d)).or_insert(0) += cnt0;
                *upd.entry((*d, *c2)).or_insert(0) += cnt0;
            } else {
                // if pair is not found in rules, keep pair
                *upd.entry((*c1, *c2)).or_insert(0) += cnt0;
            }
        }
        pairs = upd;
    }

    // count symbols in pairs
    // each symbol contributes to two pairs except for the first and the last symbol
    // start with count = 1 for first and last symbol to consistently count every symbol 
    // twice
    let mut counts = HashMap::new();
    counts.insert(template[0], 1);
    counts.insert(template[template.len() - 1], 1);
    for ((c1, c2), cnt) in &pairs {
        *counts.entry(*c1).or_insert(0) += cnt;
        *counts.entry(*c2).or_insert(0) += cnt;
    }

    // get (twice the) count for most and less frequent symbol
    let min = counts.values().min().expect("No min");
    let max = counts.values().max().expect("No max");

    // return difference, divide by 2 because every symbol is counted twice
    (max - min) / 2
}
// tag::simulate_rounds[]
/// simulate given number of rounds starting from polymer template and using given 
/// rules
:simulate_rounds[]
simulate given number of rounds starting from polymer template and using given
rules
: simulate_rounds [] simulate given number of rounds starting from polymer template and using given rules
pub fn simulate_rounds(
    template: &[char],
    rules: &HashMap<(char, char), char>,
    rounds: usize,
) -> u64 {
    // map of pairs to number of occurances of those
    let mut pairs: HashMap<_, u64> = HashMap::new();
    for (c1, c2) in template.iter().zip(template.iter().skip(1)) {
        *pairs.entry((*c1, *c2)).or_insert(0) += 1;
    }
    // in each round, update pairs
    for _ in 0..rounds {
        let mut upd = HashMap::new();
        for ((c1, c2), cnt0) in &pairs {
            if let Some(d) = rules.get(&(*c1, *c2)) {
                // if pair is found in rules, replace (c1, c2) by (c1, d) and (d, c2)
                *upd.entry((*c1, *d)).or_insert(0) += cnt0;
                *upd.entry((*d, *c2)).or_insert(0) += cnt0;
            } else {
                // if pair is not found in rules, keep pair
                *upd.entry((*c1, *c2)).or_insert(0) += cnt0;
            }
        }
        pairs = upd;
    }
    // count symbols in pairs
    // each symbol contributes to two pairs except for the first and the last symbol
    // start with count = 1 for first and last symbol to consistently count every symbol 
    // twice
    let mut counts = HashMap::new();
    counts.insert(template[0], 1);
    counts.insert(template[template.len() - 1], 1);
    for ((c1, c2), cnt) in &pairs {
        *counts.entry(*c1).or_insert(0) += cnt;
        *counts.entry(*c2).or_insert(0) += cnt;
    }
    // get (twice the) count for most and less frequent symbol
    let min = counts.values().min().expect("No min");
    let max = counts.values().max().expect("No max");
    // return difference, divide by 2 because every symbol is counted twice
    (max - min) / 2
}
pub fn simulate_rounds ( template : & [ char ] , rules : & HashMap < ( char , char ) , char > , rounds : usize , ) -> u64 { // map of pairs to number of occurances of those let mut pairs : HashMap < _ , u64 > = HashMap :: new ( ) ; for ( c1 , c2 ) in template . iter ( ) . zip ( template . iter ( ) . skip ( 1 ) ) { * pairs . entry ( ( * c1 , * c2 ) ) . or_insert ( 0 ) += 1 ; } // in each round, update pairs for _ in 0 .. rounds { let mut upd = HashMap :: new ( ) ; for ( ( c1 , c2 ) , cnt0 ) in & pairs { if let Some ( d ) = rules . get ( & ( * c1 , * c2 ) ) { // if pair is found in rules, replace (c1, c2) by (c1, d) and (d, c2) * upd . entry ( ( * c1 , * d ) ) . or_insert ( 0 ) += cnt0 ; * upd . entry ( ( * d , * c2 ) ) . or_insert ( 0 ) += cnt0 ; } else { // if pair is not found in rules, keep pair * upd . entry ( ( * c1 , * c2 ) ) . or_insert ( 0 ) += cnt0 ; } } pairs = upd ; } // count symbols in pairs // each symbol contributes to two pairs except for the first and the last symbol // start with count = 1 for first and last symbol to consistently count every symbol  // twice let mut counts = HashMap :: new ( ) ; counts . insert ( template [ 0 ] , 1 ) ; counts . insert ( template [ template . len ( ) - 1 ] , 1 ) ; for ( ( c1 , c2 ) , cnt ) in & pairs { * counts . entry ( * c1 ) . or_insert ( 0 ) += cnt ; * counts . entry ( * c2 ) . or_insert ( 0 ) += cnt ; } // get (twice the) count for most and less frequent symbol let min = counts . values ( ) . min ( ) . expect ( " " ) ; let max = counts . values ( ) . max ( ) . expect ( " " ) ; // return difference, divide by 2 because every symbol is counted twice ( max - min ) / 2 }
tag::simulate_rounds[]
simulate given number of rounds starting from polymer template and using given
rules
tag :: simulate_rounds [] simulate given number of rounds starting from polymer template and using given rules
template
&[char]
rules
&HashMap<(char, char), char>
rounds
usize
template
&[char]
rules
&HashMap<(char, char), char>
rounds
usize