briefest method of generating a list of random numbers?

B

Boris Schmid

Hi all,

I wondered if there was a more compact method of generating things like
a random string, or a random list of numbers than I'm using now (using
ruby 1.9.0-1)

array = [] ; 100.times {array << rand}
string = "" ; 100.times {string << (rand(26) + 97).chr}

The temptation is to use

array = [rand] * 100
string = (rand(26) + 97).chr * 100

but that only draws one random number a 100 times.

Is there a bit of syntax that I missed?
 
M

Mikael Høilund

Hi all,

I wondered if there was a more compact method of generating things =20
like
a random string, or a random list of numbers than I'm using now (using
ruby 1.9.0-1)

Array(100) { rand }

The block is evaluated for each element.

--=20
Mikael H=F8ilund=
 
A

Axel Etzold

-------- Original-Nachricht --------
Datum: Mon, 26 May 2008 17:45:57 +0900
Von: Boris Schmid <[email protected]>
An: (e-mail address removed)
Betreff: briefest method of generating a list of random numbers?
Hi all,

I wondered if there was a more compact method of generating things like
a random string, or a random list of numbers than I'm using now (using
ruby 1.9.0-1)

array = [] ; 100.times {array << rand}
string = "" ; 100.times {string << (rand(26) + 97).chr}

The temptation is to use

array = [rand] * 100
string = (rand(26) + 97).chr * 100

but that only draws one random number a 100 times.

Is there a bit of syntax that I missed?

Hello Boris,
string = (rand(26) + 97).chr * 100

but that only draws one random number a 100 times.

That's not correct - it draws a random number once, turns it into
a letter and then repeats it 100 times -

you could also write, e.g.,

string='x'*100 .

But what's wrong with the first - it looks fairly compact to me:

string = "" ; 100.times { string << (rand(26) + 97).chr}

You could add a srand(); in the bracket to call different
strings every time, but that's less compact :)

Best regards,

Axel
 
B

Boris Schmid

But what's wrong with the first - it looks fairly compact to me:

string = "" ; 100.times { string << (rand(26) + 97).chr}

For strings I'll have to use the one above, but arrays now read a bit
more natural (to my eyes). The size doesn't matter that much, but it is
simpler to understand.

population = Array.new(POP_SIZE) {
function_that_generates_a_random_individual }

vs the old

population = [] ; POP_SIZE.times {population <<
function_that_generates_a_random_individual }

Thanks both of you!
 
L

Lars Christensen

Array(100) { rand }

Don't you mean

Array.new(100) { rand }

Array(arg) creates an array equal to 'arg' (if it responds to .to_ary)
or an array containing precisly 'arg' otherwise. It never yields.

There is also

(1..100).map { rand }

And for strings

(1..100).map { (rand(26)+97).chr }.join

Lars
 
B

Boris Schmid

Boris said:
For strings I'll have to use the one above,

Duh. I can just use the Array.new, and append a .join at the end to get
the random string. And Axel, I'm generating quite a lot of arrays in my
small prog, and using this shorter way makes it indeed clearer :). It is
definitly worth it.

Example:


filter = Array.new(WINDOW) { bucket = Array.new(AMINO) {|i| (97 +
i).chr} }

was

filter = []
WINDOW.times {bucket = [] ; AMINO.times {|i| bucket << (97 + i).chr}
; filter << bucket}
 
R

Robert Klemme

2008/5/26 Boris Schmid said:
For strings I'll have to use the one above,

Note that String#<< understands ints as being character codes - so you
do not need the .chr:

irb(main):005:0> str = 100.to_enum:)times).inject("") {|s,| s << (?a +
rand(26))}
=> "uepizlkepyoxxfkefosxxptvcpdiuwyexecngmftnidlyfnhqgmtndbzthhykdjjiyayzwvhatovzbxzqkhclnxwbqbsoxpszwkn"
irb(main):006:0>

I believe in 1.9 you can as well do

str = 100.times.inject("") {|s,| s << (?a + rand(26))}

Kind regards

robert
 
C

Calamitas

For strings I'll have to use the one above, but arrays now read a bit
more natural (to my eyes). The size doesn't matter that much, but it is
simpler to understand.

You could also do

Array.new(100) { 97 + rand(26) }.pack("c*")

Peter
 
B

Boris Schmid

You could also do
Array.new(100) { 97 + rand(26) }.pack("c*")

Peter

Pack seems to be faster than the combination of .chr and join, which is
a nice side-effect, as I'm running simulations in ruby, and they takes
aeons of time (well, nearly a week). Don't ask me why I'm using ruby, it
just sort of happened ;), and the code is only 160 lines, which compares
favorably to the C ancestor of this simulation (which did more or less
the same in 4000 lines)


irb(main):017:0> time = Time.new ; 1000.times {string = Array.new(1000)
{ rand(26) + 97 }.pack("c*")} ; puts Time.new - time
0.184389
=> nil
irb(main):018:0> time = Time.new ; 1000.times {string = Array.new(1000)
{ (rand(26) + 97).chr }.join} ; puts Time.new - time
0.330891
=> nil
 
R

Robert Dober

("a".."z").sort_by {rand}.join
this is not really the same, maybe
(("a".."z").to_a * N).sort_by { rand }[0..x].join
does what OP wants (if N is large enough) and although this approach
has a certain elegance it would be very,very inefficent.

Cheers
R.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top