import Data.List
--`combinaciones n xs` obtiene una lista con todos los subconjuntos de `n` elementos de `xs`
combinaciones = (. subsequences) . filter . (. length) . (==)
--`binom n r` es la cantidad de combinaciones de `n` elementos tomados de `r` en `r` (coeficiente binomial)
binom n r = product [1+n-r..n] `div` product [1..r]
--`p n s` devuelve la probabilidad de obtener `s` como suma de `n` dados diferentes (o el mismo, arrojado secuencialmente `n` veces)
p :: Int -> Int -> Rational
p n s = c/6^n
where
c = fromIntegral $ sum $ map (\k -> (-1)^k*(binom n k)*(binom (s-6*k-1) (n-1))) [0..div (s-n) 6]
--`empate n` retorna la probabilidad de que haya un empate si 6 jugadores arrojan el dado `n` veces y el puntaje que obtienen es la suma de las `n` tiradas
empate :: Int -> Rational
empate n = 1 - 720 * (sum $ map (product . map (p n)) combs)
where combs = combinaciones 6 [n..6*n]