brazilian_numbers.sf 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. #!/usr/bin/ruby
  2. # https://rosettacode.org/wiki/Brazilian_numbers
  3. func is_Brazilian_prime(q) {
  4. static L = Set()
  5. static M = 0
  6. return true if L.has(q)
  7. return false if (q < M)
  8. var N = (q<500 ? 1000 : 2*q)
  9. for K in (primes(3, ilog2(N+1))) {
  10. for n in (2 .. iroot(N-1, K-1)) {
  11. var p = (n**K - 1)/(n-1)
  12. L << p if (p<N && p.is_prime)
  13. }
  14. }
  15. M = (L.max \\ 0)
  16. return L.has(q)
  17. }
  18. func is_Brazilian(n) {
  19. if (!n.is_prime) {
  20. n.is_square || return (n>6)
  21. var m = n.isqrt
  22. return (m>3 && (!m.is_prime || m==11))
  23. }
  24. is_Brazilian_prime(n)
  25. }
  26. with (20) {|n|
  27. say "First #{n} Brazilian numbers:"
  28. say (^Inf -> lazy.grep(is_Brazilian).first(n))
  29. say "\nFirst #{n} odd Brazilian numbers:"
  30. say (^Inf -> lazy.grep(is_Brazilian).grep{.is_odd}.first(n))
  31. say "\nFirst #{n} prime Brazilian numbers"
  32. say (^Inf -> lazy.grep(is_Brazilian).grep{.is_prime}.first(n))
  33. }
  34. assert_eq(is_Brazilian.first(20), [7, 8, 10, 12, 13, 14, 15, 16, 18, 20, 21, 22, 24, 26, 27, 28, 30, 31, 32, 33])
  35. assert_eq({.is_odd && is_Brazilian(_)}.first(20), [7, 13, 15, 21, 27, 31, 33, 35, 39, 43, 45, 51, 55, 57, 63, 65, 69, 73, 75, 77])
  36. assert_eq({.is_prime && is_Brazilian(_)}.first(20), [7, 13, 31, 43, 73, 127, 157, 211, 241, 307, 421, 463, 601, 757, 1093, 1123, 1483, 1723, 2551, 2801])
  37. assert_eq(is_Brazilian.nth(1e4), 11364)