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]:
sumend
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. :-))
endend
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:
sumend
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:
sumend
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:
sumAnd 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:
sumThe 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-1
Eivind.
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 dousing 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