Procházet zdrojové kódy

add list method, fix logic error

Richard Köhl před 3 roky
rodič
revize
5e081d6ff7
2 změnil soubory, kde provedl 47 přidání a 8 odebrání
  1. 11 0
      src/prime.class.test.ts
  2. 36 8
      src/prime.class.ts

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

@@ -189,4 +189,15 @@ Deno.test("Prime class", async (t) => {
       });
     });
   });
+
+  await t.step("static method list()", async (t) => {
+    await t.step("returns the list of prime numbers", () => {
+      assertEquals(Prime.list(10), [
+        2,
+        3,
+        5,
+        7,
+      ]);
+    });
+  });
 });

+ 36 - 8
src/prime.class.ts

@@ -5,7 +5,15 @@ export class Prime {
     return Prime.values.slice(-1)[0];
   }
 
-  private static searchNextKnownPrime(number: number, from = 0, to: number = Prime.values.length): number {
+  private static searchNextKnownPrime(
+    number: number,
+    from = 0,
+    to: number = Prime.values.length,
+  ): number {
+    if (0 > number || number >= Prime.lastKnown()) {
+      throw new Error("we are wandering in unknown realms...");
+    }
+
     // this is a binary search
     // basically we are splitting the list into two halves and
     // then discard the half that does not contain the input number
@@ -17,12 +25,14 @@ export class Prime {
     if (length > 1) {
       const middle = from + Math.floor(length / 2);
 
-      return Prime.values[middle] < number
-        ? Prime.searchNextKnownPrime(number, from, middle + 1)
-        : Prime.searchNextKnownPrime(number, middle, to)
+      return Prime.values[middle] > number
+        ? Prime.searchNextKnownPrime(number, from, middle)
+        : Prime.searchNextKnownPrime(number, middle + 1, to);
     }
 
-    return Prime.values[from] > number ? Prime.values[from] : 0;
+    return Prime.values[from] > number
+      ? Prime.values[from]
+      : Prime.values[from + 1];
   }
 
   private static findNextUnknown(): number {
@@ -50,7 +60,11 @@ export class Prime {
 
     // input is larger than last known prime number in our list
     // so we need to brute force the next one
-    return Prime.findNextUnknown();
+    let next: number;
+    do {
+      next = Prime.findNextUnknown();
+    } while (next <= number);
+    return next;
   }
 
   public static isPrime(number: number): boolean {
@@ -132,12 +146,26 @@ export class Prime {
       if (rest % prime === 0) {
         rest = rest / prime;
         factors.push(prime);
-      }
-      else {
+      } else {
         prime = Prime.next(prime);
       }
     } while (1 < rest && prime <= rest);
 
     return factors;
   }
+
+  public static list(to: number): number[] {
+    if (to < 2) {
+      return [];
+    }
+
+    // find the next bigger prime number
+    const outOfLimit = Prime.next(to);
+
+    // deliver the list of known primes up to (but excluding) retrieved prime
+    return Prime.values.slice(
+      0,
+      Prime.values.indexOf(outOfLimit),
+    );
+  }
 }