Data update

This commit is contained in:
Ingy döt Net 2026-04-30 12:34:36 -04:00
parent 4bb20c9b71
commit cbaf4c4b64
12390 changed files with 318560 additions and 27248 deletions

View file

@ -0,0 +1,61 @@
program circularprimes;
{$mode objfpc}
function IsPrime(n: Cardinal): Boolean;inline;
var
i, limit: Cardinal;
begin
if (n = 2) or (n = 3) then Exit(True);
if (n <= 1) or (n mod 2 = 0) or (n mod 3 = 0) then Exit(False);
i := 5;
limit := Trunc(Sqrt(n));
while i <= limit do
begin
if (n mod i = 0) or (n mod (i + 2) = 0) then Exit(False);
Inc(i, 6);
end;
Result := True;
end;
function cycle(const n:Cardinal):Cardinal;inline;
var
m:Cardinal;
p:Cardinal = 1;
begin
m := n;
while m >= 10 do
begin
p := p * 10;
m := m div 10;
end;
result := m + 10 * (n mod p);
end;
function IsCircularPrime(N: Cardinal): boolean;inline;
var
p:Cardinal;
begin
p := n;
repeat
if not IsPrime(p) or (p<n) then exit(false);
p := Cycle(p);
until p = n;
Result:=True;
end;
var
i,c: Cardinal;
s: string = '';
begin
c := 0;
for i := 0 to High(i) do
if IsPrime(i) then
if IsCircularPrime(i) then
begin
Inc(c);
writestr(s,s,i:7);
if c >= 19 then break;
If c mod 5 = 0 then s:=s+lineEnding;
end;
writeln(s,' Count = ',c);
end.

View file

