inverse_of_factorial_validation.sf 913 B

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. #!/usr/bin/ruby
  2. # Daniel "Trizen" Șuteu
  3. # Date: 29 April 2018
  4. # https://github.com/trizen
  5. # Compute the inverse of n-factorial.
  6. # The function is defined only for factorial numbers.
  7. func factorial_valuation(n,p) {
  8. (n - n.sumdigits(p)) / (p-1)
  9. }
  10. func inverse_factorial_lgrt(n) {
  11. define τ = Num.tau
  12. define e = Num.e
  13. define T = τ.root(-2*e)
  14. lgrt(T * n.root(e)) * e - 1/2
  15. }
  16. func inverse_factorial(f) {
  17. return nil if (f < 0)
  18. return 0 if (f <= 1)
  19. return nil if (f.is_odd)
  20. var n = inverse_factorial_lgrt(f).ceil
  21. for p in (primes(2, n)) {
  22. var v = factorial_valuation(n, p)
  23. f.valuation(p) == v || return nil
  24. f /= p**v
  25. }
  26. (f == 1) ? n : nil
  27. }
  28. say 7.by { defined(inverse_factorial(_)) } #=> [0, 1, 2, 6, 24, 120, 720]
  29. for n in (2..30) {
  30. var f = n!
  31. var i = inverse_factorial(f)
  32. say "#{i}! = #{f}"
  33. assert_eq(i, n)
  34. }