module Game.Mastermind.CodeSet where
import qualified Data.Set as Set
import qualified Data.List as List
import qualified Data.List.Key as Key
import Data.Function.HT (nest, )
import Data.Ord.HT (comparing, )
import Prelude hiding (null, )
class C set where
empty :: set a
union, intersection :: (Ord a) => set a -> set a -> set a
unit :: set a
leftNonEmptyProduct :: Set.Set a -> set a -> set a
flatten :: (Ord a) => set a -> [[a]]
symbols :: (Ord a) => set a -> Set.Set a
null :: set a -> Bool
size :: set a -> Integer
select :: set a -> Integer -> [a]
representationSize :: set a -> Int
compress :: (Ord a) => set a -> set a
cube :: (C set) => Set.Set a -> Int -> set a
cube alphabet n =
nest n (leftNonEmptyProduct alphabet) unit
unions :: (C set, Ord a) => [set a] -> set a
unions = foldr union empty
insertSortedBy :: (a -> a -> Ordering) -> a -> [a] -> [a]
insertSortedBy cmp x =
let recourse [] = [x]
recourse (y:ys) =
if cmp x y == GT
then y : recourse ys
else x:y:ys
in recourse
intersections :: (C set, Ord a) => [set a] -> set a
intersections =
let go [] = error "intersections: empty list"
go [(_, set)] = set
go ((_,x):(_,y):rest) =
let sec = intersection x y
in go (insertSortedBy (comparing fst) (size sec, sec) rest)
in go .
List.sortBy (comparing fst) .
map (\set -> (size set, set))
intersectionsSort :: (C set, Ord a) => [set a] -> set a
intersectionsSort =
foldl1 intersection . Key.sort size
(*&) :: (C set) => Set.Set a -> set a -> set a
c *& set =
if Set.null c
then empty
else leftNonEmptyProduct c set
(#*&) :: (C set) => a -> set a -> set a
c #*& set =
leftNonEmptyProduct (Set.singleton c) set