Personal tools

99 questions/Solutions/24

From HaskellWiki

< 99 questions | Solutions(Difference between revisions)
Jump to: navigation, search
(Last solution modified to return IO [Int] and using global number generator)
 
(7 intermediate revisions by 5 users not shown)
Line 22: Line 22:
 
diff_select n to = rnd_select [1..to] n
 
diff_select n to = rnd_select [1..to] n
 
</haskell>
 
</haskell>
  +
  +
Alternative solution:
  +
<haskell>
  +
diffSelect :: Int -> Int -> IO [Int]
  +
diffSelect n m = do
  +
gen <- getStdGen
  +
return . take n $ randomRs (1, m) gen
  +
</haskell>
  +
(Note that this doesn't really solve the problem, since it doesn't generate ''distinct'' numbers).
  +
  +
Using nub from Data.List:
  +
<haskell>
  +
diff_select :: Int -> Int -> StdGen -> [Int]
  +
diff_select n m = take n . nub . randomRs (1, m)
  +
</haskell>
  +
  +
Or without giving StdGen as argument and returning IO [Int]:
  +
<haskell>
  +
import System.Random
  +
import Data.List
  +
import Control.Applicative
  +
  +
diff_select :: Int -> Int -> IO [Int]
  +
diff_select n m = take n . nub . randomRs (1, m) <$> getStdGen
  +
</haskell>
  +
  +
[[Category:Programming exercise spoilers]]

Latest revision as of 13:01, 10 May 2014

Lotto: Draw N different random numbers from the set 1..M.

import System.Random
diff_select :: Int -> Int -> IO [Int]
diff_select n to = diff_select' n [1..to]
 
diff_select' 0 _  = return []
diff_select' _ [] = error "too few elements to choose from"
diff_select' n xs = do r <- randomRIO (0,(length xs)-1)
                       let remaining = take r xs ++ drop (r+1) xs
                       rest <- diff_select' (n-1) remaining
                       return ((xs!!r) : rest)

The random numbers have to be distinct!

In order to use randomRIO here, we need import module System.Random.

As can be seen, having implemented problem 23, rnd_select, the solution is trivial.

diff_select n to = rnd_select [1..to] n

Alternative solution:

diffSelect :: Int -> Int -> IO [Int]
diffSelect n m = do
  gen <- getStdGen
  return . take n $ randomRs (1, m) gen

(Note that this doesn't really solve the problem, since it doesn't generate distinct numbers).

Using nub from Data.List:

diff_select :: Int -> Int -> StdGen -> [Int]
diff_select n m = take n . nub . randomRs (1, m)

Or without giving StdGen as argument and returning IO [Int]:

import System.Random
import Data.List
import Control.Applicative
 
diff_select :: Int -> Int -> IO [Int]
diff_select n m = take n . nub . randomRs (1, m) <$> getStdGen