Recent Posts
PAWN | 11 sec ago
None | 42 sec ago
None | 50 sec ago
Per | 1 min ago
None | 1 min ago
None | 1 min ago
T-SQL | 2 min ago
XML | 2 min ago
T-SQL | 2 min ago
None | 2 min ago
Sitereport
Find cool info about any domain on the internet?
visit sitereport
Free Subdomains
Want a pastebin.com sub-domain for your community?
learn more...
What is pastebin?
Pastebin is a website that hosts all your text & code on dedicated servers for easy sharing.
learn more...
Learn a little bit about the new Pastebin.com on our help page. hide message
By me on the 16th of Sep 2009 08:24:07 AM Download | Raw | Embed | Report
  1. import System.Random
  2. import Ix
  3.  
  4. -- general notes:
  5. --    1. is it really this painful to do anything with random numbers?
  6. --    2. the RNG doesn't even work very well, seems to be linear-congruential
  7. --       how do i get Mersenne Twister?
  8.  
  9. -- attempt 1: straightforward translation of standard idiom; quadratic time
  10. permute1 xs = permute_ xs (mkStdGen 0) where
  11.     permute_ [] rgen = []
  12.     permute_ xs rgen = let (idx, newrgen) = randomR (1, length xs) rgen in
  13.                        xs!!(idx-1) : permute_ (take (idx-1) xs ++ drop idx xs) newrgen
  14.  
  15. -- attempt 2: decorate-sort-undecorate
  16. permute2 xs = permute_ xs (iteraternd (mkStdGen 0) random) where
  17.     -- had to force input type to Int because
  18.     -- i can't figure out what's the base class for sortable types
  19.     permute_ :: [Int] -> [Int] -> [Int]
  20.     permute_ xs rnds = map snd (qsort (zip rnds xs)) where
  21.         -- why does 'sort' work in the prelude but not here?
  22.         qsort [] = []
  23.         qsort (x:xs) = qsort (filter (<=x) xs) ++ [x] ++ qsort (filter (>x) xs)
  24.     -- i'm hoping this is somewhere in the library and i've missed it
  25.     iteraternd g rnd = let (val, newg) = rnd g in val : iteraternd newg rnd
  26.  
  27. -- attempt 3: not really sure where i was going with this..
  28. -- neither linear-time nor a perfect shuffle
  29. -- strategy is to split in half, permute each, and merge 'randomly'
  30. permute3 xs = permute_ xs (mkStdGen 0) where
  31.     permute_ []  rgen = []
  32.     permute_ [x] rgen = [x]
  33.     permute_ xs  rgen =
  34.         let mid = (length xs) `div` 2; (rgen1, rgen2) = split rgen in
  35.         merge (permute_ (take mid xs) rgen1)
  36.               (permute_ (drop mid xs) rgen2)
  37.               []
  38.               rgen
  39.     -- acc is needed to make merge tail-recursive
  40.     merge xs [] acc rgen = xs ++ acc
  41.     merge [] ys acc rgen = ys ++ acc
  42.     merge (x:xs) (y:ys) acc rgen =
  43.         let (rnd, newrgen) = randomR (0,1) rgen :: (Int, StdGen) in
  44.         if rnd == 0
  45.             then merge xs ys (x:y:acc) newrgen
  46.             else merge xs ys (y:x:acc) newrgen
Submit a correction or amendment below. Make A New Post
To highlight particular lines, prefix each line with @h@
Syntax highlighting:
Post expiration:
Post exposure:
Name / Title:
Email: