0

I was having trouble understanding the monty hall problem so I put together some Rust. I have a function which determines whether or not a participant wins a game show. If they win the game show then the function returns true, otherwise it returns false. I wanted to test for very large numbers so I added a Rayon Parallel Iterator to the for loop. The code follows:

fn gameshow(num_doors: usize, num_runs: usize, change: bool) -> usize {
    let mut won_games:usize = 0;
    let runs: Vec<Vec<bool>> = vec![stagehand(num_doors); num_runs]; // Creates common solution 
    if change {
        ParallelIterator::for_each(IntoParallelIterator::into_par_iter(runs), |game| {
            let winner: bool = run_game_no_change(game); // Each door is chosen randomly when tested
            if winner { won_games += 1;}
        });
    }
    else {
        ParallelIterator::for_each(IntoParallelIterator::into_par_iter(runs), |game| {
            let winner: bool = run_game_no_change(game); // Each door is chosen randomly when tested
            if winner { won_games += 1;}
        });     
    }
    won_games   
}

When compiling it throws a "Cannot assign to won_games, as it is a captured variable in a Fn closure" error.

1 Answers1

3

You can't modify a captured external state in parallel, or you could have data races. Rayon is specifically designed to prevent this.

Instead of for_each, use map to map each bool to 0 or 1, then take the sum of that:

fn gameshow(num_doors: usize, num_runs: usize, change: bool) -> usize {
    let runs: Vec<Vec<bool>> = vec![stagehand(num_doors); num_runs]; // Creates common solution 
    let won_games = if change {
        runs.into_par_iter().map(|game| {
            let winner: bool = run_game_no_change(game); // Each door is chosen randomly when tested
            if winner { 1 } else { 0 }
        }).sum()
    } else {
        runs.into_par_iter().map(|game| {
            let winner: bool = run_game_no_change(game); // Each door is chosen randomly when tested
            if winner { 1 } else { 0 }
        }).sum()    
    };

    won_games   
}
PitaJ
  • 12,969
  • 6
  • 36
  • 55