Most elegant way to do this?

On 27.11.2007 20:24, Brian A. wrote:

number_of_dice.times do

The interface is “roll n” regardless of the underlying implementation,
sum = 0

SCNR :wink:

No apology necessary, I beat you to it :slight_smile: (I assume you meant sum =
num_dice)

Yes, of course. Copy & paste…

Cheers

robert

2007/11/27, Brian A. [email protected]:

end
so you might as well make it fast.
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

I 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
end

SCNR :wink:

robert

Le 27 novembre à 01:17, [email protected] a écrit :

Are there any more elegant, concise, pithy, and more Rubyish ways of
doing this?

Well, in the (maybe too) rubyish ways to do it, I kinda like :

class Fixnum
def dice(faces = 6)
r = self
self.times { r += rand(faces) }
r
end
end

If you feel even more adventurous, you can even rename it ‘d’, to
approach the role playing games notation with, for instance,
3.d(100)+8… :slight_smile:

Fred

On Nov 27, 8:34 am, Brian A. [email protected] wrote:

Why be satisfied with a 10-12% increase in speed when we can have an
order of magnitude? :slight_smile:

The original poster didn’t ask for the fastest possible
implementation; you only imagined that he did.

sudo gem install rubyinline

This doesn’t work at all. What were you imagining?

  int roll(int n) {
    int sum = n;
    while (n-- > 0) {
      sum += (rand() % 6);
    }
    return sum;
  }

That C-code is hideous. Let’s compare it to something
that isn’t insanely low-level.

function roll( n: integer ): integer;
var i: integer;
begin
result := n;
for i := 1 to n do result += random(6)
end;

On Nov 27, 7:17 am, Brian A. [email protected] wrote:

    sum += rand(5).next

sum( *(1…n).map{rand(6)+1} )
end

Clever, but 3 times slower than the original (after correcting it).

What so-called correction did you imagine that you had to make?

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

vi buffer:

%w{Str Int Dex Wis Con Cha}.each do |attribute|
number_of_dice = 3
sum = 0
number_of_dice.times {sum += (rand(6) + 1)}
puts “#{attribute}: #{sum}”
end

irb:

vi
Str: 14
Int: 12
Dex: 9
Wis: 11
Con: 8
Cha: 16
=> [“Str”, “Int”, “Dex”, “Wis”, “Con”, “Cha”]

using four dice and taking out the lowest number will give you better
results, but it gets the job done.


Giles B.

Podcast: http://hollywoodgrit.blogspot.com
Blog: http://gilesbowkett.blogspot.com
Portfolio: http://www.gilesgoatboy.org
Tumblelog: http://giles.tumblr.com

On Nov 27, 5:50 pm, William J. [email protected] wrote:

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

What so-called correction did you imagine that you had to make?

Sorry for the ambiguity; “it” referred to the original - see other
posts for the imagined correction, so called :wink:

William J. wrote:

That C-code is hideous. Let’s compare it to something
that isn’t insanely low-level.

OOOOO! I know this one!

If you meant this as pascal, this is the code:

function roll( n: integer ): integer;
var i: integer;
begin
for i := 1 to n do result := inc(result, random(6) + 1);
end;

There is no += in pascal. If only… :slight_smile: Your version where you init
the result so you do not have to add may run faster but I golfed it a
bit. Still, it is far better than the C version. I liked seeing it
here too. :slight_smile:

On Nov 28, 8:10 am, Lloyd L. [email protected] wrote:

begin
for i := 1 to n do result := inc(result, random(6) + 1);
end;

There is no += in pascal. If only… :slight_smile: Your version where you init
the result so you do not have to add may run faster but I golfed it a
bit. Still, it is far better than the C version. I liked seeing it
here too. :slight_smile:

You do realize that the C code I embedded in the Ruby program actually
ran automatically via “ruby myfile.rb”, and that was the point, right?

On Nov 28, 7:10 am, Lloyd L. [email protected] wrote:

begin
for i := 1 to n do result := inc(result, random(6) + 1);
end;

There is no += in pascal. If only… :slight_smile: Your version where you init
the result so you do not have to add may run faster but I golfed it a
bit. Still, it is far better than the C version. I liked seeing it
here too. :slight_smile:

Glad you liked it. It strikes me as bizarre that so many Ruby
users who want more speed descend from the dizzying heights of
Ruby to the chthonic depths of ultra primitive C. Why not use
Pascal?

The version of Pascal that I am using does have +=.
It’s Free Pascal. Currently it’s #3 in the shootout.
(http://shootout.alioth.debian.org/gp4/benchmark.php?
test=all&lang=all)
The program below isn’t as fast as I expected; random() may be
a bit slow.

{$mode objfpc} // So that “result :=” can be used.
uses sysutils; // for timing

function roll( n: integer ): integer;
var i: integer;
begin
result := n;
for i := 1 to n do result += random(6)
end;

var i: integer;
when: tdatetime;
begin
randomize;
when := time;
for i := 1 to 3999000 do roll(2);
writeln( ((time-when)*secsperday):0:2 )
end.

On Nov 28, 2007 4:25 PM, William J. [email protected] wrote:

function roll( n: integer ): integer;
Glad you liked it. It strikes me as bizarre that so many Ruby
users who want more speed descend from the dizzying heights of
Ruby to the chthonic depths of ultra primitive C. Why not use
Pascal?

I would guess because more people know C than Pascal, and it is easier
to link Ruby to C than to Pascal?

Apart from that, having programmed both C and Pascal, I only see small
differences in level. Object Pascal aside, as far as I can remember
from my Pascal programming days (15 years since I wrote my last line
of Pascal - how time flies…), there’s little abstraction available
in Pascal that’s not there in C - the most I can think of would be
“with” and a nicer integration of the export/import module system.

Care to enlighten me as to how you see these as being at very different
levels?

Eivind.

On 2007-11-27 09:24 +0900 (Tue), Alex Y. wrote:

[email protected] wrote:

Are there any more elegant, concise, pithy, and more Rubyish ways of
doing this?..

The Incredible Inevitable Inject:…

If you’re interested in pursuing the study of elegance this direction,
you might consider procuring and working through a copy of The
Little Schemer
, perhaps followed by some playing with the Haskell
list-manipulation functions.

Ruby is quite amenable to many of the same techniques, with a couple
of caveats. The minor one is that it that it tends towards Smalltalk
idioms, such as inject instead of fold (or perhaps it’s just me when I’m
using Ruby). The bigger one is the lack of tail recursion, which has
bitten me more than a few times.

cjs

On Nov 28, 1:22 pm, Eivind E. [email protected] wrote:

If you meant this as pascal, this is the code:
here too. :slight_smile:
differences in level. Object Pascal aside, as far as I can remember
from my Pascal programming days (15 years since I wrote my last line
of Pascal - how time flies…), there’s little abstraction available
in Pascal that’s not there in C - the most I can think of would be
“with” and a nicer integration of the export/import module system.

Care to enlighten me as to how you see these as being at very different levels?

Eivind.

In C, in order to call by reference, you have to pass the address
of the variable to the function.

In C, you must use too many pointers.

In C, strings can’t contain ASCII 0.

In C, there is no boolean type.

In Free Pascal, you have 1- and 2-dimensional dynamic arrays,
i.e., arrays that can be resized at runtime.

In Free Pascal, you have array slicing:
average( scores[ 3…8 ] );
write( name[ 5…20 ] );

In Pascal, you can have automatic buffer-overflow checking
if you want.

In Pascal, you have sets:
if ‘e’ in good_chars then

“… the programming language C was designed to assist in
writing a small single-user operating system (UNIX) for a
real-time minicomputer (PDP 11), now thankfully obsolete.
For this purpose, its low level of abstraction and plethora
of machine-oriented features are entirely appropriate. For
all other purposes, they are a nuisance. The successful
propagation of the language can be explained by accidental,
commercial, historical, and political factors; it is hardly
due to any inherent quality as a tool for the reliable
creation of sophisticated programs.” - C. A. R. Hoare,
1994.

One of the most famous C gurus, Kernighan, apparently
can’t correct the bugs in his software because it’s
written in C. He has known of this bug in awk95 for
years:

BEGIN {
FS = “@”
$0 = “foo@bar”
print $1
}

It prints “foo@bar”, although it should print “foo”.