Tim Varley Logo
Tim Varley Principal AI Engineer and Tech Leader
Problem #26 hard

Reciprocal Cycles

A unit fraction contains 11 in the numerator. The decimal representation of the unit fractions with denominators 22 to 1010 are given:

1/2 &= 0.5\\ 1/3 &= 0.\bar{3}\\ 1/4 &=0.25\\ 1/5 &= 0.2\\ 1/6 &= 0.1\bar{6}\\ 1/7 &= 0.\overline{142857}\\ 1/8 &= 0.125\\ 1/9 &= 0.\bar{1}\\ 1/10 &= 0.1 \end{align}$$ Where $0.1\bar{6}$ means $0.166666\cdots$, and has a $1$-digit recurring cycle. It can be seen that $1/7$ has a $6$-digit recurring cycle. Find the value of $d \lt 1000$ for which $1/d$ contains the longest recurring cycle in its decimal fraction part.
View on Project Euler

Implementations

cpp
// https://projecteuler.net/problem=26
// A unit fraction contains 1 in the numerator. The decimal representation of the unit fractions with denominators 2 to 10 are given:
// 1/2 = 0.5
// 1/3 = 0.(3)
// 1/4 = 0.25
// 1/5 = 0.2
// 1/6 = 0.1(6)
// 1/7 = 0.(142857)
// 1/8 = 0.125
// 1/9 = 0.(1)
// 1/10 = 0.1
// Where 0.1(6) means 0.1666..., and has a 1-digit recurring cycle. It can be seen that 1/7 has a 6-digit recurring cycle.
// Find the value of d < 1000 for which 1/d contains the longest recurring cycle in its decimal fraction part.
//
// Answer: 983
//
#include <iostream>
#include <map>
int longest_reciprocal_cycle(int max_d) {
int max_cycle = 0;
int max_d_val = 0;
for (int d = 2; d < max_d; ++d) {
std::map<int, int> remainder_positions;
int remainder = 1;
int position = 0;
while (remainder != 0 && remainder_positions.find(remainder) == remainder_positions.end()) {
remainder_positions[remainder] = position;
remainder *= 10;
remainder %= d;
++position;
}
if (remainder != 0) {
int cycle_length = position - remainder_positions[remainder];
if (cycle_length > max_cycle) {
max_cycle = cycle_length;
max_d_val = d;
}
}
}
return max_d_val;
}
#if ! defined UNITTEST_MODE
int main(int argc, char const *argv[]) {
std::cout << longest_reciprocal_cycle(1000) << std::endl;
}
#endif // UNITTEST_MODE
View on GitHub
O(n) time complexity

Solution Notes

Mathematical Background

This problem explores the decimal representations of unit fractions and their repeating decimal cycles. The length of the recurring cycle for 1/d1/d is determined by the multiplicative order of 10 modulo d, or more precisely, by the period of the decimal expansion.

For a fraction 1/d1/d in lowest terms, the decimal expansion will be periodic with period equal to the smallest k such that 10k1(modd)10^k \equiv 1 \pmod{d}. The period length depends on the prime factors of d.

Algorithm Analysis

Long division simulation: Perform long division of 1 by d, tracking remainders to detect when the division repeats.

Cycle detection: Use a map to store the position where each remainder first occurred. When a remainder repeats, the cycle length is current position minus stored position.

Key optimization: Only check denominators that don’t share factors with 2 or 5, as these produce terminating decimals.

Search strategy: For each d from 2 to 999, compute the cycle length and track the maximum.

Time complexity is O(MAX × log MAX) due to the cycle detection process. Space complexity is O(MAX) for remainder tracking.

Key Insights

  • The longest cycle occurs for d = 983, with a 982-digit recurring cycle
  • Only primes not dividing 2 or 5 can produce long cycles
  • The cycle length for prime p is the order of 10 modulo p
  • Some composite numbers can have longer cycles than primes
  • This demonstrates the connection between number theory and decimal arithmetic

Educational Value

This problem teaches:

  • Decimal expansion and periodic fractions
  • The mathematics of recurring decimals
  • Cycle detection algorithms
  • Modular arithmetic applications
  • The relationship between number theory and decimal representations
  • Efficient computation of long division
  • When to use mathematical insights to optimize brute force approaches

Problem #26 is taken from Project Euler and licensed under CC BY-NC-SA 4.0.