[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Most elegant way to do this?

Joshua Choi

11/27/2007 12:18:00 AM

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!
32 Answers

Alex Young

11/27/2007 12:24:00 AM

0

rbysamppi@gmail.com 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
>
> Thanks in advance!
>

The Incredible Inevitable Inject:

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

--
Alex

JC

11/27/2007 12:27:00 AM

0

rbysamppi@gmail.com 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
>
> 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 :P )

-JC

Phrogz

11/27/2007 6:40:00 AM

0

On Nov 26, 5:24 pm, Alex Young <a...@blackkettle.org> wrote:
> rbysam...@gmail.com 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

11/27/2007 9:07:00 AM

0

2007/11/27, Phrogz <phrogz@mac.com>:
> On Nov 26, 5:24 pm, Alex Young <a...@blackkettle.org> wrote:
> > rbysam...@gmail.com 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
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

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

Robert Klemme

11/27/2007 9:21:00 AM

0

2007/11/27, Robert Klemme <shortcutter@googlemail.com>:
> 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

Alex Young

11/27/2007 9:36:00 AM

0

Phrogz wrote:
> On Nov 26, 5:24 pm, Alex Young <a...@blackkettle.org> wrote:
>> rbysam...@gmail.com 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

11/27/2007 9:37:00 AM

0

Robert Klemme wrote:
> 2007/11/27, Phrogz <phrogz@mac.com>:
>> On Nov 26, 5:24 pm, Alex Young <a...@blackkettle.org> wrote:
>>> rbysam...@gmail.com 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/po...

Nobody said dice have to be cubic...

--
Alex

Heesob Park

11/27/2007 10:04:00 AM

0

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
>
> Thanks 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 Heesob
--
Posted via http://www.ruby-....

William James

11/27/2007 11:27:00 AM

0

On Nov 26, 6:17 pm, rbysam...@gmail.com 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
>
> Thanks in advance!

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

Robert Dober

11/27/2007 11:43:00 AM

0

On Nov 27, 2007 7:40 AM, Phrogz <phrogz@mac.com> wrote:
> On Nov 26, 5:24 pm, Alex Young <a...@blackkettle.org> wrote:
> > rbysam...@gmail.com 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
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.blo...

---
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.)