@ -0,0 +1,283 @@
program CircularPrimes;
//nearly the way it is done:
//http://www.worldofnumbers.com/circular.htm
{$IFDEF FPC}
{$Release}
{$MODE DELPHI}{$OPTIMIZATION ON,ALL}{$Coperators ON}
// {$O+,R+}
uses
Sysutils,gmp;
{$ENDIF}
{$IFDEF Delphi}
uses
System.Sysutils,?gmp?;
{$ENDIF}
{$IFDEF WINDOWS}
{$APPTYPE CONSOLE}
{$ENDIF}
const
Pot10 :array[0..19] of Uint64 =
(1,10,100,1000,10000,100000,1000000,
10000000,100000000,1000000000,10000000000,100000000000,1000000000000,10000000000000,
100000000000000,1000000000000000,10000000000000000,100000000000000000,1000000000000000000,10000000000000000000);
MAXCNTOFDIGITS = 19;
type
tDigits = 0..9;
tUsedDigits = set of tDigits;
tmyNum = record
Dgts: array[0..MAXCNTOFDIGITS] of tDigits;
num : Uint64;
UsedDgt : tUsedDigits;
end;
var
CheckNum : array[0..MAXCNTOFDIGITS] of Uint64;
Found : array[0..23] of Uint64;
mpz : mpz_t;
cntPrmTest,
cntRot : Uint64;
SolCount : Int32;
procedure ExtendRepUnit(var mpz:mpz_t;idx1,idx2:Int32);
begin
inc(idx1);
dec(idx2,9);
while idx1 < idx2 do
begin
mpz_mul_ui(mpz,mpz,1000000000);// 2020 Windows only uses Uint32
mpz_add_ui(mpz,mpz,0111111111);
inc(idx1,9);
end;
inc(idx2,9);
For idx1 := idx1 to idx2 do
begin
mpz_mul_ui(mpz,mpz,10);
mpz_add_ui(mpz,mpz,1);
end;
end;
procedure CheckOne(MaxIdx:integer);
begin
MaxIdx -= 1;
Found[SolCount] := CheckNum[MaxIdx];
repeat
mpz_set_ui(mpz,CheckNum[MaxIdx]);
If mpz_probab_prime_p(mpz,3)=0then
EXIT;
inc(cntPrmTest);
dec(MaxIdx);
until MaxIdx < 0;
inc(SolCount);
end;
procedure InitNum(var myNum:tmyNum;maxDgt:Int32);
var
i: Int32;
begin
fillchar(myNum,SizeOf(myNum),#0);
with myNum do
Begin
num := 0;
For i := 0 to MaxDgt-1 do
begin
Dgts[i] := 1;
num += Pot10[i];
end;
end;
end;
procedure CorrectNum(var myNum:tmyNum;maxIdx,idx:Int32);
var
n : Uint64;
dgt :int32;
begin
with myNum do
begin
dec(MaxIdx);
dgt := Dgts[maxIdx];
n := 0;
while maxIdx>idx do
Begin
n += Dgts[maxIdx]*Pot10[maxIdx];
dec(maxIdx);
end;
For Idx := Idx downto 0 do
Begin
Dgts[idx]:= dgt;
n += Dgt*Pot10[Idx];
end;
num := n;
end;
end;
function IncNum(var myNum:tmyNum;maxDgt:Int32):boolean;
//Next number with only digits of 1,3,7,9
var
n :Uint64;
i,dgt: Int64;
Udgt : tusedDigits;
begin
with myNum do
Begin
n := num;
i := 0;
repeat
dgt := Dgts[i];
dgt +=2;
n += 2*Pot10[i];
if dgt = 5 then
begin
dgt := 7;
n += 2*Pot10[i];
end;
if dgt < 10 then
begin
Dgts[i] := dgt;
Break;
end;
//correct values
Dgts[i] := 1;
dec(n,Pot10[i]*10);
inc(i);
until i >= maxDgt;
if i >= maxDgt then
EXIT(false);
dgt := Dgts[maxDgt-1];
if dgt > 1 then
Begin
i := maxDgt-2;
while i >= 0 do
begin
if Dgts[i]< dgt then
begin
//311->333 // 91111 -> 99999
CorrectNum(myNum,maxDgt,i);
EXIT(true);
end;
dec(i);
end;
end;
num := n;
end;
result := true;
end;
function rotateNum(n:Uint64;maxDgt:Int32):boolean;
//rotate number and check divisibility by 3 and 7
var
Pot,q ,dgt,n0: Uint64;
begin
n0 := n;
if n0 mod 3 = 0 then
exit(false);
if n0 mod 7 = 0 then
exit(false);
dec(maxDgt);
CheckNum[maxDgt] := n;
Pot := Pot10[maxDgt];
while maxDgt>0 do
Begin
inc(cntRot);
q := n div 10;
//last dgt = n mod 10
dgt := n - 10*q;
n := dgt*Pot+q;
//tested elsewhere before
if n < n0 then
exit(false);
if n mod 7 = 0 then
exit(false);
dec(maxDgt);
CheckNum[maxDgt] := n;
end;
result := true;
end;
var
myNum : TmyNum;
s :AnsiString;
T0: Int64;
idx,idx2 : NativeInt;
begin
T0 := GetTickCount64;
mpz_init(mpz);
SolCount := 0;
//one digit primes including 5
For idx := 2 to 10 do
if idx in[2,3,5,7] then
begin
Found[SolCount]:= Idx;
inc(SolCount);
end;
writeln(' search for circular Primes');
writeln(' digits found rotated numbers to test time in ms ');
cntPrmTest := 0;
cntRot := 0;
For idx := 2 to 16 do
begin
InitNum(myNum,idx);
repeat
if rotateNum(myNum.num,idx) then
CheckOne(idx);
until Not(IncNUm(myNum,idx));
writeln(idx:7,Solcount:7,cntRot:17,cntPrmTest:12,GetTickCount64-T0:8);
end;
writeln;
writeln('Found these ',solcount,' circular primes: ');
For idx := 0 to solCount-2 do
write(Found[idx],',');
writeln(Found[solCount-1]);
mpz_set_ui(mpz,1);
For idx := 2 to 1031 do
begin
mpz_mul_ui(mpz,mpz,10);
mpz_add_ui(mpz,mpz,1);
if mpz_probab_prime_p(mpz,1)=1 then
writeln('Found prime RepUnit(',idx,')');
end;
(*
idx := 1031;idx2 := 5003;
ExtendRepUnit(mpz,idx,idx2);
write(' Found prime RepUnit(',idx2,')');
writeln(boolean(Ord(mpz_probab_prime_p(mpz,1))));
idx := idx2;idx2 := 9887;
ExtendRepUnit(mpz,idx,idx2);
write(' Found prime RepUnit(',idx2,')');
writeln(boolean(Ord(mpz_probab_prime_p(mpz,1))));
idx := idx2;idx2 := 15073;
ExtendRepUnit(mpz,idx,idx2);
write(' Found prime RepUnit(',idx2,')');
writeln(boolean(Ord(mpz_probab_prime_p(mpz,1))));
idx := idx2;idx2 := 15073;
ExtendRepUnit(mpz,idx,idx2);
write(' Found prime RepUnit(',idx2,')');
writeln(boolean(Ord(mpz_probab_prime_p(mpz,1))));
idx := idx2;idx2 := 25031;
ExtendRepUnit(mpz,idx,idx2);
write(' Found prime RepUnit(',idx2,')');
writeln(boolean(Ord(mpz_probab_prime_p(mpz,1))));
idx := idx2;idx2 := 35317;
ExtendRepUnit(mpz,idx,idx2);
write(' Found prime RepUnit(',idx2,')');
writeln(boolean(Ord(mpz_probab_prime_p(mpz,1))));
idx := idx2;idx2 := 49081;
ExtendRepUnit(mpz,idx,idx2);
write(' Found prime RepUnit(',idx2,')');
writeln(boolean(Ord(mpz_probab_prime_p(mpz,1))));
// real 8m9,733s
*)
mpz_clear(mpz);
{$IFDEF WINDOWS}
readln;
{$ENDIF}
end.

View file

@ -0,0 +1,167 @@
// Check if a number is prime (works with Number type)
function isPrime(n) {
if (n < 2) return false;
if (n % 2 === 0) return n === 2;
if (n % 3 === 0) return n === 3;
for (let p = 5; p * p <= n; p += 4) {
if (n % p === 0) return false;
p += 2;
if (n % p === 0) return false;
}
return true;
}
// Rotate the digits of a number: 197 -> 719 -> 971
function cycle(n) {
const s = n.toString();
if (s.length === 1) return n;
return parseInt(s.slice(1) + s[0], 10);
}
// Check if a number is a circular prime
function isCircularPrime(p) {
if (!isPrime(p)) return false;
// Quick check: multi-digit circular primes cannot contain 0,2,4,5,6,8
const s = p.toString();
if (s.length > 1 && /[024568]/.test(s)) return false;
let p2 = cycle(p);
while (p2 !== p) {
if (p2 < p || !isPrime(p2)) return false;
p2 = cycle(p2);
}
return true;
}
// Modular exponentiation: (base^exp) % mod
function powerMod(base, exp, mod) {
let result = 1n;
base = base % mod;
while (exp > 0n) {
if (exp % 2n === 1n) result = (result * base) % mod;
exp >>= 1n;
base = (base * base) % mod;
}
return result;
}
// Generate random BigInt in range [min, max] (inclusive)
function generateRandomBigInt(min, max) {
if (max < min) throw new Error("Invalid range");
const range = max - min + 1n;
// If range is small enough, use Math.random
if (range <= BigInt(Number.MAX_SAFE_INTEGER)) {
return min + BigInt(Math.floor(Math.random() * Number(range)));
}
// For large ranges, generate a random number with appropriate digit length
const maxStr = max.toString();
const len = maxStr.length;
let randomStr;
do {
// Generate a number with one fewer digit than max
randomStr = '';
for (let i = 0; i < len - 1; i++) {
randomStr += Math.floor(Math.random() * 10).toString();
}
// Remove leading zeros and ensure it's not empty
randomStr = randomStr.replace(/^0+/, '');
if (randomStr === '') randomStr = '0';
} while (BigInt(randomStr) > max);
const result = BigInt(randomStr);
return result >= min ? result : min;
}
// Miller-Rabin primality test for BigInt
function isProbablePrime(n, k = 15) {
if (n === 2n || n === 3n) return true;
if (n < 2n || n % 2n === 0n) return false;
// Write n-1 as d*2^s
let d = n - 1n;
let s = 0;
while (d % 2n === 0n) {
d /= 2n;
s++;
}
// Witness loop
for (let i = 0; i < k; i++) {
// Generate random BigInt a in range [2, n-2]
const a = generateRandomBigInt(2n, n - 2n);
let x = powerMod(a, d, n);
if (x === 1n || x === n - 1n) continue;
let composite = true;
for (let r = 0; r < s - 1; r++) {
x = (x * x) % n;
if (x === n - 1n) {
composite = false;
break;
}
}
if (composite) return false;
}
return true;
}
// Create a repunit: digits=3 -> 111n
function repunit(digits) {
return (10n ** BigInt(digits) - 1n) / 9n;
}
// Test repunit primality
function testRepunit(digits) {
const r = repunit(digits);
if (isProbablePrime(r, 15)) {
console.log(`R(${digits}) is probably prime.`);
} else {
console.log(`R(${digits}) is not prime.`);
}
}
// Main execution
console.log("First 19 circular primes:");
let p = 2;
let count = 0;
while (count < 19) {
if (isCircularPrime(p)) {
if (count > 0) process.stdout.write(", ");
process.stdout.write(p.toString());
count++;
}
p++;
}
console.log();
console.log("Next 4 circular primes:");
let digits = 1;
let repunitVal = 1n;
while (repunitVal < BigInt(p)) {
digits++;
repunitVal = repunit(digits);
}
count = 0;
while (count < 4) {
if (isProbablePrime(repunitVal, 15)) {
if (count > 0) process.stdout.write(", ");
process.stdout.write(`R(${digits})`);
count++;
}
digits++;
repunitVal = repunitVal * 10n + 1n;
}
console.log();
testRepunit(5003);
testRepunit(9887);
testRepunit(15073);
testRepunit(25031);

View file

@ -0,0 +1,19 @@
pm: { /print matrix
fw: -(3 + _log10e * 1e-12 + |/`ln x)
`0: (,/fw$$)'(0N;y) # x}
pr: {$[x < 5; |/ x = 2 3; &/ ~0=(`pri (`i$ 1 + %x))!' x]}
log10e: 1%`ln 10
len: {1+_1e-12+log10e*`ln x}
rot: {10/ {(1_x), *x} (10\x)}
rots: {(-1 + len x) rot\ x}
circ: {r: rots x; $[&/~(*r) > 1_r; &/pr' r; 0]}
gen: {[n] {{y+10*x}/x}' (1 3 7 9)@+!n#4}
cand: ,/gen' 2+!5
ps: 2, 3, 5, 7, cand@&circ' cand
`0: "The circular primes are:"
pm[ps; 10]

View file

@ -0,0 +1,74 @@
local int = require "int"
local fmt = require "fmt"
require "bignum"
local circs = {}
local function is_circular(n)
local nn = n
local pow = 1 -- will eventually contain 10 ^ d where d is number of digits in n
while nn > 0 do
pow *= 10
nn //= 10
end
nn = n
while true do
nn *= 10
local f = nn // pow -- first digit
nn += f * (1 - pow)
if nn in circs then return false end
if nn == n then break end
if !int.isprime(nn) then return false end
end
return true
end
print("The first 19 circular primes are:")
local digits = {1, 3, 7, 9}
local q = {1, 2, 3, 5, 7, 9} -- queue the numbers to be examined
local fq = {1, 2, 3, 5, 7, 9} -- also queue the corresponding first digits
local count = 0
while true do
local f = q[1] -- peek first element
local fd = fq[1] -- peek first digit
if int.isprime(f) and is_circular(f) then
circs:insert(f)
count += 1
if count == 19 then break end
end
q:remove(1) -- pop first element
fq:remove(1) -- ditto for first digit queue
if f != 2 and f != 5 then -- if digits > 1 can't contain a 2 or 5
-- add numbers with one more digit to queue
-- only numbers whose last digit >= first digit need be added
for digits as d do
if d >= fd then
q:insert(f * 10 + d)
fq:insert(fd)
end
end
end
end
fmt.lprint(circs)
print("\nThe next 4 circular primes, in repunit format, are:")
count = 0
mpz.init()
local rus = {}
local primes = int.primes(10_000)
local repunit
for i = 4, #primes do
local p = primes[i]
repunit = bigint.new(string.rep("1", p))
if mpz.isprobableprime(repunit) then
rus:insert($"R({p})")
count += 1
if count == 4 then break end
end
end
fmt.lprint(rus)
print("\nThe following repunits are probably circular primes:")
for {5003, 9887, 15073, 25031, 35317, 49081} as i do
repunit = bigint.new(string.rep("1", i))
fmt.print("R(%-5d) : %s", i, mpz.isprobableprime(repunit))
end

View file

@ -1,24 +1,27 @@
-- 23 Aug 2025
-- 25 Apr 2026
include Setting
say 'CIRCULAR PRIMES'
say version
say
call First19
call Timer 'r'
call Next3
call HigherReps
call Timer 'r'
call Rep1031
call Timer 'r'
exit
First19:
procedure expose Memo. prim.
call Time('r')
procedure expose Memo. Prim.
numeric digits 10
say 'First 19 circular primes:'
p = Primes(200000)
do i = 1 to p
a = prim.i
if Verify(a,'024568','m') > 0 then
iterate i
a = Prim.i
if a>10 then
if Verify(a,'024568','m') > 0 then
iterate i
b = a; l = Length(b)
do l-1
b = Right(b,l-1)||Left(b,1)
@ -30,14 +33,11 @@ do i = 1 to p
call Charout ,a' '
end
say
say Format(Time('e'),,3) 'seconds'
say
return
Next3:
procedure expose Memo.
call Time('r')
numeric digits 320
numeric digits 1000
say 'Next 3 circular primes:'
do i = 7 to 320
r = Repunit(i)
@ -45,21 +45,18 @@ do i = 7 to 320
call Charout ,'R('i') '
end
say
say Format(Time('e'),,3) 'seconds'
say
return
HigherReps:
Rep1031:
procedure expose Memo.
call Time('r')
numeric digits 1040
numeric digits 10000
say 'Primality of R(1031):'
if Prime(Repunit(1031)) then
say 'R(1031) is probable prime'
say 'R(1031) is probably prime'
else
say 'R(1031) is composite'
say Format(Time('e'),,3) 'seconds'
say
return
-- Primes Prime Repunit Timer
include Math

View file

@ -0,0 +1,4 @@
# Find first 19 circular primes
Rots ← ⇌⋕≡⌟↻⇡⊸⧻°⋕
IsCirc ← ⨬(⋅0|/↧≡(=1⧻°/×))⊸(=⊙/↧)⟜Rots
⍜now(▽⊸≡IsCirc+1⊚=⊣⊸°/×+1⇡1e6)

View file

@ -0,0 +1,13 @@
Prime ← =1 ⧻ °/×
Len ← +1 ⌊+1e-12 °ₑ₁₀
Rot ← ⌝⊥10 ↻1 ⊥10
AllRot ← ⍥(⊸Rot) Len ⟜∘
FirstLEq ← /↧ ≥ ⊃⊢(↘1)
Circ ← /↧ ⊂ ⊃(≡Prime) FirstLEq AllRot
Gen ← ≡/(+×10) ♭₂ ≡(˜⊏[1 3 7 9]) ⇡˜▽4
Cand ← /◇⊂ ≡(□Gen) ⇡₂5
Ps ← ⊂ [2 3 5 7] ⊏(⊚≡Circ Cand) Cand
⬚NaN ↯[∞ 10] Ps

View file

@ -1,6 +0,0 @@
# Find first 19 circular primes
IsP ← =1⧻°/×
Rots ← ≡(⋕↻)+1⊙¤⇡⧻.°⋕
Circ ← ⨬(⋅0|/↧≡IsP)⊸(=⊙/↧)⟜Rots
▽⊸≡Circ▽⊸≡IsP+1⇡1e6

View file

@ -0,0 +1,45 @@
link fastprime
procedure main(A)
limit := \A[1] | 19
write("First ",limit," circular primes are:")
every writes(" ",(x := circular(genprimes())\limit)|"\n")
limit := 3 # Patience wore out when limit = 4...
writes("Next ",limit," are:")
y := repunit(*x)
cnt := 0
while cnt < limit do {
if (circular(is_prime(y)),cnt +:= 1) then writes(" R(",*y,")")
y := 10*y+1
}
write()
limit := 1 # Patience wore out when limit > 1...
every x := (5003|9887|15073|25031|35317|49081)\limit do {
writes("R(",x,") ")
y := repunit(x)
write("is ",if is_prime(y) then "prime" else "not prime")
}
end
procedure repunit(x)
every (y := 0, 1 to x, y := 10*y+1)
return y
end
procedure circular(n)
static seen
initial seen := set()
if member(seen,n) then fail
m := c := n
x := *n
every i := 2 to x do {
if (d := c%10) = 0 then fail
c := (d*10^(x-1))+(c/10)
if not is_prime(numeric(c)) then fail
if member(seen,m >:= c) then fail
}
insert(seen,m)
return n
end