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/3] 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/3] 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/3] 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)
+  })
+})