[CoLoCo] dice rolls in C

Dale K. Hawkins dkhawk at gmail.com
Sat Feb 9 04:50:30 GMT 2008


Yes, this is the distinct advantage of C and C++: speed of execution.

The errors come from trying to add 1 to nil.  Basically, the array is setup
for the original bounds of the problem.  This can be fixed several ways:

1. Make a bigger array
2. Use a Hash with an initialization block (totals = Hash { 0 } )
3. Check for nil when doing the assignment:

faces = ARGV[0] || 6
totals = Array.new
10000.times do
    total = rand(faces) + 1 + rand(faces) + 1
    totals[total] = (totals[total] || 0) + 1
end

This allow the number of faces to be given as an argument or to default to
6.  The magic is the "totals[total] || 0" which means, use the value of
previous count or zero(0) if it was nil.

OK.  But Ruby is much more powerful than this.  We can, for example, say we
want to be able to add a number to nil and have it return the number (i.e.,
treat nil like it was zero):

class NilClass
  def +(num)
    num
  end
end

faces = ARGV[0] || 6
totals = Array.new
10000.times do
    total = rand(faces) + 1 + rand(faces) + 1
    totals[total] += 1
end

puts totals

Gotta go.  Need to put the kids to bed.

-Dale

On Feb 8, 2008 9:28 PM, Jim Hutchinson <jim at ubuntu-rocks.org> wrote:

> On Feb 5, 2008 1:30 PM, Dale K. Hawkins <dkhawk at gmail.com> wrote:
> > The Ruby version FWIW:
> >
> > ============================8<================================
> >
> > # seed the random number generator
> > srand
> >
> > # create the output array initialized to zeros (too big because 0 and 1
> are
> > invalid input; so sue me)
> >  totals = Array.new(13) { 0 }
> >
> > # run 100,000 times (this number can be much larger if you want; Ruby
> > supports automatically grow a number.  Speed does start to be an issue
> > however.
> > # The underscores help readability, but are unnecessary
> >  # the code inside the {}'s is repeatedly run
> > # rand(6) returns a result in the range 0..5 inclusive so we add 1
> > # (rand(6) + 1) is one die, we need two
> > 100_000.times { totals[(rand(6) + 1) + (rand(6) + 1) ] += 1 }
> >
> > # show some output....
> > totals.each_with_index { | t, i | puts "#{t}: #{i}" }
> >
> > ============================8<================================
> >
> > -Dale
> >
>
> Thanks for sharing this. I finally had a chance to try it. Much easier
> to work with than the C program. No compiling or anything. However, it
> does seem a bit slower. 10 million rolls in the C program took about a
> second. I changed this to 10 million and it took about 15 seconds. 10
> billion rolls in the C program took about 15 mins. I'm assuming then
> that 10 billion in the ruby program would take around 15 times as
> long.
>
> Also, if i wanted to roll 10 sided dice (number 0-9 for totals of
> 0-18) what would I change? I tried changing the 6s to 10s but got
> errors.
>
> --
> Please avoid sending me Word or PowerPoint attachments.
> See http://www.gnu.org/philosophy/no-word-attachments.html
>
> --
> Ubuntu-us-co mailing list
> Ubuntu-us-co at lists.ubuntu.com
> Modify settings or unsubscribe at:
> https://lists.ubuntu.com/mailman/listinfo/ubuntu-us-co
>



-- 
All creativity is an extended form of a joke.
- Alan Kay
-------------- next part --------------
An HTML attachment was scrubbed...
URL: https://lists.ubuntu.com/archives/ubuntu-us-co/attachments/20080208/ef2d562b/attachment.htm 


More information about the Ubuntu-us-co mailing list