Are there any more elegant, concise, pithy, and more Rubyish ways of

doing this?

def roll(number_of_dice)

sum = 0

number_of_dice.times do

sum += rand(5).next

end

sum

end

Thanks in advance!

Are there any more elegant, concise, pithy, and more Rubyish ways of

doing this?

def roll(number_of_dice)

sum = 0

number_of_dice.times do

sum += rand(5).next

end

sum

end

Thanks in advance!

[email protected] wrote:

Thanks in advance!

The Incredible Inevitable Inject:

def roll(number_of_dice)

(0…number_of_dice).inject(0){|m,r| rand(5)+m}

end

[email protected] wrote:

Thanks in advance!

I don’t think there’s really anything you can do to it, but I would

suggest that you add a parameter to set the sides of the dice and also

add one to the random output (if it’s the random number gen I’m thinking

of, it’ll give you 0-5 which means your dice have a blank side )

-JC

On Nov 26, 5:24 pm, Alex Y. [email protected] wrote:

end

The Incredible Inevitable Inject:

def roll(number_of_dice)

(0…number_of_dice).inject(0){|m,r| rand(5)+m}

end

You missed the +1 needed to take rand(5) to 1…6 instead of 0…5.

And I personally like 1…num_dice instead of 0…num_dice. And,

finally, I sum things so often I usually have this lying around:

module Enumerable

def sum

if block_given?

inject(0){ |sum,obj| sum + yield(obj) }

else

inject(0){ |sum,obj| sum+obj }

end

end

end

which makes the solution simply:

def roll(number_of_dice)

(1…number_of_dice).sum{ rand(5)+1 }

end

In the vein of DRY code and unix tools, I strongly encourage everyone

to be on constant vigil looking for bits of code that can be

abstracted out to little atomic re-usable bits. After a while, coding

is less like carving entire models from styrofoam, and more like

snapping little Lego blocks together.

2007/11/27, Robert K. [email protected]:

There is another one, that - at least theoretically - saves some

addition efforts:

Of course I wanted to say that it /practically/ saves addition efforts

and /theoretically/ it will also save time.

Cheers

robert

2007/11/27, Phrogz [email protected]:

`sum`

end

The Incredible Inevitable Inject:

def roll(number_of_dice)

(0…number_of_dice).inject(0){|m,r| rand(5)+m}

endYou missed the +1 needed to take rand(5) to 1…6 instead of 0…5.

And everybody apparently missed 6 because rand(5) will yield *5*

values ranging in 0…4. :-))

`end`

end

which makes the solution simply:

def roll(number_of_dice)

(1…number_of_dice).sum{ rand(5)+1 }

end

There is another one, that - at least theoretically - saves some

addition efforts:

require ‘enumerator’

def roll(number)

raise ArgumentError, “Negative!” if number < 0

number.to_enum(:times).inject(number) {|s,| s + rand(6)}

end

I also threw in to_enum just for the fun of it.

In the vein of DRY code and unix tools, I strongly encourage everyone

to be on constant vigil looking for bits of code that can be

abstracted out to little atomic re-usable bits. After a while, coding

is less like carving entire models from styrofoam, and more like

snapping little Lego blocks together.

Absolutely!

Kind regards

robert

Phrogz wrote:

end

The Incredible Inevitable Inject:def roll(number_of_dice)

(0…number_of_dice).inject(0){|m,r| rand(5)+m}

endYou missed the +1 needed to take rand(5) to 1…6 instead of 0…5.

Oops

Robert K. wrote:

`sum`

end

The Incredible Inevitable Inject:def roll(number_of_dice)

(0…number_of_dice).inject(0){|m,r| rand(5)+m}

end

You missed the +1 needed to take rand(5) to 1…6 instead of 0…5.And everybody apparently missed 6 because rand(5) will yield

5

values ranging in 0…4. :-))

Nobody said dice have to be cubic…

Hi,

unknown wrote:

Are there any more elegant, concise, pithy, and more Rubyish ways of

doing this?def roll(number_of_dice)

sum = 0

number_of_dice.times do

sum += rand(5).next

end

sum

endThanks in advance!

If you want the dice number, you should use rand(6).

How about this:

def roll(n)

eval(’+rand(6)+1’*n)

end

Regards,

Park H.

On Nov 26, 6:17 pm, [email protected] wrote:

Thanks in advance!

def sum *x

x.inject{|a,b| a+b}

end

def roll n

sum( *(1…n).map{rand(6)+1} )

end

On Nov 27, 6:26 am, William J. [email protected] wrote:

`sum`

end

Thanks in advance!

def sum *x

x.inject{|a,b| a+b}

end

def roll n

sum( *(1…n).map{rand(6)+1} )

end

Clever, but 3 times slower than the original (after correcting it).

On Nov 27, 2007 7:40 AM, Phrogz [email protected] wrote:

`sum`

And I personally like 1…num_dice instead of 0…num_dice. And,

end

I agree with this need, in Labrador you can do

an_enum.inject(:+)

and as we were nitpicking

inject(0){ |m,| m + rand(5) } #sic

R.

–

http://ruby-smalltalk.blogspot.com/

All truth passes through three stages. First, it is ridiculed. Second,

it is violently opposed. Third, it is accepted as being self-evident.

Schopenhauer (attr.)

On Nov 27, 8:37 am, Brian A. [email protected] wrote:

`sum`

The interface is “roll n” regardless of the underlying implementation,

You can make it ~10% faster (with the loss of some readability) by not

invoking next each time and just summing at the end:def roll num_dice

sum = 0

num_dice.times { sum += rand(6) }

sum + num_dice

end

Actually make that ~12% faster with the following - just explain with

comments

def roll num_dice

sum = num_dice

num_dice.times { sum += rand(6) }

sum

end

On Nov 27, 2:06 am, Robert K. [email protected] wrote:

2007/11/27, Phrogz [email protected]:

You missed the +1 needed to take rand(5) to 1…6 instead of 0…5.

And everybody apparently missed 6 because rand(5) will yield

5

values ranging in 0…4. :-))

Oh crimeny…oops.

There is another one, that - at least theoretically - saves some

addition efforts:require ‘enumerator’

def roll(number)

raise ArgumentError, “Negative!” if number < 0

number.to_enum(:times).inject(number) {|s,| s + rand(6)}

end

You know, I *want* to embrace to_enum, because it’s certainly

excellently powerful and abstract…but somehow I just don’t grok it.

Thanks for the reminder. Sometime I’ll have to think about it.

(I wish I could find some flaw with it, and say “no no no, what it

really should be is ____”; I just somehow basically find it confusing.)

Why be satisfied with a 10-12% increase in speed when we can have an

order of magnitude?

sudo gem install rubyinline

–

require ‘rubygems’

require ‘inline’

module Kernel

inline do |builder|

builder.c "

int roll(int n) {

int sum = n;

while (n-- > 0) {

sum += (rand() % 6);

}

return sum;

}

"

end

end

puts roll(3)

On Nov 27, 2007 3:35 PM, Brian A. [email protected] wrote:

module Kernel

end

endputs roll(3)

If you’re going to do overkill, do overkill. You’ve got an extra

compare in that main loop, with the check for n-- > 0. And it doesn’t

work for negative numbers. Correcting for this (untested):

int roll(int n) {

int sum = n;

if (n > 0) {

do {

sum += rand() % 6;

} while (–n);

} else if (n < 0) {

do {

sum -= rand() % 6;

} while (++n);

}

return sum;

}

Of course, this still has the problem that rand() % 6 typically return

slightly biased numbers, as RAND_MAX is usually a 2^n-1

Eivind.

On Nov 26, 7:17 pm, [email protected] wrote:

Thanks in advance!

As others have pointed out, you need rand(6).next to get (1…6);

otherwise, it’s hard to improve on what you have here. This is a

simple, iterative mathematical function. I personally don’t think

using map, inject, etc. is more “Rubyish” in this context, just 2 to 3

times slower.

The interface is “roll n” regardless of the underlying implementation,

so you might as well make it fast.

One style improvement might be to use a one line block:

def roll num_dice

sum = 0

num_dice.times { sum += rand(6).next }

sum

end

You can make it ~10% faster (with the loss of some readability) by not

invoking next each time and just summing at the end:

def roll num_dice

sum = 0

num_dice.times { sum += rand(6) }

sum + num_dice

end

Brian A.

On 11/27/07, Eivind E. [email protected] wrote:

Of course, this still has the problem that rand() % 6 typically return

slightly biased numbers, as RAND_MAX is usually a 2^n-1Eivind.

hah! overkill not only on method, but also in worry. biased Nd6?

awesome! ok, that kind of made my morning.

Cameron

On Nov 27, 9:57 am, Eivind E. [email protected] wrote:

If you’re going to do overkill, do overkill. You’ve got an extra

compare in that main loop, with the check for n-- > 0.

I assume you’re just having fun, but even so, if your compiler doesn’t

optimize (n-- > 0) to be as efficient as (n–), get a new compiler.

And it doesn’t

work for negative numbers. Correcting for this (untested):

Yes, rolling a negative number of dice is precluded, it just confuses

people.

}

return sum;}

You might want to double check that code…

Of course, this still has the problem that rand() % 6 typically return

slightly biased numbers, as RAND_MAX is usually a 2^n-1

Ok, here you have a point. The roll function won’t cut it in Las

Vegas.

On Nov 27, 11:53 am, Robert K. [email protected] wrote:

`number_of_dice.times do`

using map, inject, etc. is more “Rubyish” in this context, just 2 to 3

sumI guess there is even more room for improvement by doing this:

def roll num_dice

sum = roll num_dice

num_dice.times { sum += rand(6) }

sum

endSCNR

No apology necessary, I beat you to it (I assume you meant sum =

num_dice)

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

Sponsor our Newsletter | Privacy Policy | Terms of Service | Remote Ruby Jobs