Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I write this in Ruby/Python? Or, can you translate my LINQ to Ruby/Python?

Yesterday, I asked this question and never really got an answer I was really happy with. I really would like to know how to generate a list of N unique random numbers using a functional language such as Ruby without having to be extremely imperative in style.

Since I didn't see anything I really liked, I've written the solution I was looking for in LINQ:


       static void Main(string[] args)
        {
            var temp = from q in GetRandomNumbers(100).Distinct().Take(5) select q;
        }

        private static IEnumerable GetRandomNumbers(int max)
        {
            Random r = new Random();
            while (true)
            {
                yield return r.Next(max);
            }
        }

Can you translate my LINQ to Ruby? Python? Any other functional programming language?

Note: Please try not to use too many loops and conditionals - otherwise the solution is trivial. Also, I'd rather see a solution where you don't have to generate an array much bigger than N so you can then just remove the duplicates and trim it down to N.

I know I'm being picky, but I'd really like to see some elegant solutions to this problem. Thanks!

Edit:
Why all the downvotes?

Originally my code sample had the Distinct() after the Take() which, as many pointed out, could leave me with an empty list. I've changed the order in which those methods are called to reflect what I meant in the first place.

Apology:
I've been told this post came across as rather snobbish. I wasn't trying to imply that LINQ is better than Ruby/Python; or that my solution is much better than everyone else's. My intent is just to learn how to do this (with certain constraints) in Ruby. I'm sorry if I came across as a jerk.

like image 419
Esteban Araya Avatar asked Sep 23 '08 16:09

Esteban Araya


Video Answer


4 Answers

>>> import random
>>> print random.sample(xrange(100), 5)
[61, 54, 91, 72, 85]

This should yield 5 unique values in the range 0 — 99. The xrange object generates values as requested so no memory is used for values that aren't sampled.

like image 65
Jeremy Avatar answered Oct 02 '22 08:10

Jeremy


In Ruby:

a = (0..100).entries.sort_by {rand}.slice! 0, 5

Update: Here is a slightly different way: a = (0...100).entries.sort_by{rand}[0...5]

EDIT:

and In Ruby 1.9 you can do this:

Array(0..100).sample(5) 
like image 26
Michael Deardeuff Avatar answered Oct 02 '22 10:10

Michael Deardeuff


Hmm... How about (Python):

s = set()
while len(s) <= N: s.update((random.random(),))
like image 28
Will Boyce Avatar answered Oct 02 '22 08:10

Will Boyce


I will forgo the simplest solutions using the 'random' module since I take it that's not really what you are after. Here's what I think you are looking for in Python:

>>> import random
>>> 
>>> def getUniqueRandomNumbers(num, highest):
...     seen = set()
...     while len(seen) < num:
...         i = random.randrange(0, highest)
...         if i not in seen:
...             seen.add(i)  
...             yield i
... 
>>>

To show you how it works:

>>> list(getUniqueRandomNumbers(10, 100))
[81, 57, 98, 47, 93, 31, 29, 24, 97, 10]
like image 40
Thomas Wouters Avatar answered Oct 02 '22 10:10

Thomas Wouters