Last active
August 29, 2015 14:11
-
-
Save TeWu/93b839591a809eeb5227 to your computer and use it in GitHub Desktop.
100 Prisoners problem simulation
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
import scala.collection.immutable.TreeMap | |
import scala.util.Random | |
/* 100 prisoners problem - simulation of various strategies | |
* Decription at: | |
* - http://en.m.wikipedia.org/wiki/100_prisoners_problem | |
* - https://www.youtube.com/watch?v=eivGlBKlK6M | |
*/ | |
object IBSim { | |
/* Configuration */ | |
val n = 100 | |
val pickCount = (n / 2.0).toInt | |
/* ------------- */ | |
val nums = (1 to n).toList | |
def main(args: Array[String]) { | |
val trialsCount = 10000 | |
testStrategy("Cheat", CheatStrategy.apply, 10) | |
testStrategy("Random Pick", RandomPickStrategy.apply, trialsCount) | |
testStrategy("Correlated Pick", CorrelatedPickStrategy.apply, trialsCount) | |
testStrategy("Traverse Pick", TraversePickStrategy.apply, trialsCount) | |
} | |
def testStrategy(strategyName: String, strategy: (Map[Int, Int] => Boolean), trialsCount: Int) = { | |
var wins = 0 | |
for (_ <- 1 to trialsCount) { | |
val boxes = TreeMap.empty[Int, Int] ++ nums.zip(Random shuffle nums) | |
if (strategy(boxes)) wins += 1 | |
} | |
val proc = (wins / trialsCount.toDouble) * 100 | |
println(s"$strategyName Strategy\nWins = $wins\nEfficiency = $proc%\n") | |
} | |
object CheatStrategy { | |
def apply(boxes: Map[Int, Int]) = { | |
val isFoundOwnNumber = nums map { | |
num => | |
val pickedBoxed = Random shuffle nums | |
(pickedBoxed map boxes) contains num | |
} | |
isFoundOwnNumber forall (_ == true) | |
} | |
} | |
object RandomPickStrategy { | |
def apply(boxes: Map[Int, Int]) = { | |
val isFoundOwnNumber = nums map { | |
num => | |
val pickedBoxed = (Random shuffle nums) take pickCount | |
(pickedBoxed map boxes) contains num | |
} | |
isFoundOwnNumber forall (_ == true) | |
} | |
} | |
object CorrelatedPickStrategy { | |
def apply(boxes: Map[Int, Int]) = { | |
val isFoundOwnNumber = nums map { | |
num => | |
val pickedBoxed = (nums ++ nums).drop(num - 1).take(pickCount) | |
(pickedBoxed map boxes) contains num | |
} | |
isFoundOwnNumber forall (_ == true) | |
} | |
} | |
object TraversePickStrategy { | |
def apply(boxes: Map[Int, Int]) = { | |
val isFoundOwnNumber = nums map { | |
num => | |
var picks = List.empty[Int] | |
var next = num | |
for (i <- 1 to pickCount) { | |
val pick = boxes(next) | |
picks = pick :: picks | |
next = pick | |
} | |
picks.contains(num) | |
} | |
isFoundOwnNumber forall (_ == true) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment