module Set.Card (-- * Types Card(..), Color(..), Count(..), Shading(..), Symbol(..), -- * 'Card' interface functions allCards, validSet, solve ) where import Data.List (tails) import Set.Utils data Color = Red | Purple | Green deriving (Show, Eq, Ord) data Count = One | Two | Three deriving (Show, Eq, Ord) data Shading = Open | Striped | Solid deriving (Show, Eq, Ord) data Symbol = Diamond | Squiggle | Oval deriving (Show, Eq, Ord) data Card = Card { color :: Color , count :: Count , shading :: Shading , symbol :: Symbol } deriving (Show, Eq) checkAttribute :: Eq a => [a] -> Bool checkAttribute xs = all (uncurry (==)) combos || all (uncurry (/=)) combos where combos = chooseTwo xs validSet :: Card -> Card -> Card -> Bool validSet card1 card2 card3 = checkAttribute (map color cards) && checkAttribute (map count cards) && checkAttribute (map shading cards) && checkAttribute (map symbol cards) where cards = [card1, card2, card3] allCards :: [Card] allCards = [Card a b c d | a <- [Red, Purple, Green] , b <- [One, Two, Three] , c <- [Open, Striped, Solid] , d <- [Diamond, Squiggle, Oval]] -- | 'solveBoard' returns the list of all valid sets contained in the given -- list. solve :: [Card] -> [(Card,Card,Card)] solve xs = [(a,b,c) | (a:as) <- tails xs , (b:bs) <- tails as , c <- bs , validSet a b c]