diff options
author | Ben Sima <ben@bsima.me> | 2018-08-08 19:08:20 -0700 |
---|---|---|
committer | Ben Sima <ben@bsima.me> | 2018-08-08 19:08:20 -0700 |
commit | 65ffe186acb5f32f0bba07b8ce0eecacbda83bbd (patch) | |
tree | d73e18576de3e3adb3c248022b561f2e5ce09570 /rain.bh.hs | |
parent | 00ca368c2c6864fd059e3ad655afd279b5e75748 (diff) |
De-nest rain.bh exercise
Diffstat (limited to 'rain.bh.hs')
-rwxr-xr-x | rain.bh.hs | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/rain.bh.hs b/rain.bh.hs new file mode 100755 index 0000000..0133c2b --- /dev/null +++ b/rain.bh.hs @@ -0,0 +1,89 @@ +#!/usr/bin/env stack +{- stack + --nix + --resolver lts-11.15 + --install-ghc + runghc + --package random +-} + +{-# LANGUAGE TypeSynonymInstances #-} +{-# LANGUAGE FlexibleInstances #-} + +{- + +Problem: Create a string array containing a representation of the 52 cards in a +standard deck, and then a second array that shuffles the 52 cards. + +Start with two string arrays of the cards and suits: +Cards: 2, 3, 4, 5, 6, 7, 8, 9, 10, J, K, Q, A +Suits: Clubs, Diamonds, Aces, Spades + +-} + +import System.Random +import Control.Monad +import Control.Applicative + +data Name + = Two + | Three + | Four + | Five + | Six + | Seven + | Eight + | Nine + | Ten + | Jack + | King + | Queen + | Ace + deriving (Show, Enum, Bounded) + +names :: [Name] +names = [ Two .. ] + +data Suit + = Club + | Diamond + | Heart + | Spade + deriving (Show, Enum, Bounded) + +suits :: [Suit] +suits = [ Club .. ] + +type Card = (Name, Suit) + +instance Random Suit where + randomR (a, b) g = + case randomR (fromEnum a, fromEnum b) g of + (x, g') -> (toEnum x, g') + random g = randomR (minBound, maxBound) g + +instance Random Name where + randomR (a, b) g = + case randomR (fromEnum a, fromEnum b) g of + (x, g') -> (toEnum x, g') + random g = randomR (minBound, maxBound) g + +-- Dot product is same as 'liftA2 (,)' +allCards :: [Card] +allCards = liftA2 (,) names suits + +shuffle' :: [Card] -> _ +shuffle' (i:is) xs = (last firsts) : shuffle' is (init firsts ++ rest) + where (firsts, rest) = splitAt (i `mod` length xs) xs + + +shuffle g xs = shuffle (randoms g) xs + +main :: IO [()] +main = do + g <- getStdGen + let namesLength = length names + let randomNames = map fromEnum $ take namesLength $ randomRs (0, namesLength-1) g + let suitsLength = length suits + let randomSuits = map fromEnum $ take suitsLength $ randomRs (0, suitsLength-1) g + sequence $ map (putStrLn.show) $ liftA2 (,) randomNames randomSuits |