Date: Wed, 23 Apr 2025 10:54:33 +0900
Subject: [PATCH 06/14] Spelling
---
src/main/java/com/autonomouslogic/primes/PrimorialOrder.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/com/autonomouslogic/primes/PrimorialOrder.java b/src/main/java/com/autonomouslogic/primes/PrimorialOrder.java
index b39f208..d022ec7 100644
--- a/src/main/java/com/autonomouslogic/primes/PrimorialOrder.java
+++ b/src/main/java/com/autonomouslogic/primes/PrimorialOrder.java
@@ -8,7 +8,7 @@
/**
*
- * An order of priomorial.
+ * An order of primorial.
* Each order n is the primorial p_n# = c#.
* Each order consists of the order n, the last prime c, the product k,
* and all the coprime offsets iOffsets from k.
From 8ca6ac456c72144404f561aa04ac2a96d93c996d Mon Sep 17 00:00:00 2001
From: Kenneth Jorgensen
Date: Wed, 23 Apr 2025 23:54:25 +0900
Subject: [PATCH 07/14] Renamed PrimorialOrder to Primorial
---
.../{PrimorialOrder.java => Primorial.java} | 10 ++---
...orialOrderTest.java => PrimorialTest.java} | 43 +++++++++----------
2 files changed, 26 insertions(+), 27 deletions(-)
rename src/main/java/com/autonomouslogic/primes/{PrimorialOrder.java => Primorial.java} (95%)
rename src/test/java/com/autonomouslogic/primes/{PrimorialOrderTest.java => PrimorialTest.java} (59%)
diff --git a/src/main/java/com/autonomouslogic/primes/PrimorialOrder.java b/src/main/java/com/autonomouslogic/primes/Primorial.java
similarity index 95%
rename from src/main/java/com/autonomouslogic/primes/PrimorialOrder.java
rename to src/main/java/com/autonomouslogic/primes/Primorial.java
index d022ec7..0e40c78 100644
--- a/src/main/java/com/autonomouslogic/primes/PrimorialOrder.java
+++ b/src/main/java/com/autonomouslogic/primes/Primorial.java
@@ -37,7 +37,7 @@
*/
@Value
@AllArgsConstructor
-public class PrimorialOrder {
+public class Primorial {
int n;
int c;
long k;
@@ -72,7 +72,7 @@ public static long primorialOfOrder(int n) {
* @param n
* @return
*/
- public static PrimorialOrder ofOrder(int n) {
+ public static Primorial ofOrder(int n) {
var primes = Arrays.stream(PrimeList.PRIMES).limit(n).toArray();
long product = 1;
for (int prime : primes) {
@@ -91,7 +91,7 @@ public static PrimorialOrder ofOrder(int n) {
.map(num -> num - finalProduct)
.toArray();
var c = primes.length == 0 ? 1 : primes[primes.length - 1];
- return new PrimorialOrder(n, c, product, offsets);
+ return new Primorial(n, c, product, offsets);
}
/**
@@ -112,7 +112,7 @@ public static LongStream allPossiblePrimes(long from) {
throw new IllegalArgumentException("from must be at least 2");
}
return IntStream.rangeClosed(1, 8)
- .mapToObj(PrimorialOrder::ofOrder)
+ .mapToObj(Primorial::ofOrder)
.filter(o -> primorialOfOrder(o.getN() + 1) >= from)
.flatMapToLong(order -> {
if (order.getK() == 8) {
@@ -129,7 +129,7 @@ public static LongStream allPossiblePrimes(long from) {
public static void main(String[] args) {
for (int i = 0; i <= 9; i++) {
- var order = PrimorialOrder.ofOrder(i);
+ var order = Primorial.ofOrder(i);
var offsetsLen = order.getIOffsets().length;
var space = 100.0 * offsetsLen / order.getK();
System.out.printf(
diff --git a/src/test/java/com/autonomouslogic/primes/PrimorialOrderTest.java b/src/test/java/com/autonomouslogic/primes/PrimorialTest.java
similarity index 59%
rename from src/test/java/com/autonomouslogic/primes/PrimorialOrderTest.java
rename to src/test/java/com/autonomouslogic/primes/PrimorialTest.java
index 49386d6..239c587 100644
--- a/src/test/java/com/autonomouslogic/primes/PrimorialOrderTest.java
+++ b/src/test/java/com/autonomouslogic/primes/PrimorialTest.java
@@ -5,25 +5,24 @@
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import javax.swing.*;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
-public class PrimorialOrderTest {
+public class PrimorialTest {
@ParameterizedTest
@MethodSource("orderTests")
- void shouldCreateOrders(int order, PrimorialOrder expected) {
- assertEquals(expected, PrimorialOrder.ofOrder(order));
+ void shouldCreateOrders(int order, Primorial expected) {
+ assertEquals(expected, Primorial.ofOrder(order));
}
public static Stream orderTests() {
return Stream.of(
- Arguments.of(0, new PrimorialOrder(0, 1, 1, new long[] {0})),
- Arguments.of(1, new PrimorialOrder(1, 2, 2, new long[] {1})),
- Arguments.of(2, new PrimorialOrder(2, 3, 6, new long[] {1, 5})),
- Arguments.of(3, new PrimorialOrder(3, 5, 30, new long[] {1, 7, 11, 13, 17, 19, 23, 29})));
+ Arguments.of(0, new Primorial(0, 1, 1, new long[] {0})),
+ Arguments.of(1, new Primorial(1, 2, 2, new long[] {1})),
+ Arguments.of(2, new Primorial(2, 3, 6, new long[] {1, 5})),
+ Arguments.of(3, new Primorial(3, 5, 30, new long[] {1, 7, 11, 13, 17, 19, 23, 29})));
}
@ParameterizedTest
@@ -31,7 +30,7 @@ public static Stream orderTests() {
void shouldReturnPossiblePrimes(int order, List expected) {
assertEquals(
expected.toString(),
- PrimorialOrder.ofOrder(order)
+ Primorial.ofOrder(order)
.possiblePrimes()
.limit(expected.size())
.boxed()
@@ -50,13 +49,13 @@ public static Stream possiblePrimesTests() {
@Test
void shouldReturnAllPossiblePrimes() {
var expected = Stream.of(
- PrimorialOrder.ofOrder(1).possiblePrimes().takeWhile(n -> n < 6),
- PrimorialOrder.ofOrder(2).possiblePrimes().takeWhile(n -> n < 30),
- PrimorialOrder.ofOrder(3).possiblePrimes().takeWhile(n -> n < 200))
+ Primorial.ofOrder(1).possiblePrimes().takeWhile(n -> n < 6),
+ Primorial.ofOrder(2).possiblePrimes().takeWhile(n -> n < 30),
+ Primorial.ofOrder(3).possiblePrimes().takeWhile(n -> n < 200))
.flatMapToLong(s -> s)
.mapToObj(String::valueOf)
.collect(Collectors.joining("\n"));
- var actual = PrimorialOrder.allPossiblePrimes()
+ var actual = Primorial.allPossiblePrimes()
.takeWhile(n -> n <= 200)
.mapToObj(String::valueOf)
.collect(Collectors.joining("\n"));
@@ -66,15 +65,15 @@ void shouldReturnAllPossiblePrimes() {
@Test
void shouldReturnAllPossiblePrimesFromOffset() {
var expected = Stream.of(
- PrimorialOrder.ofOrder(2)
+ Primorial.ofOrder(2)
.possiblePrimes()
.filter(n -> n >= 15)
.takeWhile(n -> n < 30),
- PrimorialOrder.ofOrder(3).possiblePrimes().takeWhile(n -> n < 200))
+ Primorial.ofOrder(3).possiblePrimes().takeWhile(n -> n < 200))
.flatMapToLong(s -> s)
.mapToObj(String::valueOf)
.collect(Collectors.joining("\n"));
- var actual = PrimorialOrder.allPossiblePrimes(15)
+ var actual = Primorial.allPossiblePrimes(15)
.takeWhile(n -> n <= 200)
.mapToObj(String::valueOf)
.collect(Collectors.joining("\n"));
@@ -83,11 +82,11 @@ void shouldReturnAllPossiblePrimesFromOffset() {
@Test
void shouldCalculatePrimorialOfOrder() {
- assertEquals(1, PrimorialOrder.primorialOfOrder(0));
- assertEquals(2, PrimorialOrder.primorialOfOrder(1));
- assertEquals(6, PrimorialOrder.primorialOfOrder(2));
- assertEquals(30, PrimorialOrder.primorialOfOrder(3));
- assertEquals(210, PrimorialOrder.primorialOfOrder(4));
- assertEquals(2310, PrimorialOrder.primorialOfOrder(5));
+ assertEquals(1, Primorial.primorialOfOrder(0));
+ assertEquals(2, Primorial.primorialOfOrder(1));
+ assertEquals(6, Primorial.primorialOfOrder(2));
+ assertEquals(30, Primorial.primorialOfOrder(3));
+ assertEquals(210, Primorial.primorialOfOrder(4));
+ assertEquals(2310, Primorial.primorialOfOrder(5));
}
}
From 02da8df394e7df6ee1aea514993e02b832ca83a6 Mon Sep 17 00:00:00 2001
From: Kenneth Jorgensen
Date: Thu, 24 Apr 2025 00:43:15 +0900
Subject: [PATCH 08/14] More refactor
---
.../com/autonomouslogic/primes/Primorial.java | 140 ---------------
.../autonomouslogic/primes/Primorials.java | 164 ++++++++++++++++++
...PrimorialTest.java => PrimorialsTest.java} | 42 ++---
3 files changed, 185 insertions(+), 161 deletions(-)
delete mode 100644 src/main/java/com/autonomouslogic/primes/Primorial.java
create mode 100644 src/main/java/com/autonomouslogic/primes/Primorials.java
rename src/test/java/com/autonomouslogic/primes/{PrimorialTest.java => PrimorialsTest.java} (60%)
diff --git a/src/main/java/com/autonomouslogic/primes/Primorial.java b/src/main/java/com/autonomouslogic/primes/Primorial.java
deleted file mode 100644
index 0e40c78..0000000
--- a/src/main/java/com/autonomouslogic/primes/Primorial.java
+++ /dev/null
@@ -1,140 +0,0 @@
-package com.autonomouslogic.primes;
-
-import java.util.Arrays;
-import java.util.stream.IntStream;
-import java.util.stream.LongStream;
-import lombok.AllArgsConstructor;
-import lombok.Value;
-
-/**
- *
- * An order of primorial.
- * Each order n is the primorial p_n# = c#.
- * Each order consists of the order n, the last prime c, the product k,
- * and all the coprime offsets iOffsets from k.
- *
- *
- *
- * See Primorial
- * and Primality test (Simple methods).
- *
- *
- *
- * The main function in this class summarises the orders with the output:
- *
- * Order 0, c=1, k=1, 1 offsets, 100.0% space
- * Order 1, c=2, k=2, 1 offsets, 50.0% space
- * Order 2, c=3, k=6, 2 offsets, 33.3% space
- * Order 3, c=5, k=30, 8 offsets, 26.7% space
- * Order 4, c=7, k=210, 48 offsets, 22.9% space
- * Order 5, c=11, k=2310, 480 offsets, 20.8% space
- * Order 6, c=13, k=30030, 5760 offsets, 19.2% space
- * Order 7, c=17, k=510510, 92160 offsets, 18.1% space
- * Order 8, c=19, k=9699690, 1658880 offsets, 17.1% space
- * Order 9, c=23, k=223092870, 36495360 offsets, 16.4% space
- *
- *
- */
-@Value
-@AllArgsConstructor
-public class Primorial {
- int n;
- int c;
- long k;
- long[] iOffsets;
-
- /**
- * Returns all possible primes associated with this order.
- * Each number returned is in the form n * k + i for each possible integer n and each i.
- * For instance, order 1 will return all odd numbers.
- * Order 2 will first return 3 and 5, then 7 and 9, and so on.
- * Order 3 will first return 31, 37, 41, 43, 47, 49, 53, 59, then 61, 67, 71, 73, 77, 79, 83, 89, and so on.
- * Each order will return a higher start number, but the stream will contain less and less numbers.
- * This can be used when searching for prime numbers.
- * @return
- */
- public LongStream possiblePrimes() {
- return LongStream.iterate(1, i -> i + 1)
- .flatMap(k -> Arrays.stream(iOffsets).map(i -> k * this.k + i));
- }
-
- /**
- * Returns the primorial p_n#
- * @param n
- * @return
- */
- public static long primorialOfOrder(int n) {
- return Arrays.stream(PrimeList.PRIMES).limit(n).asLongStream().reduce(1, (left, right) -> left * right);
- }
-
- /**
- * Returns a specific primorial order.
- * @param n
- * @return
- */
- public static Primorial ofOrder(int n) {
- var primes = Arrays.stream(PrimeList.PRIMES).limit(n).toArray();
- long product = 1;
- for (int prime : primes) {
- product *= prime;
- }
- final var finalProduct = product;
- var offsets = LongStream.range(product, 2 * product)
- .filter(num -> {
- for (int prime : primes) {
- if ((num % prime) == 0) {
- return false;
- }
- }
- return true;
- })
- .map(num -> num - finalProduct)
- .toArray();
- var c = primes.length == 0 ? 1 : primes[primes.length - 1];
- return new Primorial(n, c, product, offsets);
- }
-
- /**
- * @see #allPossiblePrimes(long)
- * @return
- */
- public static LongStream allPossiblePrimes() {
- return allPossiblePrimes(2);
- }
-
- /**
- * Returns all the possible primes from each primorial order in sequence, starting from the supplied number
- * @param from the number to start from, must be at least 2
- * @return
- */
- public static LongStream allPossiblePrimes(long from) {
- if (from < 2) {
- throw new IllegalArgumentException("from must be at least 2");
- }
- return IntStream.rangeClosed(1, 8)
- .mapToObj(Primorial::ofOrder)
- .filter(o -> primorialOfOrder(o.getN() + 1) >= from)
- .flatMapToLong(order -> {
- if (order.getK() == 8) {
- return order.possiblePrimes();
- }
- var nextK = primorialOfOrder(order.getN() + 1);
- var stream = order.possiblePrimes().takeWhile(num -> num < nextK);
- if (order.getK() < from) {
- stream = stream.filter(n -> n >= from);
- }
- return stream;
- });
- }
-
- public static void main(String[] args) {
- for (int i = 0; i <= 9; i++) {
- var order = Primorial.ofOrder(i);
- var offsetsLen = order.getIOffsets().length;
- var space = 100.0 * offsetsLen / order.getK();
- System.out.printf(
- "Order %d, c=%d, k=%d, %d offsets, %.1f%% space%n",
- order.getN(), order.getC(), order.getK(), offsetsLen, space);
- }
- }
-}
diff --git a/src/main/java/com/autonomouslogic/primes/Primorials.java b/src/main/java/com/autonomouslogic/primes/Primorials.java
new file mode 100644
index 0000000..d043b0a
--- /dev/null
+++ b/src/main/java/com/autonomouslogic/primes/Primorials.java
@@ -0,0 +1,164 @@
+package com.autonomouslogic.primes;
+
+import java.util.Arrays;
+import java.util.stream.IntStream;
+import java.util.stream.LongStream;
+import lombok.AccessLevel;
+import lombok.AllArgsConstructor;
+import lombok.NoArgsConstructor;
+import lombok.Value;
+
+/**
+ *
+ * Functions for working with primorials.
+ * Each order n represents the primorial p_n# = c#, which is the sum of all primes between 2 and c.
+ * Each order consists of the order n, the last prime c, the product,
+ * and all the coprime offsets from product.
+ *
+ *
+ *
+ * See Primorial
+ * and Primality test (Simple methods).
+ *
+ *
+ *
+ * The main function in this class summarises the orders with the output:
+ *
+ * Order 0: c=1, k=1, 1 offsets, 100.0% space
+ * Order 1: c=2, k=2, 1 offsets, 50.0% space
+ * Order 2: c=3, k=6, 2 offsets, 33.3% space
+ * Order 3: c=5, k=30, 8 offsets, 26.7% space
+ * Order 4: c=7, k=210, 48 offsets, 22.9% space
+ * Order 5: c=11, k=2310, 480 offsets, 20.8% space
+ * Order 6: c=13, k=30030, 5760 offsets, 19.2% space
+ * Order 7: c=17, k=510510, 92160 offsets, 18.1% space
+ * Order 8: c=19, k=9699690, 1658880 offsets, 17.1% space
+ * Order 9: c=23, k=223092870, 36495360 offsets, 16.4% space
+ *
+ *
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public class Primorials {
+ @Value
+ @AllArgsConstructor(access = AccessLevel.PROTECTED)
+ public static class Order {
+ /**
+ * The order of the primorial.
+ */
+ int n;
+
+ /**
+ * The last prime of the product.
+ */
+ int c;
+
+ /**
+ * The product of the primorial.
+ */
+ long product;
+
+ /**
+ * The coprime offsets which when added to multiples of the product are not divisible by any of the primes
+ * below c.
+ */
+ long[] coprimeOffsets;
+
+ /**
+ * Returns all possible primes associated with this primorial order.
+ * Each number returned is in the form product * k + i, where k is an incrementing
+ * positive integer and i is each possible coprime offset.
+ * For instance, order 1 will return all odd numbers.
+ * Order 2 will first return 3 and 5, then 7 and 9, and so on.
+ * Order 3 will first return 31, 37, 41, 43, 47, 49, 53, 59, then 61, 67, 71, 73, 77, 79, 83, 89, and so on.
+ * Each order will return a higher start number, but the stream will contain fewer and fewer numbers.
+ * This can be used when searching for prime numbers.
+ *
+ * @return
+ */
+ public LongStream possiblePrimes() {
+ return LongStream.iterate(1, i -> i + 1)
+ .flatMap(k -> Arrays.stream(coprimeOffsets).map(i -> k * this.product + i));
+ }
+ }
+
+ /**
+ * Returns the primorial p_n#
+ * @param n
+ * @return
+ */
+ public static long ofOrder(int n) {
+ return Arrays.stream(PrimeList.PRIMES).limit(n).asLongStream().reduce(1, (left, right) -> left * right);
+ }
+
+ /**
+ * Returns a primorial order with all the coprime offsets calculated.
+ * @param n
+ * @return
+ */
+ public static Primorials.Order ofOrderWithCoprimes(int n) {
+ var primes = Arrays.stream(PrimeList.PRIMES).limit(n).toArray();
+ long product = 1;
+ for (int prime : primes) {
+ product *= prime;
+ }
+ final var finalProduct = product;
+ var offsets = LongStream.range(product, 2 * product)
+ .filter(num -> {
+ for (int prime : primes) {
+ if ((num % prime) == 0) {
+ return false;
+ }
+ }
+ return true;
+ })
+ .map(num -> num - finalProduct)
+ .toArray();
+ var c = primes.length == 0 ? 1 : primes[primes.length - 1];
+ return new Primorials.Order(n, c, product, offsets);
+ }
+
+ /**
+ * @see #allPossiblePrimes(long)
+ * @return
+ */
+ public static LongStream allPossiblePrimes() {
+ return allPossiblePrimes(2);
+ }
+
+ /**
+ * Returns all the possible primes from each primorial order in sequence, starting from the supplied number.
+ * The sequence will gradually contain fewer and fewer numbers as the orders are able to advance.
+ * @param from the number to start from, must be at least 2
+ * @return
+ */
+ public static LongStream allPossiblePrimes(long from) {
+ if (from < 2) {
+ throw new IllegalArgumentException("from must be at least 2");
+ }
+ return IntStream.rangeClosed(1, 8)
+ .mapToObj(Primorials::ofOrderWithCoprimes)
+ .filter(o -> ofOrder(o.getN() + 1) >= from)
+ .flatMapToLong(order -> {
+ if (order.getProduct() == 8) {
+ return order.possiblePrimes();
+ }
+ var nextK = ofOrder(order.getN() + 1);
+ var stream = order.possiblePrimes().takeWhile(num -> num < nextK);
+ if (order.getProduct() < from) {
+ stream = stream.filter(n -> n >= from);
+ }
+ return stream;
+ });
+ }
+
+ public static void main(String[] args) {
+ for (int i = 0; i <= 9; i++) {
+ var order = Primorials.ofOrderWithCoprimes(i);
+ var offsetsLen = order.getCoprimeOffsets().length;
+ var space = 100.0 * offsetsLen / order.getProduct();
+ System.out.printf(
+ "Order %d, c=%d, k=%d, %d offsets, %.1f%% space%n",
+ order.getN(), order.getC(), order.getProduct(), offsetsLen, space);
+ }
+ }
+}
diff --git a/src/test/java/com/autonomouslogic/primes/PrimorialTest.java b/src/test/java/com/autonomouslogic/primes/PrimorialsTest.java
similarity index 60%
rename from src/test/java/com/autonomouslogic/primes/PrimorialTest.java
rename to src/test/java/com/autonomouslogic/primes/PrimorialsTest.java
index 239c587..e9347bd 100644
--- a/src/test/java/com/autonomouslogic/primes/PrimorialTest.java
+++ b/src/test/java/com/autonomouslogic/primes/PrimorialsTest.java
@@ -10,19 +10,19 @@
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
-public class PrimorialTest {
+public class PrimorialsTest {
@ParameterizedTest
@MethodSource("orderTests")
- void shouldCreateOrders(int order, Primorial expected) {
- assertEquals(expected, Primorial.ofOrder(order));
+ void shouldCreateOrders(int order, Primorials.Order expected) {
+ assertEquals(expected, Primorials.ofOrderWithCoprimes(order));
}
public static Stream orderTests() {
return Stream.of(
- Arguments.of(0, new Primorial(0, 1, 1, new long[] {0})),
- Arguments.of(1, new Primorial(1, 2, 2, new long[] {1})),
- Arguments.of(2, new Primorial(2, 3, 6, new long[] {1, 5})),
- Arguments.of(3, new Primorial(3, 5, 30, new long[] {1, 7, 11, 13, 17, 19, 23, 29})));
+ Arguments.of(0, new Primorials.Order(0, 1, 1, new long[] {0})),
+ Arguments.of(1, new Primorials.Order(1, 2, 2, new long[] {1})),
+ Arguments.of(2, new Primorials.Order(2, 3, 6, new long[] {1, 5})),
+ Arguments.of(3, new Primorials.Order(3, 5, 30, new long[] {1, 7, 11, 13, 17, 19, 23, 29})));
}
@ParameterizedTest
@@ -30,7 +30,7 @@ public static Stream orderTests() {
void shouldReturnPossiblePrimes(int order, List expected) {
assertEquals(
expected.toString(),
- Primorial.ofOrder(order)
+ Primorials.ofOrderWithCoprimes(order)
.possiblePrimes()
.limit(expected.size())
.boxed()
@@ -49,13 +49,13 @@ public static Stream possiblePrimesTests() {
@Test
void shouldReturnAllPossiblePrimes() {
var expected = Stream.of(
- Primorial.ofOrder(1).possiblePrimes().takeWhile(n -> n < 6),
- Primorial.ofOrder(2).possiblePrimes().takeWhile(n -> n < 30),
- Primorial.ofOrder(3).possiblePrimes().takeWhile(n -> n < 200))
+ Primorials.ofOrderWithCoprimes(1).possiblePrimes().takeWhile(n -> n < 6),
+ Primorials.ofOrderWithCoprimes(2).possiblePrimes().takeWhile(n -> n < 30),
+ Primorials.ofOrderWithCoprimes(3).possiblePrimes().takeWhile(n -> n < 200))
.flatMapToLong(s -> s)
.mapToObj(String::valueOf)
.collect(Collectors.joining("\n"));
- var actual = Primorial.allPossiblePrimes()
+ var actual = Primorials.allPossiblePrimes()
.takeWhile(n -> n <= 200)
.mapToObj(String::valueOf)
.collect(Collectors.joining("\n"));
@@ -65,15 +65,15 @@ void shouldReturnAllPossiblePrimes() {
@Test
void shouldReturnAllPossiblePrimesFromOffset() {
var expected = Stream.of(
- Primorial.ofOrder(2)
+ Primorials.ofOrderWithCoprimes(2)
.possiblePrimes()
.filter(n -> n >= 15)
.takeWhile(n -> n < 30),
- Primorial.ofOrder(3).possiblePrimes().takeWhile(n -> n < 200))
+ Primorials.ofOrderWithCoprimes(3).possiblePrimes().takeWhile(n -> n < 200))
.flatMapToLong(s -> s)
.mapToObj(String::valueOf)
.collect(Collectors.joining("\n"));
- var actual = Primorial.allPossiblePrimes(15)
+ var actual = Primorials.allPossiblePrimes(15)
.takeWhile(n -> n <= 200)
.mapToObj(String::valueOf)
.collect(Collectors.joining("\n"));
@@ -82,11 +82,11 @@ void shouldReturnAllPossiblePrimesFromOffset() {
@Test
void shouldCalculatePrimorialOfOrder() {
- assertEquals(1, Primorial.primorialOfOrder(0));
- assertEquals(2, Primorial.primorialOfOrder(1));
- assertEquals(6, Primorial.primorialOfOrder(2));
- assertEquals(30, Primorial.primorialOfOrder(3));
- assertEquals(210, Primorial.primorialOfOrder(4));
- assertEquals(2310, Primorial.primorialOfOrder(5));
+ assertEquals(1, Primorials.ofOrder(0));
+ assertEquals(2, Primorials.ofOrder(1));
+ assertEquals(6, Primorials.ofOrder(2));
+ assertEquals(30, Primorials.ofOrder(3));
+ assertEquals(210, Primorials.ofOrder(4));
+ assertEquals(2310, Primorials.ofOrder(5));
}
}
From bfd006ed6118cbbd9519de3e7b7899e99024a844 Mon Sep 17 00:00:00 2001
From: Kenneth Jorgensen
Date: Thu, 24 Apr 2025 00:45:44 +0900
Subject: [PATCH 09/14] Fix
---
src/main/java/com/autonomouslogic/primes/Primorials.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/main/java/com/autonomouslogic/primes/Primorials.java b/src/main/java/com/autonomouslogic/primes/Primorials.java
index d043b0a..4c47bb3 100644
--- a/src/main/java/com/autonomouslogic/primes/Primorials.java
+++ b/src/main/java/com/autonomouslogic/primes/Primorials.java
@@ -59,7 +59,7 @@ public static class Order {
/**
* The coprime offsets which when added to multiples of the product are not divisible by any of the primes
- * below c.
+ * less than or equal to c.
*/
long[] coprimeOffsets;
@@ -157,7 +157,7 @@ public static void main(String[] args) {
var offsetsLen = order.getCoprimeOffsets().length;
var space = 100.0 * offsetsLen / order.getProduct();
System.out.printf(
- "Order %d, c=%d, k=%d, %d offsets, %.1f%% space%n",
+ "Order %d: c=%d, product=%d, %d coprime offsets, %.1f%% space%n",
order.getN(), order.getC(), order.getProduct(), offsetsLen, space);
}
}
From 57fa858e4e82fcda18972941c1a9c6441a5b5e04 Mon Sep 17 00:00:00 2001
From: Kenneth Jorgensen
Date: Thu, 24 Apr 2025 00:46:33 +0900
Subject: [PATCH 10/14] Docs
---
.../autonomouslogic/primes/Primorials.java | 20 +++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/src/main/java/com/autonomouslogic/primes/Primorials.java b/src/main/java/com/autonomouslogic/primes/Primorials.java
index 4c47bb3..9984268 100644
--- a/src/main/java/com/autonomouslogic/primes/Primorials.java
+++ b/src/main/java/com/autonomouslogic/primes/Primorials.java
@@ -24,16 +24,16 @@
*
* The main function in this class summarises the orders with the output:
*
- * Order 0: c=1, k=1, 1 offsets, 100.0% space
- * Order 1: c=2, k=2, 1 offsets, 50.0% space
- * Order 2: c=3, k=6, 2 offsets, 33.3% space
- * Order 3: c=5, k=30, 8 offsets, 26.7% space
- * Order 4: c=7, k=210, 48 offsets, 22.9% space
- * Order 5: c=11, k=2310, 480 offsets, 20.8% space
- * Order 6: c=13, k=30030, 5760 offsets, 19.2% space
- * Order 7: c=17, k=510510, 92160 offsets, 18.1% space
- * Order 8: c=19, k=9699690, 1658880 offsets, 17.1% space
- * Order 9: c=23, k=223092870, 36495360 offsets, 16.4% space
+ * Order 0: c=1, product=1, 1 coprime offsets, 100.0% space
+ * Order 1: c=2, product=2, 1 coprime offsets, 50.0% space
+ * Order 2: c=3, product=6, 2 coprime offsets, 33.3% space
+ * Order 3: c=5, product=30, 8 coprime offsets, 26.7% space
+ * Order 4: c=7, product=210, 48 coprime offsets, 22.9% space
+ * Order 5: c=11, product=2310, 480 coprime offsets, 20.8% space
+ * Order 6: c=13, product=30030, 5760 coprime offsets, 19.2% space
+ * Order 7: c=17, product=510510, 92160 coprime offsets, 18.1% space
+ * Order 8: c=19, product=9699690, 1658880 coprime offsets, 17.1% space
+ * Order 9: c=23, product=223092870, 36495360 coprime offsets, 16.4% space
*
*
*/
From a03695692708d808f692676fa4916150d761bfa6 Mon Sep 17 00:00:00 2001
From: Kenneth Jorgensen
Date: Thu, 24 Apr 2025 01:03:37 +0900
Subject: [PATCH 11/14] Fixed up tests
---
.../primes/PrimorialsTest.java | 24 ++++++++++++-------
1 file changed, 15 insertions(+), 9 deletions(-)
diff --git a/src/test/java/com/autonomouslogic/primes/PrimorialsTest.java b/src/test/java/com/autonomouslogic/primes/PrimorialsTest.java
index e9347bd..f13aec8 100644
--- a/src/test/java/com/autonomouslogic/primes/PrimorialsTest.java
+++ b/src/test/java/com/autonomouslogic/primes/PrimorialsTest.java
@@ -13,7 +13,7 @@
public class PrimorialsTest {
@ParameterizedTest
@MethodSource("orderTests")
- void shouldCreateOrders(int order, Primorials.Order expected) {
+ void shouldCreateOrdersWithCoprimeOffsets(int order, Primorials.Order expected) {
assertEquals(expected, Primorials.ofOrderWithCoprimes(order));
}
@@ -80,13 +80,19 @@ void shouldReturnAllPossiblePrimesFromOffset() {
assertEquals(expected, actual);
}
- @Test
- void shouldCalculatePrimorialOfOrder() {
- assertEquals(1, Primorials.ofOrder(0));
- assertEquals(2, Primorials.ofOrder(1));
- assertEquals(6, Primorials.ofOrder(2));
- assertEquals(30, Primorials.ofOrder(3));
- assertEquals(210, Primorials.ofOrder(4));
- assertEquals(2310, Primorials.ofOrder(5));
+ @ParameterizedTest
+ @MethodSource("primorialTests")
+ void shouldCalculatePrimorialOfOrder(int order, int expected) {
+ assertEquals(expected, Primorials.ofOrder(order));
+ }
+
+ public static Stream primorialTests() {
+ return Stream.of(
+ Arguments.of(0, 1),
+ Arguments.of(1, 2),
+ Arguments.of(2, 6),
+ Arguments.of(3, 30),
+ Arguments.of(4, 210),
+ Arguments.of(5, 2310));
}
}
From 656bc92e408d1fa2f7fd0ce5be0e1841d40f6eb6 Mon Sep 17 00:00:00 2001
From: Kenneth Jorgensen
Date: Thu, 24 Apr 2025 01:21:06 +0900
Subject: [PATCH 12/14] Fixes and tried integrating possible primes into
TrialDivision
---
.../autonomouslogic/primes/Primorials.java | 7 +++++-
.../autonomouslogic/primes/TrialDivision.java | 24 ++++++++++++++++---
.../primes/PrimorialsTest.java | 2 ++
3 files changed, 29 insertions(+), 4 deletions(-)
diff --git a/src/main/java/com/autonomouslogic/primes/Primorials.java b/src/main/java/com/autonomouslogic/primes/Primorials.java
index 9984268..c7173f2 100644
--- a/src/main/java/com/autonomouslogic/primes/Primorials.java
+++ b/src/main/java/com/autonomouslogic/primes/Primorials.java
@@ -135,7 +135,7 @@ public static LongStream allPossiblePrimes(long from) {
if (from < 2) {
throw new IllegalArgumentException("from must be at least 2");
}
- return IntStream.rangeClosed(1, 8)
+ var mainStream = IntStream.rangeClosed(1, 8)
.mapToObj(Primorials::ofOrderWithCoprimes)
.filter(o -> ofOrder(o.getN() + 1) >= from)
.flatMapToLong(order -> {
@@ -149,6 +149,11 @@ public static LongStream allPossiblePrimes(long from) {
}
return stream;
});
+ if (from == 2) {
+ return LongStream.concat(LongStream.of(2), mainStream);
+ } else {
+ return mainStream;
+ }
}
public static void main(String[] args) {
diff --git a/src/main/java/com/autonomouslogic/primes/TrialDivision.java b/src/main/java/com/autonomouslogic/primes/TrialDivision.java
index d00b3e3..a139da8 100644
--- a/src/main/java/com/autonomouslogic/primes/TrialDivision.java
+++ b/src/main/java/com/autonomouslogic/primes/TrialDivision.java
@@ -8,15 +8,33 @@ public boolean isPrime(long number) {
if (number == 2) {
return true;
}
+ var maxCheck = PrimeUtils.maxRequiredCheck(number);
+
+ // This is so much faster than using the stream of possible primes below. It can probably be optimised.
if (number % 2 == 0) {
return false;
}
- var max = PrimeUtils.maxRequiredCheck(number);
- for (int i = 3; i <= max; i += 2) {
- if (number % i == 0) {
+ for (int n = 3; n <= maxCheck; n += 2) {
+ if (number % n == 0) {
return false;
}
}
+
+ // var iterator = Primorials.allPossiblePrimes().iterator();
+ // while (iterator.hasNext()) {
+ // var n = iterator.next();
+ // if (n > maxCheck) {
+ // break;
+ // }
+ // if (number % n == 0) {
+ // return false;
+ // }
+ // }
+
return true;
+
+ // return Primorials.allPossiblePrimes()
+ // .takeWhile(n -> n <= maxCheck)
+ // .noneMatch(n -> number % n == 0);
}
}
diff --git a/src/test/java/com/autonomouslogic/primes/PrimorialsTest.java b/src/test/java/com/autonomouslogic/primes/PrimorialsTest.java
index f13aec8..78df1f0 100644
--- a/src/test/java/com/autonomouslogic/primes/PrimorialsTest.java
+++ b/src/test/java/com/autonomouslogic/primes/PrimorialsTest.java
@@ -4,6 +4,7 @@
import java.util.List;
import java.util.stream.Collectors;
+import java.util.stream.LongStream;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
@@ -49,6 +50,7 @@ public static Stream possiblePrimesTests() {
@Test
void shouldReturnAllPossiblePrimes() {
var expected = Stream.of(
+ LongStream.of(2),
Primorials.ofOrderWithCoprimes(1).possiblePrimes().takeWhile(n -> n < 6),
Primorials.ofOrderWithCoprimes(2).possiblePrimes().takeWhile(n -> n < 30),
Primorials.ofOrderWithCoprimes(3).possiblePrimes().takeWhile(n -> n < 200))
From 4bc9d406a1001cb372ef284e5800b29e5bd48cc3 Mon Sep 17 00:00:00 2001
From: Kenneth Jorgensen
Date: Thu, 24 Apr 2025 02:12:29 +0900
Subject: [PATCH 13/14] Trying to speed up Primorial possible prime generation
and somehow managed to break it in the process
---
.../autonomouslogic/primes/Primorials.java | 21 +++++++++++++---
.../autonomouslogic/primes/TrialDivision.java | 25 ++++++++++---------
.../primes/PrimorialsTest.java | 7 ++++++
.../primes/TrialDivisionTest.java | 1 +
4 files changed, 39 insertions(+), 15 deletions(-)
diff --git a/src/main/java/com/autonomouslogic/primes/Primorials.java b/src/main/java/com/autonomouslogic/primes/Primorials.java
index c7173f2..b7e6001 100644
--- a/src/main/java/com/autonomouslogic/primes/Primorials.java
+++ b/src/main/java/com/autonomouslogic/primes/Primorials.java
@@ -39,6 +39,13 @@
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class Primorials {
+ /**
+ * The maximum order that will be cached and used in {@link #allPossiblePrimes(long)}.
+ */
+ private static final int MAX_ORDER = 3;
+
+ private static final Order[] ORDER_CACHE = new Order[MAX_ORDER + 1];
+
@Value
@AllArgsConstructor(access = AccessLevel.PROTECTED)
public static class Order {
@@ -96,6 +103,10 @@ public static long ofOrder(int n) {
* @return
*/
public static Primorials.Order ofOrderWithCoprimes(int n) {
+ if (n <= MAX_ORDER && ORDER_CACHE[n] != null) {
+ return ORDER_CACHE[n];
+ }
+
var primes = Arrays.stream(PrimeList.PRIMES).limit(n).toArray();
long product = 1;
for (int prime : primes) {
@@ -114,7 +125,11 @@ public static Primorials.Order ofOrderWithCoprimes(int n) {
.map(num -> num - finalProduct)
.toArray();
var c = primes.length == 0 ? 1 : primes[primes.length - 1];
- return new Primorials.Order(n, c, product, offsets);
+ var order = new Primorials.Order(n, c, product, offsets);
+ if (n <= MAX_ORDER) {
+ ORDER_CACHE[n] = order;
+ }
+ return order;
}
/**
@@ -135,11 +150,11 @@ public static LongStream allPossiblePrimes(long from) {
if (from < 2) {
throw new IllegalArgumentException("from must be at least 2");
}
- var mainStream = IntStream.rangeClosed(1, 8)
+ var mainStream = IntStream.rangeClosed(1, MAX_ORDER)
.mapToObj(Primorials::ofOrderWithCoprimes)
.filter(o -> ofOrder(o.getN() + 1) >= from)
.flatMapToLong(order -> {
- if (order.getProduct() == 8) {
+ if (order.getN() == MAX_ORDER) {
return order.possiblePrimes();
}
var nextK = ofOrder(order.getN() + 1);
diff --git a/src/main/java/com/autonomouslogic/primes/TrialDivision.java b/src/main/java/com/autonomouslogic/primes/TrialDivision.java
index a139da8..3869c6e 100644
--- a/src/main/java/com/autonomouslogic/primes/TrialDivision.java
+++ b/src/main/java/com/autonomouslogic/primes/TrialDivision.java
@@ -14,23 +14,24 @@ public boolean isPrime(long number) {
if (number % 2 == 0) {
return false;
}
- for (int n = 3; n <= maxCheck; n += 2) {
- if (number % n == 0) {
- return false;
- }
- }
-
- // var iterator = Primorials.allPossiblePrimes().iterator();
- // while (iterator.hasNext()) {
- // var n = iterator.next();
- // if (n > maxCheck) {
- // break;
- // }
+ // for (int n = 3; n <= maxCheck; n += 2) {
// if (number % n == 0) {
// return false;
// }
// }
+ var iterator = Primorials.allPossiblePrimes().iterator();
+ while (iterator.hasNext()) {
+ var n = iterator.next();
+ System.out.println("n=" + n);
+ if (n > maxCheck) {
+ break;
+ }
+ if (number % n == 0) {
+ return false;
+ }
+ }
+
return true;
// return Primorials.allPossiblePrimes()
diff --git a/src/test/java/com/autonomouslogic/primes/PrimorialsTest.java b/src/test/java/com/autonomouslogic/primes/PrimorialsTest.java
index 78df1f0..8ca08d1 100644
--- a/src/test/java/com/autonomouslogic/primes/PrimorialsTest.java
+++ b/src/test/java/com/autonomouslogic/primes/PrimorialsTest.java
@@ -58,6 +58,7 @@ void shouldReturnAllPossiblePrimes() {
.mapToObj(String::valueOf)
.collect(Collectors.joining("\n"));
var actual = Primorials.allPossiblePrimes()
+ .peek(n -> System.out.println(n))
.takeWhile(n -> n <= 200)
.mapToObj(String::valueOf)
.collect(Collectors.joining("\n"));
@@ -97,4 +98,10 @@ public static Stream primorialTests() {
Arguments.of(4, 210),
Arguments.of(5, 2310));
}
+
+ @Test
+ void speedTest() {
+ var sum = Primorials.allPossiblePrimes().takeWhile(n -> n < 104729).sum();
+ assertEquals(1058956954, sum);
+ }
}
diff --git a/src/test/java/com/autonomouslogic/primes/TrialDivisionTest.java b/src/test/java/com/autonomouslogic/primes/TrialDivisionTest.java
index 95f1a33..53a4628 100644
--- a/src/test/java/com/autonomouslogic/primes/TrialDivisionTest.java
+++ b/src/test/java/com/autonomouslogic/primes/TrialDivisionTest.java
@@ -13,6 +13,7 @@ public class TrialDivisionTest {
void testTrialDivision() {
var test = new TrialDivision();
PrimeTestUtil.primeTestNumbers()
+ .filter(t -> t.number == 49)
.forEach(n -> assertEquals(n.isPrime, test.isPrime(n.number), Long.toString(n.number)));
}
From ccdb8d3f39a2f60521ae9806f333493a495114ef Mon Sep 17 00:00:00 2001
From: Kenneth Jorgensen
Date: Fri, 25 Apr 2025 16:24:06 +0900
Subject: [PATCH 14/14] Debugging
---
.../java/com/autonomouslogic/primes/Primorials.java | 12 ++++++++----
.../com/autonomouslogic/primes/PrimorialsTest.java | 10 +++++++---
2 files changed, 15 insertions(+), 7 deletions(-)
diff --git a/src/main/java/com/autonomouslogic/primes/Primorials.java b/src/main/java/com/autonomouslogic/primes/Primorials.java
index b7e6001..5f858ff 100644
--- a/src/main/java/com/autonomouslogic/primes/Primorials.java
+++ b/src/main/java/com/autonomouslogic/primes/Primorials.java
@@ -154,14 +154,18 @@ public static LongStream allPossiblePrimes(long from) {
.mapToObj(Primorials::ofOrderWithCoprimes)
.filter(o -> ofOrder(o.getN() + 1) >= from)
.flatMapToLong(order -> {
- if (order.getN() == MAX_ORDER) {
- return order.possiblePrimes();
+ System.out.printf("Order: %s%n", order);
+ var stream = order.possiblePrimes();
+ if (order.getN() < MAX_ORDER) {
+ System.out.println("not MAX_ORDER");
+ var nextK = ofOrder(order.getN() + 1);
+ System.out.printf("nextK: %s%n", nextK);
+ stream = order.possiblePrimes().takeWhile(num -> num < nextK);
}
- var nextK = ofOrder(order.getN() + 1);
- var stream = order.possiblePrimes().takeWhile(num -> num < nextK);
if (order.getProduct() < from) {
stream = stream.filter(n -> n >= from);
}
+ System.out.println("return stream");
return stream;
});
if (from == 2) {
diff --git a/src/test/java/com/autonomouslogic/primes/PrimorialsTest.java b/src/test/java/com/autonomouslogic/primes/PrimorialsTest.java
index 8ca08d1..e144765 100644
--- a/src/test/java/com/autonomouslogic/primes/PrimorialsTest.java
+++ b/src/test/java/com/autonomouslogic/primes/PrimorialsTest.java
@@ -56,12 +56,16 @@ void shouldReturnAllPossiblePrimes() {
Primorials.ofOrderWithCoprimes(3).possiblePrimes().takeWhile(n -> n < 200))
.flatMapToLong(s -> s)
.mapToObj(String::valueOf)
- .collect(Collectors.joining("\n"));
+ .toList();
+ // .collect(Collectors.joining("\n"));
var actual = Primorials.allPossiblePrimes()
.peek(n -> System.out.println(n))
- .takeWhile(n -> n <= 200)
+ // .takeWhile(n -> n <= 200)
.mapToObj(String::valueOf)
- .collect(Collectors.joining("\n"));
+ .limit(expected.size())
+ .toList();
+ // .count();
+ // .collect(Collectors.joining("\n"));
assertEquals(expected, actual);
}