From f7d376d2e60b500ad7bf7103cab3f2c6ff57f336 Mon Sep 17 00:00:00 2001
From: Lamine Gaye <lamine5.gaye@ucad.edu.sn>
Date: Wed, 16 Oct 2024 15:09:36 +0000
Subject: [PATCH 1/5] feat: add findLongestRecurringCycle algorithm

---
 Maths/MobiusFunction.js               |  4 +-
 Project-Euler/Problem026.js           | 71 +++++++++++++++++++++++++++
 Project-Euler/test/Problem026.test.js | 30 +++++++++++
 3 files changed, 103 insertions(+), 2 deletions(-)
 create mode 100644 Project-Euler/Problem026.js
 create mode 100644 Project-Euler/test/Problem026.test.js

diff --git a/Maths/MobiusFunction.js b/Maths/MobiusFunction.js
index bd268b8bbd..4239d6ab31 100644
--- a/Maths/MobiusFunction.js
+++ b/Maths/MobiusFunction.js
@@ -28,6 +28,6 @@ export const mobiusFunction = (number) => {
   return primeFactorsArray.length !== new Set(primeFactorsArray).size
     ? 0
     : primeFactorsArray.length % 2 === 0
-    ? 1
-    : -1
+      ? 1
+      : -1
 }
diff --git a/Project-Euler/Problem026.js b/Project-Euler/Problem026.js
new file mode 100644
index 0000000000..edee6f2299
--- /dev/null
+++ b/Project-Euler/Problem026.js
@@ -0,0 +1,71 @@
+/**
+ * Problem - Longest Recurring Cycle
+ *
+ * @see {@link https://projecteuler.net/problem=26}
+ *
+ * Find the value of denominator < 1000 for which 1/denominator contains the longest recurring cycle in its decimal fraction part.
+ *
+ * A unit fraction (1/denominator) either terminates or repeats. We need to determine the length of the repeating sequence (cycle)
+ * for each fraction where the denominator is between 2 and 999, and find the denominator that produces the longest cycle.
+ */
+
+/**
+ * Main function to find the denominator < limit with the longest recurring cycle in 1/denominator.
+ *
+ * @param {number} limit - The upper limit for the denominator (exclusive).
+ * @returns {number} The denominator that has the longest recurring cycle in its decimal fraction part.
+ */
+function findLongestRecurringCycle(limit) {
+  /**
+   * Calculates the length of the recurring cycle for 1 divided by a given denominator.
+   *
+   * @param {number} denominator - The denominator of the unit fraction (1/denominator).
+   * @returns {number} The length of the recurring cycle in the decimal part of 1/denominator.
+   */
+  function getRecurringCycleLength(denominator) {
+    // A map to store the position of each remainder encountered during division
+    const remainderPositions = new Map()
+    let numerator = 1 // We start with 1 as the numerator (as we're computing 1/denominator)
+    let position = 0 // This tracks the position of each digit in the decimal sequence
+
+    // Continue until the remainder becomes 0 (terminating decimal) or a cycle is found
+    while (numerator !== 0) {
+      // If the remainder has been seen before, we've found the start of the cycle
+      if (remainderPositions.has(numerator)) {
+        // The length of the cycle is the current position minus the position when the remainder first appeared
+        return position - remainderPositions.get(numerator)
+      }
+
+      // Record the position of this remainder
+      remainderPositions.set(numerator, position)
+
+      // Multiply numerator by 10 to simulate long division and get the next digit
+      numerator = (numerator * 10) % denominator
+      position++ // Move to the next digit position
+    }
+
+    // If numerator becomes 0, it means the decimal terminates (no cycle)
+    return 0
+  }
+
+  let maxCycleLength = 0 // Store the maximum cycle length found
+  let denominatorWithMaxCycle = 0 // Store the denominator corresponding to the longest cycle
+
+  // Iterate through each possible denominator from 2 up to (limit - 1)
+  for (let denominator = 2; denominator < limit; denominator++) {
+    // Calculate the cycle length for the current denominator
+    const cycleLength = getRecurringCycleLength(denominator)
+
+    // Update the maximum length and the corresponding denominator if a longer cycle is found
+    if (cycleLength > maxCycleLength) {
+      maxCycleLength = cycleLength
+      denominatorWithMaxCycle = denominator
+    }
+  }
+
+  // Return the denominator that has the longest recurring cycle
+  return denominatorWithMaxCycle
+}
+
+// Exporting the main function for use in other modules
+export { findLongestRecurringCycle }
diff --git a/Project-Euler/test/Problem026.test.js b/Project-Euler/test/Problem026.test.js
new file mode 100644
index 0000000000..ac276bf748
--- /dev/null
+++ b/Project-Euler/test/Problem026.test.js
@@ -0,0 +1,30 @@
+import { findLongestRecurringCycle } from '../Problem026'
+
+/**
+ * Tests for the findLongestRecurringCycle function.
+ */
+describe('findLongestRecurringCycle', () => {
+  // Test to check the basic case with a limit of 10
+  test('should return 7 for limit of 10', () => {
+    const result = findLongestRecurringCycle(10)
+    expect(result).toBe(7)
+  })
+
+  // Test to check with a limit of 1000
+  test('should return the correct value for limit of 1000', () => {
+    const result = findLongestRecurringCycle(1000)
+    expect(result).toBe(983) // The expected result is the denominator with the longest cycle
+  })
+
+  // Test with a smaller limit to validate behavior
+  test('should return 3 for limit of 4', () => {
+    const result = findLongestRecurringCycle(4)
+    expect(result).toBe(3)
+  })
+
+  // Test with a limit of 2, where there is no cycle
+  test('should return 0 for limit of 2', () => {
+    const result = findLongestRecurringCycle(2)
+    expect(result).toBe(0) // No cycle for fractions 1/1 and 1/2
+  })
+})

