combinations_and_permutations.sf 946 B

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. #!/usr/bin/ruby
  2. func P(n, k) { n! / ((n-k)!) }
  3. func C(n, k) { binomial(n, k) }
  4.  
  5. class Logarithm(value) {
  6. method to_s {
  7. var e = int(value/10.log)
  8. "%.8fE%+d" % (exp(value - e*10.log), e)
  9. }
  10. }
  11.  
  12. func lstirling(n) {
  13. n < 10 ? (lstirling(n+1) - log(n+1))
  14.  : (0.5*log(2*Num.pi*n) + n*log(n/Num.e + 1/(12*Num.e*n)))
  15. }
  16.  
  17. func P_approx(n, k) {
  18. Logarithm((lstirling(n) - lstirling(n -k)))
  19. }
  20.  
  21. func C_approx(n, k) {
  22. Logarithm((lstirling(n) - lstirling(n -k) - lstirling(k)))
  23. }
  24.  
  25. say "=> Exact results:"
  26. for n (1..12) {
  27. var p = n//3
  28. say "P(#{n}, #{p}) = #{P(n, p)}"
  29. }
  30. for n (10..60 `by` 10) {
  31. var p = n//3
  32. say "C(#{n}, #{p}) = #{C(n, p)}"
  33. }
  34. say '';
  35. say "=> Floating point approximations:"
  36. for n ([5, 50, 500, 1000, 5000, 15000]) {
  37. var p = n//3
  38. say "P(#{n}, #{p}) = #{P_approx(n, p)}"
  39. }
  40. for n (100..1000 `by` 100) {
  41. var p = n//3
  42. say "C(#{n}, #{p}) = #{C_approx(n, p)}"
  43. }