Hobby-hacking Eric

2007-05-20

unsort bis

Boy, do I feel like a big dummy!

Here is a super short and functional version I saw from a Pythonista on reddit.


import Data.List ( sort )
import System.Random ( Random, RandomGen, randoms, getStdGen )

main :: IO ()
main =
do gen <- getStdGen
interact $ unlines . unsort gen . lines

unsort :: (Ord x, RandomGen g) => g -> [x] -> [x]
unsort g es = [ y | (_,y) <- sort $ zip rs es ]
where rs = randoms g :: [Integer]


edit!

Heffalump points out that (i) if you have duplicates in rs, you don't get scrambling for the relevant bits (ii) this requires Ord x, which it really ought not to (although that is ani improvement from the array thing where I had to lock the type down for some reason)

edit deux

Hmm... what does it mean to get a list of random arbitrary precision integers?


2 comments:

sekaino_ai said...

That doesn't have to depend on Ord. The author was just lazy.

compareTuple (a,b) (c,d) = compare a c

unsort :: (RandomGen g) => g -> [x] -> [x]
unsort g es = [ y | (_,y) <- sortBy compareTuple $ zip rs es]
where rs = randoms g :: [Integer]

kowey said...

Yep! I think we could also have something like sortBy (comparing fst)