optimalSeq(drawers, n) = iterate(ind => drawers[ind - 1], n) |> takeUntil(ind => drawers[ind - 1] == n) optimalTrial(drawers) = range(1, 100) |> map(optimalSeq(drawers)) randomSeq(drawers, n) = iterate(ind => randRange(1, 100), randRange(1, 100)) |> takeUntil(ind => drawers[ind - 1] == n) randomTrial(drawers) = range(1, 100) |> map(randomSeq(drawers)) checkLength(seq) = length(take(51, seq)) <= 50 numTrials = 3000 runTrials(trialFunc) = for t in range(1, numTrials) yield range(1, 100) |> shuffle |> toArray |> trialFunc |> map(checkLength) |> all countSuccess(trialFunc) = runTrials(trialFunc) |> filter(id) |> length optimalCount = countSuccess(optimalTrial) randomCount = countSuccess(randomTrial) output = format("optimal: {} / {} = {} prob\nrandom: {} / {} = {} prob", [ optimalCount, numTrials, optimalCount / numTrials, randomCount, numTrials, randomCount / numTrials, ]) |> println