{-# LANGUAGE NoMonomorphismRestriction, TupleSections #-}
module Math.Core.Utils where
import Data.List as L
import qualified Data.Set as S
toSet = S.toList . S.fromList
sortDesc = L.sortBy (flip compare)
insertDesc = L.insertBy (flip compare)
setUnionAsc :: Ord a => [a] -> [a] -> [a]
setUnionAsc (x:xs) (y:ys) =
case compare x y of
LT -> x : setUnionAsc xs (y:ys)
EQ -> x : setUnionAsc xs ys
GT -> y : setUnionAsc (x:xs) ys
setUnionAsc xs ys = xs ++ ys
setUnionDesc :: Ord a => [a] -> [a] -> [a]
setUnionDesc (x:xs) (y:ys) =
case compare x y of
GT -> x : setUnionDesc xs (y:ys)
EQ -> x : setUnionDesc xs ys
LT -> y : setUnionDesc (x:xs) ys
setUnionDesc xs ys = xs ++ ys
intersectAsc :: Ord a => [a] -> [a] -> [a]
intersectAsc (x:xs) (y:ys) =
case compare x y of
LT -> intersectAsc xs (y:ys)
EQ -> x : intersectAsc xs ys
GT -> intersectAsc (x:xs) ys
intersectAsc _ _ = []
multisetSumAsc :: Ord a => [a] -> [a] -> [a]
multisetSumAsc (x:xs) (y:ys) =
case compare x y of
LT -> x : multisetSumAsc xs (y:ys)
EQ -> x : y : multisetSumAsc xs ys
GT -> y : multisetSumAsc (x:xs) ys
multisetSumAsc xs ys = xs ++ ys
multisetSumDesc :: Ord a => [a] -> [a] -> [a]
multisetSumDesc (x:xs) (y:ys) =
case compare x y of
GT -> x : multisetSumDesc xs (y:ys)
EQ -> x : y : multisetSumDesc xs ys
LT -> y : multisetSumDesc (x:xs) ys
multisetSumDesc xs ys = xs ++ ys
diffAsc :: Ord a => [a] -> [a] -> [a]
diffAsc (x:xs) (y:ys) = case compare x y of
LT -> x : diffAsc xs (y:ys)
EQ -> diffAsc xs ys
GT -> diffAsc (x:xs) ys
diffAsc xs [] = xs
diffAsc [] _ = []
diffDesc :: Ord a => [a] -> [a] -> [a]
diffDesc (x:xs) (y:ys) = case compare x y of
GT -> x : diffDesc xs (y:ys)
EQ -> diffDesc xs ys
LT -> diffDesc (x:xs) ys
diffDesc xs [] = xs
diffDesc [] _ = []
isSubsetAsc = isSubMultisetAsc
isSubMultisetAsc (x:xs) (y:ys) =
case compare x y of
LT -> False
EQ -> isSubMultisetAsc xs ys
GT -> isSubMultisetAsc (x:xs) ys
isSubMultisetAsc [] ys = True
isSubMultisetAsc xs [] = False
elemAsc :: Ord a => a -> [a] -> Bool
elemAsc x (y:ys) = case compare x y of
LT -> False
EQ -> True
GT -> elemAsc x ys
notElemAsc :: Ord a => a -> [a] -> Bool
notElemAsc x (y:ys) = case compare x y of
LT -> True
EQ -> False
GT -> notElemAsc x ys
picks :: [a] -> [(a,[a])]
picks [] = []
picks (x:xs) = (x,xs) : [(y,x:ys) | (y,ys) <- picks xs]
pairs (x:xs) = map (x,) xs ++ pairs xs
pairs [] = []
ordpair x y | x < y = (x,y)
| otherwise = (y,x)
foldcmpl p xs = and $ zipWith p xs (tail xs)
isWeaklyIncreasing :: Ord t => [t] -> Bool
isWeaklyIncreasing = foldcmpl (<=)
isStrictlyIncreasing :: Ord t => [t] -> Bool
isStrictlyIncreasing = foldcmpl (<)
isWeaklyDecreasing :: Ord t => [t] -> Bool
isWeaklyDecreasing = foldcmpl (>=)
isStrictlyDecreasing :: Ord t => [t] -> Bool
isStrictlyDecreasing = foldcmpl (>)
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 (k-1) xs) ++ combinationsOf k xs
choose :: (Integral a) => a -> a -> a
choose n k = product [n-k+1..n] `div` product [1..k]
class FinSet x where
elts :: [x]
class HasInverses a where
inverse :: a -> a
infix 8 ^-
(^-) :: (Num a, HasInverses a, Integral b) => a -> b -> a
x ^- n = inverse x ^ n