1
|
|
|
""" |
2
|
|
|
Project Euler Problem 26: Reciprocal Cycles |
3
|
|
|
=========================================== |
4
|
|
|
|
5
|
|
|
.. module:: solutions.problem26 |
6
|
|
|
:synopsis: My solution to problem #26. |
7
|
|
|
|
8
|
|
|
The source code for this problem can be |
9
|
|
|
`found here <https://bitbucket.org/nekedome/project-euler/src/master/solutions/problem26.py>`_. |
10
|
|
|
|
11
|
|
|
Problem Statement |
12
|
|
|
################# |
13
|
|
|
|
14
|
|
|
A unit fraction contains :math:`1` in the numerator. The decimal representation of the unit fractions with denominators |
|
|
|
|
15
|
|
|
:math:`2` to :math:`10` are given: |
16
|
|
|
|
17
|
|
|
.. math:: |
18
|
|
|
|
19
|
|
|
\\ ^1 / _2 &= 0.5 \\\\ |
20
|
|
|
\\ ^1 / _3 &= 0.(3) \\\\ |
21
|
|
|
\\ ^1 / _4 &= 0.25 \\\\ |
22
|
|
|
\\ ^1 / _5 &= 0.2 \\\\ |
23
|
|
|
\\ ^1 / _6 &= 0.1(6) \\\\ |
24
|
|
|
\\ ^1 / _7 &= 0.(142857) \\\\ |
25
|
|
|
\\ ^1 / _8 &= 0.125 \\\\ |
26
|
|
|
\\ ^1 / _9 &= 0.(1) \\\\ |
27
|
|
|
\\ ^1 / _{10} &= 0.1 |
28
|
|
|
|
29
|
|
|
Where :math:`0.1(6)` means :math:`0.166666\\dots`, and has a :math:`1`-digit recurring cycle. It can be seen that |
|
|
|
|
30
|
|
|
:math:`\\ ^1 / _7` has a :math:`6`-digit recurring cycle. |
31
|
|
|
|
32
|
|
|
Find the value of :math:`d \\lt 1000` for which :math:`\\ ^1 / _d` contains the longest recurring cycle in its decimal |
|
|
|
|
33
|
|
|
fraction part. |
34
|
|
|
|
35
|
|
|
Solution Discussion |
36
|
|
|
################### |
37
|
|
|
|
38
|
|
|
The decimal expansion of :math:`\\ ^1 / _d` falls into one of three possibilities: |
39
|
|
|
|
40
|
|
|
1. Divisors :math:`d` of the form :math:`2^n \\times 5^m` produce a finite expansion, e.g. :math:`\\ ^1 / _2 = 0.5` |
|
|
|
|
41
|
|
|
(non-recurring) |
42
|
|
|
2. Prime divisors :math:`d` that are co-prime with :math:`2` and :math:`5` produce an infinite expansion |
|
|
|
|
43
|
|
|
3. Multiples of prime divisors :math:`d` that are divisible by :math:`2` or :math:`5` produce infinite expansion with a |
|
|
|
|
44
|
|
|
non-recurring prefix |
45
|
|
|
|
46
|
|
|
.. note:: the cycle produced by numbers of the third class are actually rotations of the cycles produced by their prime |
|
|
|
|
47
|
|
|
divisor. |
48
|
|
|
|
49
|
|
|
.. math:: |
50
|
|
|
|
51
|
|
|
\\ ^1 / _7 &= 0.(142857) \\\\ |
52
|
|
|
\\ ^1 / _{14} &= 0.0(714285) |
53
|
|
|
|
54
|
|
|
Observe that the cycles are rotations of one-another and that :math:`7` is a prime divisor of :math:`14`. |
|
|
|
|
55
|
|
|
|
56
|
|
|
Therefore, we must only consider prime divisors that are co-prime with :math:`2` and :math:`5`. |
57
|
|
|
|
58
|
|
|
Interestingly, the cycle length of such a divisor :math:`p` in the decimal representation of :math:`\\ ^1 / _p` is the |
|
|
|
|
59
|
|
|
multiplicative order of :math:`10 \\mod p`. That is, the cycle length is the minimum :math:`k` s.t. |
60
|
|
|
:math:`10^k = 1 \\mod p`. |
61
|
|
|
|
62
|
|
|
Solution Implementation |
63
|
|
|
####################### |
64
|
|
|
|
65
|
|
|
.. literalinclude:: ../../solutions/problem26.py |
66
|
|
|
:language: python |
67
|
|
|
:lines: 70- |
68
|
|
|
""" |
69
|
|
|
|
70
|
|
|
from lib.grouptheory import multiplicative_order |
71
|
|
|
from lib.sequence import Primes |
72
|
|
|
|
73
|
|
|
|
74
|
|
|
def solve(): |
75
|
|
|
""" Compute the answer to Project Euler's problem #26 """ |
76
|
|
|
upper_bound = 1000 |
77
|
|
|
max_cycle_length = 0 |
78
|
|
|
answer = 0 |
79
|
|
|
primes = filter(lambda _p: _p not in [2, 5], Primes(upper_bound=upper_bound)) |
80
|
|
|
for p in primes: |
|
|
|
|
81
|
|
|
cycle_length = multiplicative_order(10, p) |
82
|
|
|
if cycle_length > max_cycle_length: |
83
|
|
|
max_cycle_length = cycle_length |
84
|
|
|
answer = p |
85
|
|
|
return answer |
86
|
|
|
|
87
|
|
|
|
88
|
|
|
expected_answer = 983 |
|
|
|
|
89
|
|
|
|
This check looks for lines that are too long. You can specify the maximum line length.