From: Robert Klemme Date: 2007-11-27T18:06:49+09:00 Subject: Re: Most elegant way to do this? 2007/11/27, Phrogz : > On Nov 26, 5:24 pm, Alex Young 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