乱数の扱いは難しい
重複無し乱数です。乱数に大苦戦。
与えられたリストからランダムに一つ選んで、選んだもの以外のリストからさらにランダムに一つ選んで……、というやり方です。
import System.Random main = bingo(10) >>= print bingo :: Int -> IO [Int] bingo n = do g <- getStdGen return $ randomGet g [1..n] randomGet :: (Eq a) => StdGen -> [a] -> [a] randomGet _ [] = [] randomGet g xs = let (n, gen) = rnd g (0, (length xs) - 1) a = xs !! n ys = filter (/= a) xs zs = randomGet gen ys in (a : zs) rnd :: StdGen -> (Int, Int) -> (Int, StdGen) rnd g range = randomR range g
投稿されていたプログラムを見るとrandomRIOというのを使っていたので、私も使ってみました。
import System.Random main = bingo(10) >>= print bingo :: Int -> IO [Int] bingo n = randomGet [1..n] randomGet :: (Eq a) => [a] -> IO [a] randomGet [] = return [] randomGet xs = do n <- randomRIO (0, (length xs) - 1) let a = xs !! n let ys = filter (/= a) xs zs <- randomGet ys return (a : zs)
リストユーティリティを見るとdeleteなんていうのがあるので使ってみました。
import Data.List import System.Random main = bingo(10) >>= print bingo :: Int -> IO [Int] bingo n = randomGet [1..n] randomGet :: (Eq a) => [a] -> IO [a] randomGet [] = return [] randomGet xs = do n <- randomRIO (0, (length xs) - 1) let a = xs !! n ys <- randomGet(delete a xs) return (a : ys)