summaryrefslogtreecommitdiff
path: root/testsuite/tests/concurrent/T13615/T13615.hs
blob: 9295db3a7c4d64abd673e8c6a3c7e1b61dbb56bb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
{-# LANGUAGE RankNTypes #-}

module Main where

import Parallel
import qualified Memo
import qualified Data.Map.Lazy as M
import Control.DeepSeq
import Control.Monad.ST
import Data.STRef

fight :: Int -> Int -> [Int]
fight i a = map fst $ fightVanillaM i a

fightVanillaM :: Int -> Int -> [(Int, Int)]
fightVanillaM = Memo.memo2 Memo.bits Memo.bits fightVanilla

fightVanilla :: Int -> Int -> [(Int, Int)]
fightVanilla php ohp
  | php <= 0 || ohp <= 0 = [(max 0 php, max 0 ohp)]
  | otherwise = regroup $ do
      (odmg, pdmg) <- [(9,3),(10,2),(11,2),(12,2),(14,1),(16,1),(18,0),(100,0),(100,0),(100,0)]
      fightVanillaM (php - pdmg) (ohp - odmg)

update :: Int -> Int -> [(Int, Int)]
update i outcome = (,) outcome <$> fight i outcome

memoState :: Memo.Memo (Int, Int)
memoState = Memo.pair Memo.bits Memo.bits

fibFight :: Int -> [Int]
fibFight 0 = []
fibFight 1 = []
fibFight x = [(x - 1), (x - 2)]


-----------------------------------------------------------------------------------
regroup :: (NFData a, Show a, Eq a, Ord a) => [(a, Int)] -> [(a, Int)]
regroup xs =
    let xs' = M.toList $ M.fromListWith (+) xs
        s' = addTheNumbers (map (\(_,x) -> x) xs) -- sum (map snd xs')
        s  = sum (map snd xs)
     in if s' /= s
            then if show s' == show s
                    then error "WAT????"
                    else error $ "Those are expected to be equal" ++ show (s', s)
            else xs'
----------------------------------------------------------------------------------

addTheNumbers :: [Int] -> Int
addTheNumbers xs0 = runST $ do
  y <- newSTRef 0
  let go [] = readSTRef y
      go (x : xs) = do
        modifySTRef y (+x)
        go xs
  go xs0

main :: IO ()
main = rnf (go (80, 250)) `seq` return ()
    where
        go = memoState (rnf . parMap rdeepseq (map go) . step)
step (cid, hp) = map (update hp) (fibFight cid)