Concurrent Clean : あなたならどうお書きになります1.0

ちょっとひねった。
shuffled_permは、順列をランダムに並べて返すというのを作ろうとしたのだけれど、失敗している。
ついでに、中間状態の保持にメモリを消費するので、要素数が大きくなると破綻する。
もうちょっと考える。

import StdEnv, OptEnv, MersenneTwister

shuffled_perm _ [] _ = [[]]
shuffled_perm frnd ls s # (ls,rnd) = shuffle ls (frnd s)
                        = loop (map_extract [] ls rnd)
  where
    map_extract _ [] _ = []
    map_extract ls1 [a:ls2] [s:r] = [(a,shuffled_perm frnd (ls1++ls2) s):map_extract [a:ls1] ls2 r]

    loop [] = []
    loop [(a,[]):rest] = loop rest
    loop [(a,[l:lr]):rest] = [[a:l]:loop (rest ++ [(a,lr)])]

::Person = Person !Char !Int

answer ps frnd s = filter f $ map (zip2 ps) $ shuffled_perm frnd ps s
  where
    f [] = True
    f [(Person g1 _,Person g2 _):rest] = g1 <> g2 && f rest

Start w # (t,w) = tick_count w
        = case answer case10 genRandInt t of
            []  = Nothing
            ans = Just (hd ans)

ちなみに、shuffle_permのloopのところは、shuffle_permがきちんとshuffleされていないので、これがないと、最初の方の要素で失敗したときに、その後の試行がしばらく全滅してしまう。