Dyota's blog

Power Query: 100 prisoners

Of course I did it in Power Query.

WARNING: While I believe the method and the expression of problem to be correct, in reality, this code does not behave the way you think it might. The percentage of success sits around 50% - 60%, where the actual theoretical success rate should be around 30%. This is because of Power Query's lazy evaluation model - it evaluates (and re-evaluates) expressions as and when it is encountered.

When you trace back the function calls, all the way back to shuffle, you will see that Power Query is actually generating a new set of boxes for every prisoner, instead of sticking to the same set of boxes for the whole cohort.

I didn't spend more time on this to make it "work"[1], but anyway... here it is:

let
      
    hundred = {0..99},
    
    shuffle = (source as list) as list =>
        List.Sort(
            source, 
            (a, b) => Number.RoundAwayFromZero(Number.RandomBetween(-1, 1))
        ),
    
    makeCabinet = () as list => shuffle(hundred),

    searchThroughBoxes = (prisonerNumber as number, cabinet as list) as logical => 
        let 
            searches = List.Generate(
                () => cabinet{prisonerNumber},
                each cabinet{_} <> prisonerNumber,
                each cabinet{_}
            ),
            success = List.Count(searches) + 1 <= 50 
        in 
            success,

    trialGroupOfPrisoners = (thisCabinet as list ) as list => 
            List.Transform(
                hundred, 
                each searchThroughBoxes(_, thisCabinet)
            ),

    lifetimes = 1000,

    allLifetimes = List.Transform(
        {1..lifetimes},
        each 
            let
                cabinet = List.Buffer(makeCabinet())
            in
                List.AllTrue(
                    trialGroupOfPrisoners(cabinet)
                )
    ),

    percentageSuccess = List.Count(List.Select(allLifetimes, each _ = true)) / List.Count(allLifetimes)

in 
    percentageSuccess

[1] I could have (outside of Excel) generated 1 unique cabinet of boxes for every lifetime, frozen them in a text file, and pulled them in using Power Query, but... that's much more work than it is fun.

#montecarlo #powerquery #recursive