Data update
This commit is contained in:
parent
35bcdeebf8
commit
74c69a0df6
2427 changed files with 31826 additions and 3468 deletions
|
|
@ -1,30 +1,28 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">play<span style="color: #0000FF;">(<span style="color: #004080;">integer</span> <span style="color: #000000;">prisoners<span style="color: #0000FF;">,</span> <span style="color: #000000;">iterations<span style="color: #0000FF;">,</span> <span style="color: #004080;">bool</span> <span style="color: #000000;">optimal<span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">drawers</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">shuffle<span style="color: #0000FF;">(<span style="color: #7060A8;">tagset<span style="color: #0000FF;">(<span style="color: #000000;">prisoners<span style="color: #0000FF;">)<span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">pardoned</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
|
||||
<span style="color: #004080;">bool</span> <span style="color: #000000;">found</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i<span style="color: #0000FF;">=<span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">iterations</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">drawers</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">shuffle<span style="color: #0000FF;">(<span style="color: #000000;">drawers<span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">prisoner<span style="color: #0000FF;">=<span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">prisoners</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">found</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">drawer</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff<span style="color: #0000FF;">(<span style="color: #000000;">optimal<span style="color: #0000FF;">?<span style="color: #000000;">prisoner<span style="color: #0000FF;">:<span style="color: #7060A8;">rand<span style="color: #0000FF;">(<span style="color: #000000;">prisoners<span style="color: #0000FF;">)<span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">j<span style="color: #0000FF;">=<span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">prisoners<span style="color: #0000FF;">/<span style="color: #000000;">2</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">drawer</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">drawers<span style="color: #0000FF;">[<span style="color: #000000;">drawer<span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">drawer<span style="color: #0000FF;">==<span style="color: #000000;">prisoner</span> <span style="color: #008080;">then</span> <span style="color: #000000;">found</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">optimal</span> <span style="color: #008080;">then</span> <span style="color: #000000;">drawer</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">rand<span style="color: #0000FF;">(<span style="color: #000000;">prisoners<span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">found</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #000000;">pardoned</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">found</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">100<span style="color: #0000FF;">*<span style="color: #000000;">pardoned<span style="color: #0000FF;">/<span style="color: #000000;">iterations</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
function play(integer prisoners, iterations, bool optimal)
|
||||
sequence drawers = shuffle(tagset(prisoners))
|
||||
integer pardoned = 0
|
||||
bool found = false
|
||||
for i=1 to iterations do
|
||||
drawers = shuffle(drawers)
|
||||
for prisoner=1 to prisoners do
|
||||
found = false
|
||||
integer drawer = iff(optimal?prisoner:rand(prisoners))
|
||||
for j=1 to prisoners/2 do
|
||||
drawer = drawers[drawer]
|
||||
if drawer==prisoner then found = true exit end if
|
||||
if not optimal then drawer = rand(prisoners) end if
|
||||
end for
|
||||
if not found then exit end if
|
||||
end for
|
||||
pardoned += found
|
||||
end for
|
||||
return 100*pardoned/iterations
|
||||
end function
|
||||
|
||||
<span style="color: #008080;">constant</span> <span style="color: #000000;">iterations</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">100<span style="color: #000000;">_000</span>
|
||||
<span style="color: #7060A8;">printf<span style="color: #0000FF;">(<span style="color: #000000;">1<span style="color: #0000FF;">,<span style="color: #008000;">"Simulation count: %d\n"<span style="color: #0000FF;">,<span style="color: #000000;">iterations<span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">prisoners<span style="color: #0000FF;">=<span style="color: #000000;">10</span> <span style="color: #008080;">to</span> <span style="color: #000000;">100</span> <span style="color: #008080;">by</span> <span style="color: #000000;">90</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">random</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">play<span style="color: #0000FF;">(<span style="color: #000000;">prisoners<span style="color: #0000FF;">,<span style="color: #000000;">iterations<span style="color: #0000FF;">,<span style="color: #004600;">false<span style="color: #0000FF;">)<span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">optimal</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">play<span style="color: #0000FF;">(<span style="color: #000000;">prisoners<span style="color: #0000FF;">,<span style="color: #000000;">iterations<span style="color: #0000FF;">,<span style="color: #004600;">true<span style="color: #0000FF;">)</span>
|
||||
<span style="color: #7060A8;">printf<span style="color: #0000FF;">(<span style="color: #000000;">1<span style="color: #0000FF;">,<span style="color: #008000;">"Prisoners:%d, random:%g, optimal:%g\n"<span style="color: #0000FF;">,<span style="color: #0000FF;">{<span style="color: #000000;">prisoners<span style="color: #0000FF;">,<span style="color: #000000;">random<span style="color: #0000FF;">,<span style="color: #000000;">optimal<span style="color: #0000FF;">}<span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for
|
||||
<!--
|
||||
constant iterations = 100_000
|
||||
printf(1,"Simulation count: %d\n",iterations)
|
||||
for prisoners in {10,100} do
|
||||
atom random = play(prisoners,iterations,false),
|
||||
optimal = play(prisoners,iterations,true)
|
||||
printf(1,"Prisoners:%d, random:%g, optimal:%g\n",{prisoners,random,optimal})
|
||||
end for
|
||||
|
|
|
|||
59
Task/100-prisoners/SETL/100-prisoners.setl
Normal file
59
Task/100-prisoners/SETL/100-prisoners.setl
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
program prisoners;
|
||||
setrandom(0);
|
||||
|
||||
strategies := {
|
||||
["Optimal", routine optimal_strategy],
|
||||
["Random", routine random_strategy]
|
||||
};
|
||||
|
||||
runs := 10000;
|
||||
|
||||
loop for strategy = strategies(name) do
|
||||
successes := run_simulations(strategy, runs);
|
||||
print(rpad(name + ":", 10), successes * 100 / runs, "%");
|
||||
end loop;
|
||||
|
||||
proc run_simulations(strategy, amount);
|
||||
loop for i in [1..amount] do
|
||||
successes +:= if simulate(strategy) then 1 else 0 end;
|
||||
end loop;
|
||||
return successes;
|
||||
end proc;
|
||||
|
||||
proc simulate(strategy);
|
||||
drawers := [1..100];
|
||||
shuffle(drawers);
|
||||
loop for prisoner in [1..100] do
|
||||
if not call(strategy, drawers, prisoner) then
|
||||
return false;
|
||||
end if;
|
||||
end loop;
|
||||
return true;
|
||||
end proc;
|
||||
|
||||
proc optimal_strategy(drawers, prisoner);
|
||||
d := prisoner;
|
||||
loop for s in [1..50] do
|
||||
if (d := drawers(d)) = prisoner then
|
||||
return true;
|
||||
end if;
|
||||
end loop;
|
||||
return false;
|
||||
end proc;
|
||||
|
||||
proc random_strategy(drawers, prisoner);
|
||||
loop for s in [1..50] do
|
||||
if drawers(1+random(#drawers-1)) = prisoner then
|
||||
return true;
|
||||
end if;
|
||||
end loop;
|
||||
return false;
|
||||
end proc;
|
||||
|
||||
proc shuffle(rw drawers);
|
||||
loop for i in [1..#drawers] do
|
||||
j := i+random(#drawers-i);
|
||||
[drawers(i), drawers(j)] := [drawers(j), drawers(i)];
|
||||
end loop;
|
||||
end proc;
|
||||
end program;
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import "random" for Random
|
||||
import "/fmt" for Fmt
|
||||
import "./fmt" for Fmt
|
||||
|
||||
var rand = Random.new()
|
||||
|
||||
|
|
@ -40,8 +40,8 @@ var doTrials = Fn.new{ |trials, np, strategy|
|
|||
}
|
||||
}
|
||||
if (!nextPrisoner) {
|
||||
nextTrial = true
|
||||
break
|
||||
nextTrial = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!nextTrial) pardoned = pardoned + 1
|
||||
|
|
|
|||
128
Task/100-prisoners/Zig/100-prisoners-1.zig
Normal file
128
Task/100-prisoners/Zig/100-prisoners-1.zig
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub const Cupboard = struct {
|
||||
comptime {
|
||||
std.debug.assert(u7 == std.math.IntFittingRange(0, 100));
|
||||
}
|
||||
|
||||
pub const Drawer = packed struct(u8) {
|
||||
already_visited: bool,
|
||||
card: u7,
|
||||
};
|
||||
|
||||
drawers: [100]Drawer,
|
||||
randomizer: std.rand.Random,
|
||||
|
||||
/// Cupboard is not shuffled after initialization,
|
||||
/// it is shuffled during `play` execution.
|
||||
pub fn init(random: std.rand.Random) Cupboard {
|
||||
var drawers: [100]Drawer = undefined;
|
||||
for (&drawers, 0..) |*drawer, i| {
|
||||
drawer.* = .{
|
||||
.already_visited = false,
|
||||
.card = @intCast(i),
|
||||
};
|
||||
}
|
||||
|
||||
return .{
|
||||
.drawers = drawers,
|
||||
.randomizer = random,
|
||||
};
|
||||
}
|
||||
|
||||
pub const Decision = enum {
|
||||
pardoned,
|
||||
sentenced,
|
||||
};
|
||||
|
||||
pub const Strategy = enum {
|
||||
follow_card,
|
||||
random,
|
||||
|
||||
pub fn decisionOfPrisoner(strategy: Strategy, cupboard: *Cupboard, prisoner_id: u7) Decision {
|
||||
switch (strategy) {
|
||||
.random => {
|
||||
return for (0..50) |_| {
|
||||
// If randomly chosen drawer was already opened,
|
||||
// throw dice again.
|
||||
const drawer = try_throw_random: while (true) {
|
||||
const random_i = cupboard.randomizer.uintLessThan(u7, 100);
|
||||
const drawer = &cupboard.drawers[random_i];
|
||||
|
||||
if (!drawer.already_visited)
|
||||
break :try_throw_random drawer;
|
||||
};
|
||||
std.debug.assert(!drawer.already_visited);
|
||||
defer drawer.already_visited = true;
|
||||
|
||||
if (drawer.card == prisoner_id)
|
||||
break .pardoned;
|
||||
} else .sentenced;
|
||||
},
|
||||
.follow_card => {
|
||||
var drawer_i = prisoner_id;
|
||||
return for (0..50) |_| {
|
||||
const drawer = &cupboard.drawers[drawer_i];
|
||||
std.debug.assert(!drawer.already_visited);
|
||||
defer drawer.already_visited = true;
|
||||
|
||||
if (drawer.card == prisoner_id)
|
||||
break .pardoned
|
||||
else
|
||||
drawer_i = drawer.card;
|
||||
} else .sentenced;
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
pub fn play(cupboard: *Cupboard, strategy: Strategy) Decision {
|
||||
cupboard.randomizer.shuffleWithIndex(Drawer, &cupboard.drawers, u7);
|
||||
|
||||
// Decisions for all 100 prisoners.
|
||||
var all_decisions: [100]Decision = undefined;
|
||||
for (&all_decisions, 0..) |*current_decision, prisoner_id| {
|
||||
// Make decision for current prisoner
|
||||
current_decision.* = strategy.decisionOfPrisoner(cupboard, @intCast(prisoner_id));
|
||||
|
||||
// Close all drawers after one step.
|
||||
for (&cupboard.drawers) |*drawer|
|
||||
drawer.already_visited = false;
|
||||
}
|
||||
|
||||
// If there is at least one sentenced person, everyone are sentenced.
|
||||
return for (all_decisions) |decision| {
|
||||
if (decision == .sentenced)
|
||||
break .sentenced;
|
||||
} else .pardoned;
|
||||
}
|
||||
|
||||
pub fn runSimulation(cupboard: *Cupboard, strategy: Cupboard.Strategy, total: u32) void {
|
||||
var success: u32 = 0;
|
||||
for (0..total) |_| {
|
||||
const result = cupboard.play(strategy);
|
||||
if (result == .pardoned) success += 1;
|
||||
}
|
||||
|
||||
const ratio = @as(f32, @floatFromInt(success)) / @as(f32, @floatFromInt(total));
|
||||
|
||||
const stdout = std.io.getStdOut();
|
||||
const stdout_w = stdout.writer();
|
||||
|
||||
stdout_w.print(
|
||||
\\
|
||||
\\Strategy: {s}
|
||||
\\Total runs: {d}
|
||||
\\Successful runs: {d}
|
||||
\\Failed runs: {d}
|
||||
\\Success rate: {d:.4}%.
|
||||
\\
|
||||
, .{
|
||||
@tagName(strategy),
|
||||
total,
|
||||
success,
|
||||
total - success,
|
||||
ratio * 100.0,
|
||||
}) catch {}; // Do nothing on error
|
||||
}
|
||||
};
|
||||
15
Task/100-prisoners/Zig/100-prisoners-2.zig
Normal file
15
Task/100-prisoners/Zig/100-prisoners-2.zig
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
const std = @import("std");
|
||||
|
||||
pub fn main() std.os.GetRandomError!void {
|
||||
var prnd = std.rand.DefaultPrng.init(seed: {
|
||||
var init_seed: u64 = undefined;
|
||||
try std.os.getrandom(std.mem.asBytes(&init_seed));
|
||||
break :seed init_seed;
|
||||
});
|
||||
const random = prnd.random();
|
||||
|
||||
var cupboard = Cupboard.init(random);
|
||||
|
||||
cupboard.runSimulation(.follow_card, 10_000);
|
||||
cupboard.runSimulation(.random, 10_000);
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue