njhkugk6i76g6gi6gi7g6
njhkugk6i76g6gi6gi7g6

Reputation: 61

The same function always returns different answers for the same input

I've been doing exercises after Rust Books's Chapter 8. I've implemented the first task, but there is a problem: I don't change the function and the input, but the result is always different.

use std::collections::HashMap;

fn main() {
    println!("{:?}",vector(&mut vec![10,15,20,20]));
    println!("{:?}",vector(&mut vec![10,15,20,20]));
    println!("{:?}",vector(&mut vec![10,15,20,20]));
    println!("{:?}",vector(&mut vec![10,15,20,20]));
}

fn vector(V:&mut Vec<i32>)->[i32;3]{
    let average:i32 = V.iter().sum::<i32>()/(V.len() as i32);
    V.sort();
    let median:i32 = V[V.len()/2+1];
    let mut map = HashMap::new();
    let mut mode = 0;
    for el in V{
        let count = map.entry(el).or_insert(0);
        //or_insert returns reference to the value of the key
        *count+=1; //dereference and increase;
      }
      for (k,v) in map{
          if v>mode{
                mode=*k;
          }
      }

    return [average,median,mode]
}

The outputs vary from execution to execution:

[16, 20, 20]
[16, 20, 15]
[16, 20, 15]
[16, 20, 20]

Here's a playground runnable example

Why does the output differ from the same input values?

Upvotes: 1

Views: 117

Answers (1)

loganfsmyth
loganfsmyth

Reputation: 161457

The fact that you assign *k to mode does not make sense, did you mean to assign v? It seems like at a minimum this needs to be:

let mut mode = (0, 0);
for (k, v) in map {
    if v > mode.1 {
        mode = (*k, v);
    }
}

return [average, median, mode.0];

The reason your code is behaving non-deterministically is because hashmaps do not make any guarantees about the order in which the key/value pairs are produced by the iterator. On the docs page you mentioned for instance, it notes

This code will print each pair in an arbitrary order:

and because your code as-is uses v instead of *k for the first check (and v is a small value compared to *k, the first value to be produced by the hashmap will a always be set as the mode value because the the first entry is larger than the default 0 mode, and then future pairs are never large enough to change it.

Upvotes: 3

Related Questions