Skip to content

Instantly share code, notes, and snippets.

@jleeothon
Last active August 29, 2015 14:08
Show Gist options
  • Save jleeothon/98d42a68856f13585dce to your computer and use it in GitHub Desktop.
Save jleeothon/98d42a68856f13585dce to your computer and use it in GitHub Desktop.
Ruby combinatorics
class Integer
def !
if self > 0
(1..self).reduce :*
elsif self.zero?
1
else
raise ArgumentError, "No factorial for #{self}"
end
end
alias :"!@" :!
alias :fact :!
def choose r
raise ArgumentError, "r = #{r} is outside 0..#{self}" if r < 0 or r > self
(self.!).fdiv((self - r).!).fdiv(r.!).to_i
end
end
def nice n, p=3
return n unless n.kind_of? Numeric
i = n.to_i
f = ((n - i).round(p).to_s)[2..-1]
i = i.to_s.reverse.gsub(/...(?=.)/, '\& ').reverse
"#{i}.#{f}"
end
def ncr n, r
raise ArgumentError, "r = #{r} is outside 0..#{n}" if r < 0 or r > n
n.choose r
end
def npr n, r
raise ArgumentError, "r = #{r} is outside 0..#{n}" if r < 0 or r > n
n.!.fdiv((n - r).!).to_i
end
def binomial(n, x, p)
raise ArgumentError, "x=#{x} cannot be greater than n=#{n}" if x > n
n.choose(x) * p ** x * (1 - p) ** (n - x)
end
@jleeothon
Copy link
Author

Fun things to try:

puts 8.! # 40320
puts !8 # 40320, for the sake of fun
puts 8.fact # 40320, for the sake of fun

puts(7.choose 0) # 1
puts(7.choose 1) # 7
puts(7.choose 2) # 21
puts(7.choose 4) # 35
puts(7.choose 5) # 21
puts(7.choose 6) # 7
puts(7.choose 7) # 1

puts(npr 7, 6) # 5040

puts(binomial(8, 3, 0.4)) # 0.27869184

@jleeothon
Copy link
Author

Also, to use the nice function, remember the special variable underscore, i.e. _! (Only works in irb 😢)

> nice 4345.34535
=> "4 345.345"
> 8379.44
=> 8379.44
> nice _
=> "8 379.44"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment