Forum: Ruby Ruby Math (nPr, nCr)

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
425cab08658a06567879717de154552c?d=identicon&s=25 Ari Brown (Guest)
on 2007-05-26 03:58
(Received via mailing list)
What's that? You want me to ask more questions? Sure!

So I'm writing a pascals triangle program. My goal is to write it in
fewer lines than those on the RubyQuiz site. My idea is to use more
math, and less programming.

So in order for my method to work, I sorta need to recreate nPr and
nCr functions. To be official and learn more, I am doing this through
a class. However, every time I run it, I get the following errors:

pascal.rb:29:in `pascal': undefined method `nCr' for 1:Fixnum
(NoMethodError)
         from pascal.rb:24:in `upto'
         from pascal.rb:24:in `pascal'
         from pascal.rb:41

My code:

# Pascals triangle

class Integer

   def self.nPr(r)
     numerator   = factorial(self)
     denominator = factorial(self - r)

     @permutations = numerator / denominator
   end

   def self.nCr(r)
     numerator   = factorial(self)
     denominator = factorial(r) * factorial(self - r)

     @combinations = numberator / denominator
   end

end


def pascal max_row

   0.upto(max_row) {|row_num|

     holder = []
     ticker = 0
     while ticker != row_num
       result = row_num.nCr(ticker)
       ticker = ticker + 1
       holder = result.push
     end
     puts holder.join(' ').center(80)

   }

end

puts 'How many rows do you want?'
max_row = gets.chomp.to_i
pascal max_row


Any help?

Thanks,
Ari
--------------------------------------------|
If you're not living on the edge,
then you're just wasting space.
Caf38c89d40443a858741b61ac6d82de?d=identicon&s=25 Dan Zwell (Guest)
on 2007-05-26 04:46
(Received via mailing list)
Ari Brown wrote:
>     numerator   = factorial(self)
>     denominator = factorial(self - r)
>
>     @permutations = numerator / denominator
>   end
> end

Ari,

It looks like you are defining--don't remember the ruby term--java calls
it a static method. You want an instance method. Just declare it as
def self(r)
and not
def self.nPr(r)
because that is called like:
Integer.nPr(something)
and you want:
my_number.nPr(r)

Dan
Caf38c89d40443a858741b61ac6d82de?d=identicon&s=25 Dan Zwell (Guest)
on 2007-05-26 05:58
(Received via mailing list)
Dan Zwell wrote:
> You want an instance method. Just declare it as
> def self(r)
> and not
> def self.nPr(r)

Oops. I meant:

def nPr(r)

Good luck.
Dan
7a561ec0875fcbbe3066ea8fe288ec77?d=identicon&s=25 Sebastian Hungerecker (Guest)
on 2007-05-26 10:03
(Received via mailing list)
Dan Zwell wrote:
> It looks like you are defining--don't remember the ruby term--java calls
> it a static method.

Class methods.
753dcb78b3a3651127665da4bed3c782?d=identicon&s=25 Brian Candler (Guest)
on 2007-05-26 16:11
(Received via mailing list)
On Sat, May 26, 2007 at 10:57:16AM +0900, Ari Brown wrote:
>
>   def self.nCr(r)
>     numerator   = factorial(self)
>     denominator = factorial(r) * factorial(self - r)
>
>     @combinations = numberator / denominator
>   end
>
> end

Of course Ruby has Bignums, but you could make the program more
efficient by
not calculating such enormous intermediate values and then dividing
them.

I suggest you cancel out the terms which are common to the numerator and
denominator.

That is, 9C4 is 9!/5!/!4!, but 9!/5! is 9*8*7*6, so the result is
9*8*7*6/4*3*2*1. Also, you can swap r and n-r to minimise the
calculation.

Example:

def Math.nCr(n,r)
  a, b = r, n-r
  a, b = b, a if a < b  # a is the larger
  numer = (a+1..n).inject(1) { |t,v| t*v }  # n!/r!
  denom = (2..b).inject(1) { |t,v| t*v }    # (n-r)!
  numer/denom
end

(0..9).each { |r| puts Math.nCr(9,r) }

As for making these instance variables of Integer (without self.):
that's
fine, but I'd suggest you make them class methods of Math or of your own
module. Whilst

   Math.nCr(9,4)

is a bit more long-winded to type than 9.nCr(4), it avoids cluttering
Integer with more methods.

Regards,

Brian.
This topic is locked and can not be replied to.