module Math.Core.Utils where
import Data.List as L
import qualified Data.Set as S
toSet = S.toList . S.fromList
pairs (x:xs) = map (x,) xs ++ pairs xs
pairs [] = []
ordpair x y | x < y = (x,y)
| otherwise = (y,x)
foldcmpl p (x1:x2:xs) = p x1 x2 && foldcmpl p (x2:xs)
foldcmpl _ _ = True
cmpfst x y = compare (fst x) (fst y)
eqfst x y = (==) (fst x) (fst y)
fromBase b xs = foldl' (\n x -> n * b + x) 0 xs
powersetdfs :: [a] -> [[a]]
powersetdfs xs = map reverse $ dfs [ ([],xs) ]
where dfs ( (ls,rs) : nodes ) = ls : dfs (successors (ls,rs) ++ nodes)
dfs [] = []
successors (ls,rs) = [ (r:ls, rs') | r:rs' <- L.tails rs ]
powersetbfs :: [a] -> [[a]]
powersetbfs xs = map reverse $ bfs [ ([],xs) ]
where bfs ( (ls,rs) : nodes ) = ls : bfs ( nodes ++ successors (ls,rs) )
bfs [] = []
successors (ls,rs) = [ (r:ls, rs') | r:rs' <- L.tails rs ]
combinationsOf :: Int -> [a] -> [[a]]
combinationsOf 0 _ = [[]]
combinationsOf _ [] = []
combinationsOf k (x:xs) | k > 0 = map (x:) (combinationsOf (k1) xs) ++ combinationsOf k xs
choose :: (Integral a) => a -> a -> a
choose n k = product [nk+1..n] `div` product [1..k]