module CCard where import Data.Word (Word64) import Data.Bits (setBit, (.|.), (.&.), shift, xor, testBit) data Flower = Pine | Plum | Cherry | Wisteria | Iris | Peony | BushClover | SusukiGrass | Chrysanthemum | Maple | Willow | Paulownia deriving (Eq, Ord, Enum, Show) data Card = Pine0 | Pine1 | PinePoetry | Crane | Plum0 | Plum1 | PlumPoetry | BushWarbler | Cherry0 | Cherry1 | CherryPoetry | CampCurtain | Wisteria0 | Wisteria1 | WisteriaRed | Cuckoo | Iris0 | Iris1 | IrisRed | EightPlankBridge | Peony0 | Peony1 | PeonyBlue | Butterflies | BushClover0 | BushClover1 | BushCloverRed | Boar | SusukiGrass0 | SusukiGrass1 | Geese | FullMoon | Chrysanthemum0 | Chrysanthemum1 | ChrysanthemumBlue | SakeCup | Maple0 | Maple1 | MapleBlue | Deer | Lightning | WillowRed | Swallow | RainMan | Paulownia0 | Paulownia1 | Sand | Phoenix deriving (Eq, Ord, Enum, Show) type Pack = Word64 flower :: Card -> Flower flower = toEnum . (`div` 4) . fromEnum set :: [Card] -> Pack set = foldl setBit 0 . map fromEnum contains :: Pack -> Card -> Bool contains pack = testBit pack . fromEnum inoshikacho :: Pack inoshikacho = set [Butterflies, Boar, Deer] animals :: Pack animals = set [BushWarbler, Cuckoo, EightPlankBridge, Geese, SakeCup, Swallow] .|. inoshikacho blue :: Pack blue = set [PeonyBlue, ChrysanthemumBlue, MapleBlue] poetry :: Pack poetry = set [PinePoetry, PlumPoetry, CherryPoetry] ribbons = set [WisteriaRed, IrisRed, BushCloverRed, WillowRed] .|. blue .|. poetry lights :: Pack lights = set [Crane, CampCurtain, FullMoon, RainMan, Phoenix] plain :: Pack plain = pack `xor` (lights .|. ribbons .|. animals) .&. pack pack :: Pack pack = 1 `shift` (fromEnum Phoenix + 1) - 1 pair :: Card -> Card -> Bool pair card1 card2 = flower card1 == flower card2 cards :: [Card] cards = [Pine0 .. Phoenix]