From 2b739bfced6cd28c4dbdafeb5c24981c162f8f1a Mon Sep 17 00:00:00 2001
From: Lamine Gaye <lamine5.gaye@ucad.edu.sn>
Date: Wed, 16 Oct 2024 15:28:49 +0000
Subject: [PATCH 2/5] fix: format MobiusFunction.js with Prettier

---
 Maths/MobiusFunction.js | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Maths/MobiusFunction.js b/Maths/MobiusFunction.js
index 4239d6ab31..bd268b8bbd 100644
--- a/Maths/MobiusFunction.js
+++ b/Maths/MobiusFunction.js
@@ -28,6 +28,6 @@ export const mobiusFunction = (number) => {
   return primeFactorsArray.length !== new Set(primeFactorsArray).size
     ? 0
     : primeFactorsArray.length % 2 === 0
-      ? 1
-      : -1
+    ? 1
+    : -1
 }

From fd1d6e6d5a6d861854d37ff057237e91b4242c59 Mon Sep 17 00:00:00 2001
From: Lamine Gaye <lamine5.gaye@ucad.edu.sn>
Date: Wed, 16 Oct 2024 17:58:15 +0000
Subject: [PATCH 3/5] Add Problem 027 - Quadratic Primes algorithm and tests

---
 Project-Euler/Problem027.js           | 61 +++++++++++++++++++++++++++
 Project-Euler/test/Problem027.test.js |  9 ++++
 2 files changed, 70 insertions(+)
 create mode 100644 Project-Euler/Problem027.js
 create mode 100644 Project-Euler/test/Problem027.test.js

diff --git a/Project-Euler/Problem027.js b/Project-Euler/Problem027.js
new file mode 100644
index 0000000000..dac47a4552
--- /dev/null
+++ b/Project-Euler/Problem027.js
@@ -0,0 +1,61 @@
+/**
+ * Problem - Quadratic Primes
+ *
+ * @see {@link https://projecteuler.net/problem=27}
+ *
+ * The quadratic expression n^2 + an + b, where |a| < 1000 and |b| ≤ 1000,
+ * produces a positive prime for consecutive values of n, starting with n = 0.
+ * Find the product of the coefficients, a and b, for the quadratic expression that
+ * produces the maximum number of primes for consecutive values of n.
+ */
+
+/**
+ * Main function to find the coefficients a and b that produce the maximum number
+ * of consecutive primes for the quadratic expression n^2 + an + b.
+ *
+ * @returns {{maxPrimes: number, product: number}} An object containing the maximum number of primes
+ * and the product of coefficients a and b.
+ */
+function findMaxConsecutivePrimes() {
+  /**
+   * Checks if a number is prime.
+   *
+   * @param {number} n - The number to check for primality.
+   * @returns {boolean} True if n is a prime number, false otherwise.
+   */
+  function isPrime(n) {
+    if (n < 2) return false // 0 and 1 are not prime numbers
+    if (n === 2) return true // 2 is a prime number
+    if (n % 2 === 0) return false // Exclude even numbers
+    for (let i = 3; i <= Math.sqrt(n); i += 2) {
+      // Check odd divisors only
+      if (n % i === 0) return false // Divisible by i, so not prime
+    }
+    return true // No divisors found, so it is prime
+  }
+
+  let maxPrimes = 0 // Store the maximum number of primes found
+  let product = 0 // Store the product of coefficients a and b
+
+  for (let a = -999; a < 1000; a++) {
+    for (let b = -1000; b <= 1000; b++) {
+      let n = 0
+      let consecutivePrimes = 0
+      while (true) {
+        const result = n * n + a * n + b // Evaluate the quadratic expression
+        if (result < 0 || !isPrime(result)) break // Stop if the result is negative or not prime
+        consecutivePrimes++
+        n++
+      }
+      if (consecutivePrimes > maxPrimes) {
+        maxPrimes = consecutivePrimes
+        product = a * b // Calculate product of coefficients a and b
+      }
+    }
+  }
+
+  return { maxPrimes, product } // Return the results
+}
+
+// Exporting the main function for use in other modules
+export { findMaxConsecutivePrimes }
diff --git a/Project-Euler/test/Problem027.test.js b/Project-Euler/test/Problem027.test.js
new file mode 100644
index 0000000000..f7859f03d6
--- /dev/null
+++ b/Project-Euler/test/Problem027.test.js
@@ -0,0 +1,9 @@
+import { findMaxConsecutivePrimes } from '../Problem027'
+
+describe('Problem 027 - Quadratic Primes', () => {
+  test('should return the correct product of coefficients for max consecutive primes', () => {
+    const { maxPrimes, product } = findMaxConsecutivePrimes()
+    expect(maxPrimes).toBe(71)
+    expect(product).toBe(-59231)
+  })
+})

From c6192d760d9d097352d49ccb49a76dd189309927 Mon Sep 17 00:00:00 2001
From: Lamine Gaye <lamine5.gaye@ucad.edu.sn>
Date: Sun, 20 Oct 2024 19:34:56 +0000
Subject: [PATCH 4/5] feat: add findLongestRecurringCycle algorithm (Problem
 26)

---
 Project-Euler/Problem026.js           | 25 +++++-----------------
 Project-Euler/test/Problem026.test.js | 30 +++++++--------------------
 2 files changed, 13 insertions(+), 42 deletions(-)

diff --git a/Project-Euler/Problem026.js b/Project-Euler/Problem026.js
index edee6f2299..684f1c55a1 100644
--- a/Project-Euler/Problem026.js
+++ b/Project-Euler/Problem026.js
@@ -4,9 +4,6 @@
  * @see {@link https://projecteuler.net/problem=26}
  *
  * Find the value of denominator < 1000 for which 1/denominator contains the longest recurring cycle in its decimal fraction part.
- *
- * A unit fraction (1/denominator) either terminates or repeats. We need to determine the length of the repeating sequence (cycle)
- * for each fraction where the denominator is between 2 and 999, and find the denominator that produces the longest cycle.
  */
 
 /**
@@ -23,49 +20,37 @@ function findLongestRecurringCycle(limit) {
    * @returns {number} The length of the recurring cycle in the decimal part of 1/denominator.
    */
   function getRecurringCycleLength(denominator) {
-    // A map to store the position of each remainder encountered during division
     const remainderPositions = new Map()
-    let numerator = 1 // We start with 1 as the numerator (as we're computing 1/denominator)
-    let position = 0 // This tracks the position of each digit in the decimal sequence
+    let numerator = 1
+    let position = 0
 
-    // Continue until the remainder becomes 0 (terminating decimal) or a cycle is found
     while (numerator !== 0) {
-      // If the remainder has been seen before, we've found the start of the cycle
       if (remainderPositions.has(numerator)) {
-        // The length of the cycle is the current position minus the position when the remainder first appeared
         return position - remainderPositions.get(numerator)
       }
 
-      // Record the position of this remainder
       remainderPositions.set(numerator, position)
 
-      // Multiply numerator by 10 to simulate long division and get the next digit
       numerator = (numerator * 10) % denominator
-      position++ // Move to the next digit position
+      position++
     }
 
-    // If numerator becomes 0, it means the decimal terminates (no cycle)
     return 0
   }
 
-  let maxCycleLength = 0 // Store the maximum cycle length found
-  let denominatorWithMaxCycle = 0 // Store the denominator corresponding to the longest cycle
+  let maxCycleLength = 0
+  let denominatorWithMaxCycle = 0
 
-  // Iterate through each possible denominator from 2 up to (limit - 1)
   for (let denominator = 2; denominator < limit; denominator++) {
-    // Calculate the cycle length for the current denominator
     const cycleLength = getRecurringCycleLength(denominator)
 
-    // Update the maximum length and the corresponding denominator if a longer cycle is found
     if (cycleLength > maxCycleLength) {
       maxCycleLength = cycleLength
       denominatorWithMaxCycle = denominator
     }
   }
 
-  // Return the denominator that has the longest recurring cycle
   return denominatorWithMaxCycle
 }
 
