omega_primes.sf 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. #!/usr/bin/ruby
  2. # a(n) is the smallest centered n-gonal number with exactly n distinct prime factors.
  3. # https://oeis.org/A358894
  4. # Known terms:
  5. # 460, 99905, 463326, 808208947, 23089262218
  6. # PARI/GP program:
  7. #`(
  8. # Version 1
  9. omega_polygonals(A, B, n, k) = A=max(A, vecprod(primes(n))); (f(m, p, j) = my(list=List()); forprime(q=p, sqrtnint(B\m, j), my(s=q%k); if(s==1 || s==7 || s==9 || s==15, my(v=m*q, r=nextprime(q+1)); while(v <= B, if(j==1, if(v>=A, if (issquare((8*(v-1))/k + 1) && ((sqrtint((8*(v-1))/k + 1)-1)%2 == 0), listput(list, v))), if(v*r <= B, list=concat(list, f(v, r, j-1)))); v *= q))); list); vecsort(Vec(f(1, 2, n)));
  10. a(n, k=n) = if(n < 3, return()); my(x=vecprod(primes(n)), y=2*x); while(1, my(v=omega_polygonals(x, y, n, k)); if(#v >= 1, return(v[1])); x=y+1; y=2*x); \\ ~~~~
  11. # Version 2
  12. omega_polygonals(A, B, n, k) = A=max(A, vecprod(primes(n))); (f(m, p, j) = my(list=List()); forprime(q=p, sqrtnint(B\m, j), my(s=q%k); if(s==1 || s==9, my(v=m*q, r=nextprime(q+1)); while(v <= B, if(j==1, if(v>=A, if (issquare((8*(v-1))/k + 1) && ((sqrtint((8*(v-1))/k + 1)-1)%2 == 0), listput(list, v))), if(v*r <= B, list=concat(list, f(v, r, j-1)))); v *= q))); list); vecsort(Vec(f(1, 2, n)));
  13. a(n, k=n) = if(n < 3, return()); my(x=vecprod(primes(n)), y=2*x); while(1, my(v=omega_polygonals(x, y, n, k)); if(#v >= 1, return(v[1])); x=y+1; y=2*x); \\ ~~~~
  14. )
  15. # Find the residues of the prime factors of centered n-gonal numbers:
  16. # for n in (3..20) { say [n, 1000.of {|k| ((n*k*(k+1))/2 + 1) }.map{.factor.map{.mod(n)}}.flat.uniq.sort] }
  17. # Resides for each n = 3..n:
  18. #`(
  19. [3, [1, 2]]
  20. [4, [1]]
  21. [5, [1, 2, 3, 4]]
  22. [6, [1]]
  23. [7, [1, 2, 4]]
  24. [8, [1, 3, 5, 7]]
  25. [9, [1, 2, 4, 5, 7, 8]]
  26. [10, [1, 9]]
  27. [11, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]
  28. [12, [1, 11]]
  29. [13, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]]
  30. [14, [1, 3, 5, 9, 11, 13]]
  31. [15, [1, 2, 4, 7, 8, 11, 13, 14]]
  32. [16, [1, 7, 9, 15]]
  33. [17, [1, 2, 3, 4, 8, 9, 13, 15, 16]]
  34. [18, [1, 5, 7, 11, 13, 17]]
  35. [19, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]]
  36. [20, [1, 3, 7, 9, 11, 13, 17, 19]]
  37. )
  38. func upper_bound(n, from = 2, upto = 2*from) {
  39. say "\n:: Searching an upper-bound for a(#{n})\n"
  40. loop {
  41. var count = n.squarefree_almost_prime_count(from, upto)
  42. if (count > 0) {
  43. say "Sieving range: [#{from}, #{upto}]"
  44. say "This range contains: #{count.commify} elements\n"
  45. n.squarefree_almost_primes_each(from, upto, {|v|
  46. if ((n `divides` 8*v.dec) && (8*v.dec / n + 1 -> is_square)) {
  47. say "a(#{n}) = #{v}"
  48. return v
  49. }
  50. })
  51. }
  52. from = upto+1
  53. upto *= 2
  54. }
  55. }
  56. upper_bound(13)
  57. __END__
  58. a(3) = 460
  59. a(4) = 99905
  60. a(5) = 463326
  61. a(6) = 808208947
  62. a(7) = 23089262218
  63. a(8) = 12442607161209225
  64. a(9) = 53780356630
  65. a(10) = 700326051644920151
  66. a(11) = 46634399568693102
  67. a(12) = 45573558879962759570353