modular_bell_numbers_recurrence.sf 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. #!/usr/bin/ruby
  2. # A recurrence for computing the Bell numbers modulo a given integer.
  3. # Interesting fact:
  4. # Bell(p) == 2 (mod p) for prime numbers p.
  5. # See also:
  6. # https://oeis.org/A166226 -- Bell number n modulo n.
  7. # https://oeis.org/A325630 -- Numbers k such that Bell(k) is divisible by k.
  8. # https://mathworld.wolfram.com/BellNumber.html
  9. func modular_binomial(n, k, m) is cached {
  10. return 1 if (n == k)
  11. return 0 if (n == 0)
  12. (__FUNC__(n-1, k-1, m) + __FUNC__(n-1, k, m)) % m
  13. }
  14. func modular_bell(n, k=0, m=n) is cached {
  15. return 1 if (n == 0)
  16. return 0 if (k == n)
  17. (__FUNC__(n, k+1, m) + (__FUNC__(k, 0, m)*modular_binomial(n-1, k, m))) % m
  18. }
  19. for k in (1..20) {
  20. say "Bell(#{'%2d' % k}) == #{'%2d' % modular_bell(k)} (mod #{k})"
  21. }
  22. __END__
  23. Bell( 1) == 0 (mod 1)
  24. Bell( 2) == 0 (mod 2)
  25. Bell( 3) == 2 (mod 3)
  26. Bell( 4) == 3 (mod 4)
  27. Bell( 5) == 2 (mod 5)
  28. Bell( 6) == 5 (mod 6)
  29. Bell( 7) == 2 (mod 7)
  30. Bell( 8) == 4 (mod 8)
  31. Bell( 9) == 6 (mod 9)
  32. Bell(10) == 5 (mod 10)
  33. Bell(11) == 2 (mod 11)
  34. Bell(12) == 1 (mod 12)
  35. Bell(13) == 2 (mod 13)
  36. Bell(14) == 12 (mod 14)
  37. Bell(15) == 5 (mod 15)
  38. Bell(16) == 3 (mod 16)
  39. Bell(17) == 2 (mod 17)
  40. Bell(18) == 13 (mod 18)
  41. Bell(19) == 2 (mod 19)
  42. Bell(20) == 12 (mod 20)