Robert Klemme
11/27/2007 9:07:00 AM
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