100 prisoners: Difference between revisions
Content added Content deleted
(added output) |
|||
Line 3,738: | Line 3,738: | ||
Random play wins: 0.00000000% of simulations. |
Random play wins: 0.00000000% of simulations. |
||
Optimal play wins: 31.18100000% of simulations. |
Optimal play wins: 31.18100000% of simulations. |
||
</pre> |
|||
=={{header|Koka}}== |
|||
Imperative equivalent (using mutable vectors, but also with exceptional control flow) |
|||
<syntaxhighlight lang="koka"> |
|||
import std/num/random |
|||
value struct drawer |
|||
num: int |
|||
open: bool = False |
|||
inline extern unsafe-assign : forall<a> ( v : vector<a>, i : ssize_t, x : a ) -> total () |
|||
c "kk_vector_unsafe_assign" |
|||
fun createDrawers() |
|||
val drawers = vector(100, Drawer(0,open=True)) |
|||
for(0, 99) fn(i) |
|||
var found := False |
|||
while {!found} |
|||
val r = random-int() % 100 |
|||
if drawers[r].open then |
|||
drawers.unsafe-assign(r.ssize_t, Drawer(i)) |
|||
found := True |
|||
else |
|||
() |
|||
drawers |
|||
fun closeAll(d:vector<drawer>) |
|||
for(0,99) fn(i) |
|||
d.unsafe-assign(i.ssize_t, d[i](open=False)) |
|||
effect fail |
|||
final ctl failed(): a |
|||
fun open-random(drawers: vector<drawer>) |
|||
val r = random-int() % 100 |
|||
val opened = drawers[r] |
|||
if opened.open then |
|||
open-random(drawers) |
|||
else |
|||
drawers.unsafe-assign(r.ssize_t, opened(open=True)) |
|||
opened.num |
|||
fun random-approach(drawers: vector<drawer>) |
|||
for(0, 99) fn(i) |
|||
var found := False |
|||
for(0, 49) fn(j) |
|||
val opened = open-random(drawers) |
|||
if opened == i then |
|||
found := True |
|||
else |
|||
() |
|||
if !found then |
|||
failed() |
|||
else |
|||
drawers.closeAll() |
|||
fun optimal-approach(drawers: vector<drawer>) |
|||
for(0, 99) fn(i) |
|||
var found := False |
|||
var drawer := i; |
|||
for(0, 49) fn(j) |
|||
val opened = drawers[drawer] |
|||
if opened.open then |
|||
failed() |
|||
if opened.num == i then |
|||
found := True |
|||
else |
|||
drawers.unsafe-assign(drawer.ssize_t, opened(open=True)) |
|||
drawer := opened.num |
|||
if !found then |
|||
failed() |
|||
else |
|||
drawers.closeAll() |
|||
() |
|||
fun run-trials(f, num-trials) |
|||
var num_success := 0 |
|||
for(0,num-trials - 1) fn(i) |
|||
val drawers = createDrawers() |
|||
with handler |
|||
return(x) -> |
|||
num_success := num_success + 1 |
|||
final ctl failed() -> |
|||
() |
|||
f(drawers) |
|||
num_success |
|||
fun main() |
|||
val num_trials = 1000 |
|||
val num_success_random = run-trials(random-approach, num_trials) |
|||
val num_success_optimal = run-trials(optimal-approach, num_trials) |
|||
println("Number of trials: " ++ num_trials.show) |
|||
println("Random approach: wins " ++ num_success_random.show ++ " (" ++ (num_success_random.float64 * 100.0 / num_trials.float64).show(2) ++ "%)") |
|||
println("Optimal approach: wins " ++ num_success_optimal.show ++ " (" ++ (num_success_optimal.float64 * 100.0 / num_trials.float64).show(2) ++ "%)") |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
Number of trials: 1000 |
|||
Random approach: wins 0 (0.00%) |
|||
Optimal approach: wins 319 (31.90%) |
|||
</pre> |
</pre> |
||