import Data.Ord import Data.List import Data.Function dice n = [1..n] combinations xs ys = concat $ map (\y -> map (\x -> x : y) xs) ys diceCombinations n k = foldr (combinations) (map return diceN) (replicate (k - 1) diceN) where diceN = dice n mapFst f xs = map (\(x, y) -> (f x, y)) xs isEq :: Ordering -> Bool isEq EQ = True isEq _ = False elementCounts :: (a -> a -> Ordering) -> [a] -> [(a, Int)] elementCounts f xs = map (\ys -> (head ys, length ys)) $ groupBy (\x y -> isEq $ f x y) $ sortBy f xs diceModuloCounts k = groupModCounts where diceCounts = elementCounts compare $ map sum $ diceCombinations 6 k modCounts = mapFst (`rem`k) diceCounts groupedMods = groupBy ((==) `on` fst) $ sortBy (compare `on` fst) modCounts groupModCounts = map (\l -> (fst $ head l, sum $ map snd l)) groupedMods