100 prisoners: Difference between revisions

Content added Content deleted
(→‎{{header|Tcl}}: Add implementation.)
(→‎{{header|JavaScript}}: Added Javascript school example)
Line 3,095: Line 3,095:
console.log("Random Play Success Rate: " + execRandom());
console.log("Random Play Success Rate: " + execRandom());
</lang>
</lang>

===School example===

{{works with|JavaScript|Node.js 16.13.0 (LTS)}}

<lang JavaScript>"use strict";

// Simulate several thousand instances of the game:
const gamesCount = 2000;

// ...where the prisoners randomly open drawers.
const randomResults = playGame(gamesCount, randomStrategy);

// ...where the prisoners use the optimal strategy mentioned in the Wikipedia article.
const optimalResults = playGame(gamesCount, optimalStrategy);

// Show and compare the computed probabilities of success for the two strategies.
console.log(`Games count: ${gamesCount}`);
console.log(`Probability of success with "random" strategy: ${computeProbability(randomResults, gamesCount)}`);
console.log(`Probability of success with "optimal" strategy: ${computeProbability(optimalResults, gamesCount)}`);

function playGame(gamesCount, strategy, prisonersCount = 100) {
const results = new Array();

for (let game = 1; game <= gamesCount; game++) {
// A room having a cupboard of 100 opaque drawers numbered 1 to 100, that cannot be seen from outside.
// Cards numbered 1 to 100 are placed randomly, one to a drawer, and the drawers all closed; at the start.
const drawers = initDrawers(prisonersCount);

// A prisoner tries to find his own number.
// Prisoners start outside the room.
// They can decide some strategy before any enter the room.
const findings = new Array();
for (let prisoner = 1; prisoner <= prisonersCount; prisoner++)
findings.push(find(prisoner, drawers, strategy));

// If all 100 findings find their own numbers then they will all be pardoned. If any don't then all sentences stand.
results.push((findings.filter(p => p == true).length == prisonersCount));
}

return results;
}

function find(prisoner, drawers, strategy) {
// A prisoner can open no more than 50 drawers.
const openMax = Math.floor(drawers.length / 2);

// Prisoners start outside the room.
let card;
for (let open = 0; open < openMax; open++) {
// A prisoner tries to find his own number.
card = strategy(prisoner, drawers, card);

// A prisoner finding his own number is then held apart from the others.
if (card == prisoner)
break;
}

return (card == prisoner);
}

function randomStrategy(prisoner, drawers, card) {
// Simulate the game where the prisoners randomly open drawers.

const min = 0;
const max = drawers.length - 1;

return drawers[draw(min, max)];
}

function optimalStrategy(prisoner, drawers, card) {
// Simulate the game where the prisoners use the optimal strategy mentioned in the Wikipedia article.

// First opening the drawer whose outside number is his prisoner number.
// If the card within has his number then he succeeds...
if (typeof card === "undefined")
return drawers[prisoner - 1];
// ...otherwise he opens the drawer with the same number as that of the revealed card.
return drawers[card - 1];
}

function initDrawers(prisonersCount) {
const drawers = new Array();
for (let card = 1; card <= prisonersCount; card++)
drawers.push(card);

return shuffle(drawers);
}

function shuffle(drawers) {
const min = 0;
const max = drawers.length - 1;
for (let i = min, j; i < max; i++) {
j = draw(min, max);
if (i != j)
[drawers[i], drawers[j]] = [drawers[j], drawers[i]];
}

return drawers;
}

function draw(min, max) {
// See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
return Math.floor(Math.random() * (max - min + 1)) + min;
}

function computeProbability(results, gamesCount) {
return Math.round(results.filter(x => x == true).length * 10000 / gamesCount) / 100;
}</lang>

Output:

<lang>Games count: 2000
Probability of success with "random" strategy: 0
Probability of success with "optimal" strategy: 33.2</lang>


=={{header|Julia}}==
=={{header|Julia}}==