-- | Calculs de combinaisons. module Htirage.Combin where -- | @n`nCk`k@ retourne le nombre de combinaisons -- de longueur 'k' d’un ensemble de longueur 'n'. nCk :: Integral i => i -> i -> i n`nCk`k | n<0||k<0||n n `div` 2 = go n (n - k) -- more efficient and safe with smaller numbers | otherwise = go n k where go i j | j == 0 = 1 | otherwise = go i (j-1) * (i-j+1) `div` j -- | @combinOfRank n k r@ retourne les indices de permutation -- de la combinaison de 'k' entiers parmi @[1..n]@ -- au rang lexicographique 'r' dans @[0..(n`nCk`k)-1]@. -- -- Construit chaque choix de la combinaison en prenant le prochain plus grand -- dont le successeur engendre un nombre de combinaisons -- qui dépasse le rang restant à atteindre. -- -- DOC: , p.26 combinOfRank :: Integral i => i -> i -> i -> [i] combinOfRank n k rk | rk<0||n`nCk`k, pp.24-25 -- -- @ -- 'rankOfCombin' n ('combinOfRank' n k r) == r -- 'combinOfRank' n ('length' ns) ('rankOfCombin' n ns) == ns -- @ rankOfCombin :: Integral i => i -> [i] -> i rankOfCombin n ns | any (\x -> x<1||n [a] -> [a] permute ps xs = [xs !! pred p | p <- ps]