Created
July 1, 2022 19:14
-
-
Save 190n/799621a3b46dde83c462d5041f894526 to your computer and use it in GitHub Desktop.
100 prisoners in zig
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// based on https://www.youtube.com/watch?v=iSNsgj1OCLA | |
const std = @import("std"); | |
const Strategy = fn (my_num: u32, boxes: [100]u32, random: std.rand.Random) bool; | |
fn searchRandom(my_num: u32, boxes: [100]u32, random: std.rand.Random) bool { | |
var i: u32 = 0; | |
var tried = [_]bool{false} ** 100; | |
while (i < 50) : (i += 1) { | |
const guess = blk: { | |
while (true) { | |
const maybe_guess = random.intRangeLessThan(u32, 0, 100); | |
if (!tried[maybe_guess]) { | |
break :blk maybe_guess; | |
} | |
} | |
}; | |
tried[guess] = true; | |
if (boxes[guess] == my_num) { | |
return true; | |
} | |
} | |
return false; | |
} | |
fn searchLoop(my_num: u32, boxes: [100]u32, random: std.rand.Random) bool { | |
_ = random; | |
var i: u32 = 0; | |
var guess = my_num; | |
while (i < 50) : (i += 1) { | |
if (boxes[guess] == my_num) { | |
return true; | |
} | |
guess = boxes[guess]; | |
} | |
return false; | |
} | |
fn group(boxes: [100]u32, random: std.rand.Random, strategy: Strategy) u32 { | |
var i: u32 = 0; | |
var succeeded: u32 = 0; | |
while (i < 100) : (i += 1) { | |
if (strategy(i, boxes, random)) { | |
succeeded += 1; | |
} | |
} | |
return succeeded; | |
} | |
pub fn main() !void { | |
var prng = std.rand.DefaultPrng.init(blk: { | |
var seed: u64 = undefined; | |
try std.os.getrandom(@ptrCast([*]u8, &seed)[0..@sizeOf(u64)]); | |
break :blk seed; | |
}); | |
const random = prng.random(); | |
var boxes = comptime blk: { | |
var wip: [100]u32 = undefined; | |
var i: u32 = 0; | |
while (i < 100) : (i += 1) { | |
wip[i] = i; | |
} | |
break :blk wip; | |
}; | |
const stdout = std.io.getStdOut().writer(); | |
const strats = [_]struct { name: []const u8, func: Strategy }{ | |
.{ .name = "random", .func = searchRandom }, | |
.{ .name = "loop", .func = searchLoop }, | |
}; | |
const iters = 250_000; | |
for (strats) |strat| { | |
var prisoner_win: u32 = 0; | |
var group_win: u32 = 0; | |
var i: u32 = 0; | |
while (i < iters) : (i += 1) { | |
random.shuffle(u32, &boxes); | |
const num_passed = group(boxes, random, strat.func); | |
prisoner_win += num_passed; | |
if (num_passed == 100) { | |
group_win += 1; | |
} | |
try stdout.print("{}\n", .{num_passed}); | |
} | |
try std.io.getStdErr().writer().print( | |
\\== Strategy "{s}" == | |
\\Pass rate (prisoner): {d}% | |
\\Pass rate (group): {d}% | |
\\ | |
\\ | |
, .{ strat.name, @intToFloat(f64, prisoner_win) / (iters * 100) * 100.0, @intToFloat(f64, group_win) / iters * 100 }); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment