Skip to content

Instantly share code, notes, and snippets.

@JoolsF
Last active June 2, 2022 21:20
Show Gist options
  • Save JoolsF/219ddd0c17dca65b4c5e0c69619d2933 to your computer and use it in GitHub Desktop.
Save JoolsF/219ddd0c17dca65b4c5e0c69619d2933 to your computer and use it in GitHub Desktop.
Monty Hall problem simulator
import scala.util.Random.nextInt
//https://en.wikipedia.org/wiki/Monty_Hall_problem
case class MontyHallProblem(printActive: Boolean) {
def playMany(gameCount: Int, stick: Boolean): Double = {
val results = for (_ <- 1 to gameCount) yield playOne(nextLetter, stick)
val wins = results.count(_ == true)
val percentWon = (wins.doubleValue / gameCount.doubleValue()) * 100
percentWon
}
def playOne(guess: String, stickToOriginalGuess: Boolean): Boolean = {
val gameDoors = chooseDoors
val winningDoor = gameDoors.find(_.prize).head.value
printStrLn(s"HOST: Guess is $guess")
printStrLn(s"(Winning door is $winningDoor)")
val (opened, remaining) = openedAndRemainingDoors(guess, gameDoors)
printStrLn(
s"HOST: Winning door is not ${opened.value}. The remaining doors are ${remaining.map(_.value) mkString ", "}." +
s" Do you want to stick to $guess?"
)
printStrLn(s"CONTESTANT: I ${if (stickToOriginalGuess) "do" else "dont"} want to stick")
def result =
if (stickToOriginalGuess) {
guess == winningDoor
} else {
remaining.filterNot(_.value == guess).head.prize
}
printStrLn(s"HOST: You ${if (result) "won!" else "did not win!"}\n*************\n\n")
result
}
private def chooseDoors = {
val index = nextInt(3)
doors(index)
}
private def openedAndRemainingDoors(guess: String, doors: List[Door]): (Door, List[Door]) = {
val notGuess = doors.filterNot(_.value == guess)
val notGuessWithoutPrize = notGuess.filterNot(_.prize)
val openedDoor =
if (notGuessWithoutPrize.length == 1)
notGuessWithoutPrize.head
else
notGuessWithoutPrize(nextInt(2))
val remainingDoors = doors.filterNot(_.value == openedDoor.value)
(openedDoor, remainingDoors)
}
private def nextLetter: String = {
List("a", "b", "c")(nextInt(3))
}
private def printStrLn(str: String) = {
if (printActive)
println(str)
else ()
}
private def doors =
List(
List(
Door("a", true),
Door("b", false),
Door("c", false)
),
List(
Door("a", false),
Door("b", true),
Door("c", false)
),
List(
Door("a", false),
Door("b", false),
Door("c", true)
)
)
case class Door(value: String, prize: Boolean)
}
//MontyHallProblem(false).playMany(5000, true)
MontyHallProblem(true).playOne("a", true)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment