Преглед на файлове

add methods for validating special types of primes

balanced primes,
semiprimes,
distinct semiprimes,
chen primes,
circular primes
Richard Köhl преди 3 години
родител
ревизия
b273df0ba2
променени са 2 файла, в които са добавени 354 реда и са изтрити 0 реда
  1. 297 0
      src/prime.class.test.ts
  2. 57 0
      src/prime.class.ts

+ 297 - 0
src/prime.class.test.ts

@@ -260,4 +260,301 @@ Deno.test("Prime class", async (t) => {
       });
     });
   });
+
+  await t.step("static method isBalanced()", async (t) => {
+    await t.step("validate balanced prime numbers", () => {
+      [
+        5,
+        53,
+        157,
+        173,
+        211,
+        257,
+        263,
+        373,
+        563,
+        593,
+        607,
+        653,
+        733,
+        947,
+        977,
+        1103,
+        1123,
+        1187,
+        1223,
+        1367,
+        1511,
+        1747,
+        1753,
+        1907,
+        2287,
+        2417,
+        2677,
+        2903,
+      ].forEach((number) => {
+        assert(Prime.isBalanced(number), `${number} is a balanced prime`);
+      });
+    });
+
+    await t.step("validate non-balanced-prime numbers", () => {
+      [2, 3, 4, 10, 13, 17, 50, 51, 51, 54, 55, 56, 57].forEach((number) => {
+        assert(!Prime.isBalanced(number), `${number} is NOT a balanced prime`);
+      });
+    });
+  });
+
+  await t.step("static method isSemiprime()", async (t) => {
+    await t.step("validate semiprime numbers", () => {
+      [
+        4,
+        6,
+        9,
+        10,
+        14,
+        15,
+        21,
+        22,
+        25,
+        26,
+        33,
+        34,
+        35,
+        38,
+        39,
+        46,
+        49,
+        51,
+        55,
+        57,
+        58,
+        62,
+        65,
+        69,
+        74,
+        77,
+        82,
+        85,
+        86,
+        87,
+        91,
+        93,
+        94,
+        95,
+      ].forEach((number) => {
+        assert(Prime.isSemiprime(number), `${number} is a semiprime`);
+      });
+    });
+
+    await t.step("validate non-semiprime numbers", () => {
+      [2, 3, 5, 13, 17, 50, 54, 56, 59].forEach((number) => {
+        assert(!Prime.isSemiprime(number), `${number} is NOT a semiprime`);
+      });
+    });
+  });
+
+  await t.step("static method isDistinctSemiprime()", async (t) => {
+    await t.step("validate distinct semiprime numbers", () => {
+      [
+        6,
+        10,
+        14,
+        15,
+        21,
+        22,
+        26,
+        33,
+        34,
+        35,
+        38,
+        39,
+        46,
+        51,
+        55,
+        57,
+        58,
+        62,
+        65,
+        69,
+        74,
+        77,
+        82,
+        85,
+        86,
+        87,
+        91,
+        93,
+        94,
+        95,
+      ].forEach((number) => {
+        assert(
+          Prime.isDistinctSemiprime(number),
+          `${number} is a distinct semiprime`,
+        );
+      });
+    });
+
+    await t.step("validate non-distinct-semiprime numbers", () => {
+      [4, 9, 25, 49, 1, 2, 3, 100, 150].forEach((number) => {
+        assert(
+          !Prime.isDistinctSemiprime(number),
+          `${number} is NOT a distinct semiprime`,
+        );
+      });
+    });
+  });
+
+  await t.step("static method isChenPrime()", async (t) => {
+    await t.step("validate chen prime numbers", () => {
+      [
+        2,
+        3,
+        5,
+        7,
+        11,
+        13,
+        17,
+        19,
+        23,
+        29,
+        31,
+        37,
+        41,
+        47,
+        53,
+        59,
+        67,
+        71,
+        83,
+        89,
+        101,
+        107,
+        109,
+        113,
+        127,
+        131,
+        137,
+        139,
+        149,
+        157,
+        167,
+        179,
+        181,
+        191,
+        197,
+        199,
+        211,
+        227,
+        233,
+        239,
+        251,
+        257,
+        263,
+        269,
+        281,
+        293,
+        307,
+        311,
+        317,
+        337,
+        347,
+        353,
+        359,
+        379,
+        389,
+        401,
+        409,
+      ].forEach((number) => {
+        assert(
+          Prime.isChenPrime(number),
+          `${number} is a chen prime`,
+        );
+      });
+    });
+
+    await t.step("validate non-chen-prime numbers", () => {
+      [1, 4, 8, 9, 10, 14, 15, 16, 18, 308, 403].forEach((number) => {
+        assert(
+          !Prime.isChenPrime(number),
+          `${number} is NOT a chen prime`,
+        );
+      });
+    });
+  });
+
+  await t.step("static method isCircular()", async (t) => {
+    await t.step("validate circular prime numbers", () => {
+      [
+        2,
+        3,
+        5,
+        7,
+        11,
+        13,
+        17,
+        31,
+        37,
+        71,
+        73,
+        79,
+        97,
+        113,
+        131,
+        197,
+        199,
+        311,
+        337,
+        373,
+        719,
+        733,
+        919,
+        971,
+        991,
+        1193,
+        1931,
+        3119,
+        3779,
+        7793,
+        7937,
+        9311,
+        9377,
+        11939,
+        19391,
+        19937,
+        37199,
+        39119,
+        71993,
+        91193,
+        93719,
+        93911,
+        99371,
+        193939,
+        199933,
+        319993,
+        331999,
+        391939,
+        393919,
+        919393,
+        933199,
+        939193,
+        939391,
+        993319,
+        999331,
+      ].forEach((number) => {
+        assert(
+          Prime.isCircular(number),
+          `${number} is a circular prime`,
+        );
+      });
+    });
+
+    await t.step("validate non-circular-prime numbers", () => {
+      [1, 4, 8, 15.7, 133, 312, 313].forEach((number) => {
+        assert(
+          !Prime.isCircular(number),
+          `${number} is NOT a circular prime`,
+        );
+      });
+    });
+  });
 });

+ 57 - 0
src/prime.class.ts

@@ -132,6 +132,19 @@ export class Prime {
     return true;
   }
 
+  public static isBalanced(number: number): boolean {
+    if (number <= 2 || !Prime.isPrime(number)) {
+      return false;
+    }
+
+    const prev = Prime.values[Prime.values.indexOf(number) - 1];
+    const next = Prime.lastKnown() === number
+      ? Prime.findNextUnknown()
+      : Prime.values[Prime.values.indexOf(number) + 1];
+
+    return number === (prev + next) / 2;
+  }
+
   public static factors(number: number): number[] {
     if (Prime.isPrime(number)) {
       return [number];
@@ -154,6 +167,50 @@ export class Prime {
     return factors;
   }
 
+  public static isSemiprime(number: number): boolean {
+    return Prime.factors(number).length === 2;
+  }
+
+  public static isDistinctSemiprime(number: number): boolean {
+    if (!Prime.isSemiprime(number)) {
+      return false;
+    }
+
+    const [a, b] = Prime.factors(number);
+    return a !== b;
+  }
+
+  public static isChenPrime(number: number): boolean {
+    if (!Prime.isPrime(number)) {
+      return false;
+    }
+
+    const next = number + 2;
+    return Prime.isPrime(next) || Prime.isSemiprime(next);
+  }
+
+  public static isCircular(number: number): boolean {
+    if (!Prime.isPrime(number)) {
+      return false;
+    }
+
+    const digits = number.toString().split("");
+    if (digits.length > 0) {
+      for (let i = 0; i < digits.length - 1; i += 1) {
+        digits.push(digits.shift() ?? "x");
+        const c = Number(digits.join(""));
+
+        if (!Prime.isPrime(c)) {
+          return false;
+        }
+      }
+
+      return true;
+    }
+
+    return false;
+  }
+
   public static list(to: number): number[] {
     if (to < 2) {
       return [];