-
Notifications
You must be signed in to change notification settings - Fork 38
Expand file tree
/
Copy pathlucas-carmichael_numbers_in_range.pl
More file actions
83 lines (58 loc) · 3.73 KB
/
lucas-carmichael_numbers_in_range.pl
File metadata and controls
83 lines (58 loc) · 3.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#!/usr/bin/perl
# Daniel "Trizen" Șuteu
# Date: 27 August 2022
# https://github.com/trizen
# Generate all the Lucas-Carmichael numbers with n prime factors in a given range [a,b]. (not in sorted order)
# See also:
# https://en.wikipedia.org/wiki/Almost_prime
# https://trizenx.blogspot.com/2020/08/pseudoprimes-construction-methods-and.html
# PARI/GP program (in range [A,B]) (simple):
# lucas_carmichael(A, B, k) = A=max(A, vecprod(primes(k+1))\2); (f(m, l, lo, k) = my(list=List()); my(hi=sqrtnint(B\m, k)); if(lo > hi, return(list)); if(k==1, forprime(p=max(lo, ceil(A/m)), hi, my(t=m*p); if((t+1)%l == 0 && (t+1)%(p+1) == 0, listput(list, t))), forprime(p=lo, hi, if(gcd(m, p+1) == 1, list=concat(list, f(m*p, lcm(l, p+1), p+1, k-1))))); list); vecsort(Vec(f(1, 1, 3, k)));
# PARI/GP program (in range [A, B]) (fast):
# lucas_carmichael(A, B, k) = A=max(A, vecprod(primes(k+1))\2); my(max_p=sqrtint(B+1)-1); (f(m, l, lo, k) = my(list=List()); my(hi=min(max_p, sqrtnint(B\m, k))); if(lo > hi, return(list)); if(k==1, lo=max(lo, ceil(A/m)); my(t=lift(-1/Mod(m,l))); while(t < lo, t += l); forstep(p=t, hi, l, if(isprime(p), my(n=m*p); if((n+1)%(p+1) == 0, listput(list, n)))), forprime(p=lo, hi, if(gcd(m, p+1) == 1, list=concat(list, f(m*p, lcm(l, p+1), p+1, k-1))))); list); vecsort(Vec(f(1, 1, 3, k)));
# PARI/GP program to generate all the Lucas-Carmichael numbers <= n (fast):
# lucas_carmichael(A, B, k) = A=max(A, vecprod(primes(k+1))\2); my(max_p=sqrtint(B+1)-1); (f(m, l, lo, k) = my(list=List()); my(hi=min(max_p, sqrtnint(B\m, k))); if(lo > hi, return(list)); if(k==1, lo=max(lo, ceil(A/m)); my(t=lift(-1/Mod(m,l))); while(t < lo, t += l); forstep(p=t, hi, l, if(isprime(p), my(n=m*p); if((n+1)%(p+1) == 0, listput(list, n)))), forprime(p=lo, hi, if(gcd(m, p+1) == 1, list=concat(list, f(m*p, lcm(l, p+1), p+1, k-1))))); list); f(1, 1, 3, k);
# upto(n) = my(list=List()); for(k=3, oo, if(vecprod(primes(k+1))\2 > n, break); list=concat(list, lucas_carmichael(1, n, k))); vecsort(Vec(list));
use 5.036;
use ntheory 0.74 qw(:all);
sub lucas_carmichael_numbers_in_range ($A, $B, $k) {
$A = vecmax($A, pn_primorial($k));
# Largest possisble prime factor for Lucas-Carmichael numbers <= B
my $max_p = sqrtint($B);
my @list;
sub ($m, $L, $lo, $k) {
my $hi = rootint(divint($B, $m), $k);
if ($lo > $hi) {
return;
}
if ($k == 1) {
$hi = $max_p if ($hi > $max_p);
$lo = vecmax($lo, cdivint($A, $m));
$lo > $hi && return;
my $t = $L - invmod($m, $L);
$t > $hi && return;
$t += $L * cdivint($lo - $t, $L) if ($t < $lo);
for (my $p = $t ; $p <= $hi ; $p += $L) {
if (($m * $p + 1) % ($p + 1) == 0 and is_prime($p)) {
push @list, $m * $p;
}
}
return;
}
foreach my $p (@{primes($lo, $hi)}) {
if (gcd($m, $p + 1) == 1) {
__SUB__->($m * $p, lcm($L, $p + 1), $p + 1, $k - 1);
}
}
}
->(1, 1, 3, $k);
return sort { $a <=> $b } @list;
}
# Generate all the Lucas-Carmichael numbers with 5 prime factors in the range [100, 10^8]
my $k = 5;
my $from = 100;
my $upto = 1e8;
my @arr = lucas_carmichael_numbers_in_range($from, $upto, $k);
say join(', ', @arr);
__END__
588455, 1010735, 2276351, 2756159, 4107455, 4874639, 5669279, 6539819, 8421335, 13670855, 16184663, 16868159, 21408695, 23176439, 24685199, 25111295, 26636687, 30071327, 34347599, 34541639, 36149399, 36485015, 38999519, 39715319, 42624911, 43134959, 49412285, 49591919, 54408959, 54958799, 57872555, 57953951, 64456223, 66709019, 73019135, 77350559, 78402815, 82144799, 83618639, 86450399, 93277079, 96080039, 98803439