-// Exporting the main function for use in other modules
 export { findLongestRecurringCycle }
diff --git a/Project-Euler/test/Problem026.test.js b/Project-Euler/test/Problem026.test.js
index ac276bf748..67f60c2b48 100644
--- a/Project-Euler/test/Problem026.test.js
+++ b/Project-Euler/test/Problem026.test.js
@@ -4,27 +4,13 @@ import { findLongestRecurringCycle } from '../Problem026'
  * Tests for the findLongestRecurringCycle function.
  */
 describe('findLongestRecurringCycle', () => {
-  // Test to check the basic case with a limit of 10
-  test('should return 7 for limit of 10', () => {
-    const result = findLongestRecurringCycle(10)
-    expect(result).toBe(7)
-  })
-
-  // Test to check with a limit of 1000
-  test('should return the correct value for limit of 1000', () => {
-    const result = findLongestRecurringCycle(1000)
-    expect(result).toBe(983) // The expected result is the denominator with the longest cycle
-  })
-
-  // Test with a smaller limit to validate behavior
-  test('should return 3 for limit of 4', () => {
-    const result = findLongestRecurringCycle(4)
-    expect(result).toBe(3)
-  })
-
-  // Test with a limit of 2, where there is no cycle
-  test('should return 0 for limit of 2', () => {
-    const result = findLongestRecurringCycle(2)
-    expect(result).toBe(0) // No cycle for fractions 1/1 and 1/2
+  it.each([
+    { limit: 10, expected: 7 },
+    { limit: 1000, expected: 983 }, // The denominator with the longest cycle for limit of 1000
+    { limit: 4, expected: 3 },
+    { limit: 2, expected: 0 } // No cycle for fractions 1/1 and 1/2
+  ])('should return $expected for limit of $limit', ({ limit, expected }) => {
+    const result = findLongestRecurringCycle(limit)
+    expect(result).toBe(expected)
   })
 })

From 714bdab27863e2589cc7acb91ac633bc4cf19f37 Mon Sep 17 00:00:00 2001
From: Lamine Gaye <lamine5.gaye@ucad.edu.sn>
Date: Sun, 20 Oct 2024 19:54:51 +0000
Subject: [PATCH 5/5] feat: add Quadratic Primes algorithm and tests (Problem
 27)

---
 Project-Euler/Problem027.js | 36 +++++++++++++-----------------------
 1 file changed, 13 insertions(+), 23 deletions(-)

diff --git a/Project-Euler/Problem027.js b/Project-Euler/Problem027.js
index dac47a4552..d1d27aa3b2 100644
--- a/Project-Euler/Problem027.js
+++ b/Project-Euler/Problem027.js
@@ -17,45 +17,35 @@
  * and the product of coefficients a and b.
  */
 function findMaxConsecutivePrimes() {
-  /**
-   * Checks if a number is prime.
-   *
-   * @param {number} n - The number to check for primality.
-   * @returns {boolean} True if n is a prime number, false otherwise.
-   */
   function isPrime(n) {
-    if (n < 2) return false // 0 and 1 are not prime numbers
-    if (n === 2) return true // 2 is a prime number
-    if (n % 2 === 0) return false // Exclude even numbers
+    if (n < 2) return false
+    if (n === 2) return true
+    if (n % 2 === 0) return false
     for (let i = 3; i <= Math.sqrt(n); i += 2) {
-      // Check odd divisors only
-      if (n % i === 0) return false // Divisible by i, so not prime
+      if (n % i === 0) return false
     }
-    return true // No divisors found, so it is prime
+    return true
   }
 
-  let maxPrimes = 0 // Store the maximum number of primes found
-  let product = 0 // Store the product of coefficients a and b
+  let maxPrimes = 0
+  let product = 0
 
   for (let a = -999; a < 1000; a++) {
     for (let b = -1000; b <= 1000; b++) {
       let n = 0
-      let consecutivePrimes = 0
       while (true) {
-        const result = n * n + a * n + b // Evaluate the quadratic expression
-        if (result < 0 || !isPrime(result)) break // Stop if the result is negative or not prime
-        consecutivePrimes++
+        const result = n * n + a * n + b
+        if (result < 0 || !isPrime(result)) break
         n++
       }
-      if (consecutivePrimes > maxPrimes) {
-        maxPrimes = consecutivePrimes
-        product = a * b // Calculate product of coefficients a and b
+      if (n > maxPrimes) {
+        maxPrimes = n
+        product = a * b
       }
     }
   }
 
-  return { maxPrimes, product } // Return the results
+  return { maxPrimes, product }
 }
 
-// Exporting the main function for use in other modules
 export { findMaxConsecutivePrimes }