我是Haskell的新手,我正在尝试为Sudoku中的任意单元格生成随机加权数字
90% of the time, it should generate Nothing
10% of the time, it should generate a random value between 1 and 9
这是我到目前为止所提出的(它没有编译)
-- cell generates an arbitrary cell in a Sudoku
-- cell :: Gen (Maybe Int)
cell = case x of 1 -> return (Just y); _ -> return Nothing
where std = mkStdGen(100)
(x, a) = randomR(1, 10) std
(y, a')= randomR(1, 9) std
非常感谢任何帮助它进行编译,或指导我采用更好的方法
使用Quickcheck这就是我的方法:
-- cell generates an arbitrary cell in a Sudoku
cell :: Gen (Maybe Int)
cell = frequency [(9, return Nothing),
(1, do r <- choose (1,9); return (Just r))]
-- an instance for generating Arbitrary Sudokus
instance Arbitrary Sudoku where
arbitrary =
do rows <- sequence [ sequence [ cell | j <- [1..9] ] | i <- [1..9] ]
return (Sudoku rows)
答案 0 :(得分:2)
如果您使用的是QuickCheck,那么您当然不希望cell
达到纯值 - randomR (0,100) (mkStdGen 43434343)
不是随机的,因此对您来说测试无用。
由于您使用的是QuickCheck,因此需要使用QuickCheck功能。您也不能轻易使用System.Random
。只需使用(非常强大的)QuickCheck API,它具有一个函数choose :: Random a => (a,a) -> Gen a
,它可以选择一个范围内的随机数,一个函数frequency :: [(Int, Gen a)] -> Gen a
根据它的权重选择一个随机生成器,即可能性,并返回该生成器。您可以将cell
写为:
cell :: Gen (Maybe Int)
cell = frequency
[ (1, Just `fmap` choose (1,9))
, (9, return Nothing)
]
然后,例如,如果您将数独游戏板定义为data Sudoku = Sudoku [[Maybe Int]]
,则可以使用Arbitrary
轻松为其编写cell
个实例:
import Control.Monad (replicateM)
instance Arbitrary Sudoku where
arbitrary = Sudoku `fmap` replicateM 9 (replicateM 9 cell)