Created
June 6, 2018 17:18
-
-
Save realsonic/1912f669fe8139716ed7372d0b571c46 to your computer and use it in GitHub Desktop.
Doors
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
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
namespace Doors | |
{ | |
internal class Program | |
{ | |
private const int ITERATIONS = 10_000_000; | |
//private const int SEED = 0; | |
private static void Main(string[] args) | |
{ | |
// маппинги номер двери <-> value tuple флага двери | |
var numberTupleMap = new Dictionary<int, (bool Door1, bool Door2, bool Door3)> | |
{ | |
{1, (Door1: true, Door2: false, Door3: false)}, | |
{2, (Door1: false, Door2: true, Door3: false)}, | |
{3, (Door1: false, Door2: false, Door3: true)} | |
}; | |
Dictionary<(bool Door1, bool Door2, bool Door3), int> tupleNumberMap = | |
numberTupleMap.ToDictionary(pair => pair.Value, pair => pair.Key); | |
// функции конвертации номер двери <-> value tuple флага двери | |
(bool Door1, bool Door2, bool Door3) TupleByNumber(int doorNumber) => | |
numberTupleMap[doorNumber]; | |
int NumberByTuple((bool Door1, bool Door2, bool Door3) tuple) => tupleNumberMap[tuple]; | |
var random = new Random( /*SEED*/); | |
T RandomFrom<T>(IReadOnlyList<T> list) | |
{ | |
int randomIndex = random.Next(0, list.Count); | |
return list[randomIndex]; | |
} | |
// расставим двери | |
List<(bool Door1, bool Door2, bool Door3)> doorsIters = Enumerable | |
.Range(1, ITERATIONS) | |
.Select(i => random.Next(1, 4)) | |
.Select(TupleByNumber) | |
.ToList(); | |
// посчитаем кол-во дверей | |
var winDoorsCount = doorsIters | |
.GroupBy(i => i) | |
.Select(dg => new {Tuple = dg.Key, Quantity = dg.Count()}) | |
.OrderBy(dq => NumberByTuple(dq.Tuple)) | |
.ToList(); | |
// кол-во всех дверей | |
int allDoorsQty = doorsIters.Count; | |
// выводим процентный разброс дверей | |
foreach (var doorCount in winDoorsCount) { | |
Console.WriteLine( | |
$"Door #{NumberByTuple(doorCount.Tuple)} - quantity {doorCount.Quantity}, procentile: {(double) doorCount.Quantity / allDoorsQty:P}"); | |
} | |
/* для каждой итерации надо провести: | |
выбрать дверь случайно, далее открыть (убрать из выбора) любую пустую дверь; | |
далее: | |
вариант 1: не менять выбор; если выбор верный - посчитать как удачу в вар.1 | |
вариант 2: поменять выбор - выбрать оставшуюся дверь; если выбор верный - посчитать как удачу в вар.2 | |
*/ | |
// выбираем дверь | |
var selectedDoors = doorsIters.Select(tuple => new | |
{ | |
// выбираем дверь | |
SelectedDoor = random.Next(1, 4), | |
// передаём выйгрышную дверь | |
WinDoor = NumberByTuple(tuple) | |
}) | |
.ToList(); | |
// вариант 1: не менять выбор | |
int var1Qty = selectedDoors.Count(sd => sd.SelectedDoor == sd.WinDoor); | |
// вариант 2: поменять выбор - выбрать оставшуюся дверь | |
var doorsFullSet = new[] {1, 2, 3}; | |
var var2Data = selectedDoors.Select(sd => new | |
{ | |
// открываем пустую дверь | |
OpenDoor = | |
RandomFrom( | |
doorsFullSet.Except(new[] {sd.SelectedDoor, sd.WinDoor}).ToList()), | |
// передаём выйгрышную дверь | |
sd.WinDoor, | |
// передаём выбранную дверь | |
sd.SelectedDoor | |
}) | |
.Select(sd => new | |
{ | |
// выбираем оставшуюся закрытой дверь | |
SecondSelectedDoor = | |
RandomFrom(doorsFullSet.Except(new[] {sd.SelectedDoor, sd.OpenDoor}) | |
.ToList()), | |
// передаём открытую дверь | |
sd.OpenDoor, | |
// передаём выйгрышную дверь | |
sd.WinDoor, | |
// передаём выбранную дверь | |
sd.SelectedDoor | |
}); | |
int var2Qty = var2Data.Count(sd => sd.SecondSelectedDoor == sd.WinDoor); | |
// выводим результаты | |
Console.WriteLine( | |
$"Win % for variant 1 (don't change selection): \t{(double) var1Qty / allDoorsQty:P}"); | |
Console.WriteLine( | |
$"Win % for variant 2 (do change selection): \t{(double) var2Qty / allDoorsQty:P}"); | |
Console.Write("End. Press ENTER: "); | |
Console.ReadLine(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment