Skip to content

Commit c6192d7

Browse files
committed
feat: add findLongestRecurringCycle algorithm (Problem 26)
1 parent fd1d6e6 commit c6192d7

File tree

2 files changed

+13
-42
lines changed

2 files changed

+13
-42
lines changed

Project-Euler/Problem026.js

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,6 @@
44
* @see {@link https://projecteuler.net/problem=26}
55
*
66
* Find the value of denominator < 1000 for which 1/denominator contains the longest recurring cycle in its decimal fraction part.
7-
*
8-
* A unit fraction (1/denominator) either terminates or repeats. We need to determine the length of the repeating sequence (cycle)
9-
* for each fraction where the denominator is between 2 and 999, and find the denominator that produces the longest cycle.
107
*/
118

129
/**
@@ -23,49 +20,37 @@ function findLongestRecurringCycle(limit) {
2320
* @returns {number} The length of the recurring cycle in the decimal part of 1/denominator.
2421
*/
2522
function getRecurringCycleLength(denominator) {
26-
// A map to store the position of each remainder encountered during division
2723
const remainderPositions = new Map()
28-
let numerator = 1 // We start with 1 as the numerator (as we're computing 1/denominator)
29-
let position = 0 // This tracks the position of each digit in the decimal sequence
24+
let numerator = 1
25+
let position = 0
3026

31-
// Continue until the remainder becomes 0 (terminating decimal) or a cycle is found
3227
while (numerator !== 0) {
33-
// If the remainder has been seen before, we've found the start of the cycle
3428
if (remainderPositions.has(numerator)) {
35-
// The length of the cycle is the current position minus the position when the remainder first appeared
3629
return position - remainderPositions.get(numerator)
3730
}
3831

39-
// Record the position of this remainder
4032
remainderPositions.set(numerator, position)
4133

42-
// Multiply numerator by 10 to simulate long division and get the next digit
4334
numerator = (numerator * 10) % denominator
44-
position++ // Move to the next digit position
35+
position++
4536
}
4637

47-
// If numerator becomes 0, it means the decimal terminates (no cycle)
4838
return 0
4939
}
5040

51-
let maxCycleLength = 0 // Store the maximum cycle length found
52-
let denominatorWithMaxCycle = 0 // Store the denominator corresponding to the longest cycle
41+
let maxCycleLength = 0
42+
let denominatorWithMaxCycle = 0
5343

54-
// Iterate through each possible denominator from 2 up to (limit - 1)
5544
for (let denominator = 2; denominator < limit; denominator++) {
56-
// Calculate the cycle length for the current denominator
5745
const cycleLength = getRecurringCycleLength(denominator)
5846

59-
// Update the maximum length and the corresponding denominator if a longer cycle is found
6047
if (cycleLength > maxCycleLength) {
6148
maxCycleLength = cycleLength
6249
denominatorWithMaxCycle = denominator
6350
}
6451
}
6552

66-
// Return the denominator that has the longest recurring cycle
6753
return denominatorWithMaxCycle
6854
}
6955

70-
// Exporting the main function for use in other modules
7156
export { findLongestRecurringCycle }

Project-Euler/test/Problem026.test.js

Lines changed: 8 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,13 @@ import { findLongestRecurringCycle } from '../Problem026'
44
* Tests for the findLongestRecurringCycle function.
55
*/
66
describe('findLongestRecurringCycle', () => {
7-
// Test to check the basic case with a limit of 10
8-
test('should return 7 for limit of 10', () => {
9-
const result = findLongestRecurringCycle(10)
10-
expect(result).toBe(7)
11-
})
12-
13-
// Test to check with a limit of 1000
14-
test('should return the correct value for limit of 1000', () => {
15-
const result = findLongestRecurringCycle(1000)
16-
expect(result).toBe(983) // The expected result is the denominator with the longest cycle
17-
})
18-
19-
// Test with a smaller limit to validate behavior
20-
test('should return 3 for limit of 4', () => {
21-
const result = findLongestRecurringCycle(4)
22-
expect(result).toBe(3)
23-
})
24-
25-
// Test with a limit of 2, where there is no cycle
26-
test('should return 0 for limit of 2', () => {
27-
const result = findLongestRecurringCycle(2)
28-
expect(result).toBe(0) // No cycle for fractions 1/1 and 1/2
7+
it.each([
8+
{ limit: 10, expected: 7 },
9+
{ limit: 1000, expected: 983 }, // The denominator with the longest cycle for limit of 1000
10+
{ limit: 4, expected: 3 },
11+
{ limit: 2, expected: 0 } // No cycle for fractions 1/1 and 1/2
12+
])('should return $expected for limit of $limit', ({ limit, expected }) => {
13+
const result = findLongestRecurringCycle(limit)
14+
expect(result).toBe(expected)
2915
})
3016
})

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy