Velocity Reviews > Ruby > Most elegant way to do this?

# Most elegant way to do this?

rbysamppi@gmail.com
Guest
Posts: n/a

 11-27-2007
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

Alex Young
Guest
Posts: n/a

 11-27-2007
http://www.velocityreviews.com/forums/(E-Mail Removed) 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
> end
>
>

The Incredible Inevitable Inject:

def roll(number_of_dice)
(0...number_of_dice).inject(0){|m,r| rand(5)+m}
end

--
Alex

JC
Guest
Posts: n/a

 11-27-2007
(E-Mail Removed) 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
> end
>

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

Phrogz
Guest
Posts: n/a

 11-27-2007
On Nov 26, 5:24 pm, Alex Young <(E-Mail Removed)> wrote:
> (E-Mail Removed) 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
> > 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.

Robert Klemme
Guest
Posts: n/a

 11-27-2007
2007/11/27, Phrogz <(E-Mail Removed)>:
> On Nov 26, 5:24 pm, Alex Young <(E-Mail Removed)> wrote:
> > (E-Mail Removed) 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
> > > 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. )

> 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

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

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

--
use.inject do |as, often| as.you_can - without end

Robert Klemme
Guest
Posts: n/a

 11-27-2007
2007/11/27, Robert Klemme <(E-Mail Removed)>:
> There is another one, that - at least theoretically - saves some

Of course I wanted to say that it /practically/ saves addition efforts
and /theoretically/ it will also save time.

Cheers

robert

Alex Young
Guest
Posts: n/a

 11-27-2007
Phrogz wrote:
> On Nov 26, 5:24 pm, Alex Young <(E-Mail Removed)> wrote:
>> (E-Mail Removed) 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
>>> 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.

Oops

--
Alex

Alex Young
Guest
Posts: n/a

 11-27-2007
Robert Klemme wrote:
> 2007/11/27, Phrogz <(E-Mail Removed)>:
>> On Nov 26, 5:24 pm, Alex Young <(E-Mail Removed)> wrote:
>>> (E-Mail Removed) 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
>>>> 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. )

http://hometown.aol.com/dicetalk/polymor2.htm

Nobody said dice have to be cubic...

--
Alex

Heesob Park
Guest
Posts: n/a

 11-27-2007
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
> end
>

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

def roll(n)
eval('+rand(6)+1'*n)
end

Regards,

Park Heesob
--
Posted via http://www.ruby-forum.com/.

William James
Guest
Posts: n/a

 11-27-2007
On Nov 26, 6:17 pm, (E-Mail Removed) 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
> end
>

def sum *x
x.inject{|a,b| a+b}
end
def roll n
sum( *(1..n).map{rand(6)+1} )
end