Data update
This commit is contained in:
parent
4bb20c9b71
commit
cbaf4c4b64
12390 changed files with 318560 additions and 27248 deletions
167
Task/Circular-primes/JavaScript/circular-primes.js
Normal file
167
Task/Circular-primes/JavaScript/circular-primes.js
Normal 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);
|
||||
Loading…
Add table
Add a link
Reference in a new issue