Skip to content

Instantly share code, notes, and snippets.

@Profpatsch
Created November 14, 2021 15:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Profpatsch/089da6c804f71d36351e4ef68cb62386 to your computer and use it in GitHub Desktop.
Save Profpatsch/089da6c804f71d36351e4ef68cb62386 to your computer and use it in GitHub Desktop.
How many people do you have to meet to have a 50% chance somebody has Covid at an incidence of 500 (in 100k people)

This is a simulation we wrote to understand whether ln(1-0.5) / ln(1-500/100000) is the right formula to apply here.

module Main where
import System.Random
import Data.Ratio
import Data.Bifunctor
-- | Returns for a bunch of people you meet , with a chance of 1/200 for each person, whether any has Covid
randomPeople200 :: (RandomGen gen) => Int -> gen -> (Bool, gen)
randomPeople200 numberOfPeople =
first anyHasCovid . runGeneratorNTimes numberOfPeople 0 (uniformR (1, 200::Int))
anyHasCovid :: [Int] -> Bool
anyHasCovid = any (== 1)
runGeneratorNTimes :: (RandomGen gen) => Int -> a -> (gen -> (a, gen)) -> gen -> ([a], gen)
runGeneratorNTimes times ignored f gen = do
let (gen1, genRes) = split gen
(map fst . take times . drop 1 $ iterate (\(_old, gen) -> f gen) (ignored, gen1), genRes)
percentage ls = realToFrac (100 * (length (filter (==True) ls) % length ls))
main = do
gen <- newStdGen
print $ fst $ randomPeople200 15 gen
print $ percentage $ fst $ runGeneratorNTimes 1000 False (randomPeople200 138) gen
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment