diff options
Diffstat (limited to '08.01.hs')
-rw-r--r-- | 08.01.hs | 46 |
1 files changed, 27 insertions, 19 deletions
@@ -1,26 +1,33 @@ - -import System.Random import Control.Monad.State +import Data.Foldable import Data.Maybe -import Data.Tuple import Data.Sequence as Seq -import Data.Foldable +import Data.Tuple +import System.Random -- | Take a random element from a list, removing it from the list. randomChoice :: RandomGen g => State (Seq a, g) (Maybe a) -randomChoice = get >>= (\(xs, g) -> if (Seq.null xs) then (return Nothing) else (let - (r, g2) = randomR (0, Seq.length xs - 1) g - in (put (deleteAt r xs, g2) >> (return (Just $ index xs r)) - ))) +randomChoice = + get >>= + (\(xs, g) -> + if (Seq.null xs) + then (return Nothing) + else (let (r, g2) = randomR (0, Seq.length xs - 1) g + in (put (deleteAt r xs, g2) >> (return (Just $ index xs r))))) -- | Returns a list of randomly chosen values with no repeats. randomChoices :: RandomGen g => Int -> State (Seq a, g) (Seq a) -randomChoices n = state (\si -> - let (maybeVals, sf) = runState (sequence $ Prelude.replicate n randomChoice) si - in (fromList $ catMaybes maybeVals, sf) - ) +randomChoices n = + state + (\si -> + let (maybeVals, sf) = runState (sequence $ Prelude.replicate n randomChoice) si + in (fromList $ catMaybes maybeVals, sf)) + +data Bacterium + = Red + | Green + deriving (Show) -data Bacterium = Red | Green deriving Show type Bacteria = Seq Bacterium reproduce :: Bacteria -> Bacteria @@ -36,21 +43,22 @@ initialize :: Int -> Bacteria initialize n = (Seq.replicate (n `quot` 2) Red) <> (Seq.replicate (n `quot` 2) Green) isRed :: Bacterium -> Bool -isRed Red = True +isRed Red = True isRed Green = False nRed :: Bacteria -> Int nRed b = Seq.length $ Seq.filter isRed b isDone :: Bacteria -> Bool -isDone b | nRed b == 0 = True - | nRed b == Seq.length b = True - | otherwise = False +isDone b + | nRed b == 0 = True + | nRed b == Seq.length b = True + | otherwise = False run :: RandomGen g => Int -> g -> ([Bacteria], g) run n g = (fst <$> steps, snd $ last steps) - where steps = takeWhile (not . isDone . fst) $ iterate hour (initialize n, g) + where + steps = takeWhile (not . isDone . fst) $ iterate hour (initialize n, g) lifetime :: [Bacteria] -> Int lifetime b = Data.Foldable.length b - |