Skip to content

Commit 26f2df7

Browse files
Enkryppoyea
andauthored
Add sol for P104 Project Euler (TheAlgorithms#5257)
* Hacktoberfest: added sol for P104 Project Euler * bot requests resolved * pre-commit * Update sol.py * Update sol.py * remove trailing zeroes * Update sol.py * Update sol.py * Update sol.py Co-authored-by: John Law <[email protected]>
1 parent 4bd5494 commit 26f2df7

File tree

2 files changed

+137
-0
lines changed

2 files changed

+137
-0
lines changed

project_euler/problem_104/__init__.py

Whitespace-only changes.

project_euler/problem_104/sol.py

+137
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
"""
2+
Project Euler Problem 104 : https://projecteuler.net/problem=104
3+
4+
The Fibonacci sequence is defined by the recurrence relation:
5+
6+
Fn = Fn−1 + Fn−2, where F1 = 1 and F2 = 1.
7+
It turns out that F541, which contains 113 digits, is the first Fibonacci number
8+
for which the last nine digits are 1-9 pandigital (contain all the digits 1 to 9,
9+
but not necessarily in order). And F2749, which contains 575 digits, is the first
10+
Fibonacci number for which the first nine digits are 1-9 pandigital.
11+
12+
Given that Fk is the first Fibonacci number for which the first nine digits AND
13+
the last nine digits are 1-9 pandigital, find k.
14+
"""
15+
16+
17+
def check(number: int) -> bool:
18+
"""
19+
Takes a number and checks if it is pandigital both from start and end
20+
21+
22+
>>> check(123456789987654321)
23+
True
24+
25+
>>> check(120000987654321)
26+
False
27+
28+
>>> check(1234567895765677987654321)
29+
True
30+
31+
"""
32+
33+
check_last = [0] * 11
34+
check_front = [0] * 11
35+
36+
# mark last 9 numbers
37+
for x in range(9):
38+
check_last[int(number % 10)] = 1
39+
number = number // 10
40+
# flag
41+
f = True
42+
43+
# check last 9 numbers for pandigitality
44+
45+
for x in range(9):
46+
if not check_last[x + 1]:
47+
f = False
48+
if not f:
49+
return f
50+
51+
# mark first 9 numbers
52+
number = int(str(number)[:9])
53+
54+
for x in range(9):
55+
check_front[int(number % 10)] = 1
56+
number = number // 10
57+
58+
# check first 9 numbers for pandigitality
59+
60+
for x in range(9):
61+
if not check_front[x + 1]:
62+
f = False
63+
return f
64+
65+
66+
def check1(number: int) -> bool:
67+
"""
68+
Takes a number and checks if it is pandigital from END
69+
70+
>>> check1(123456789987654321)
71+
True
72+
73+
>>> check1(120000987654321)
74+
True
75+
76+
>>> check1(12345678957656779870004321)
77+
False
78+
79+
"""
80+
81+
check_last = [0] * 11
82+
83+
# mark last 9 numbers
84+
for x in range(9):
85+
check_last[int(number % 10)] = 1
86+
number = number // 10
87+
# flag
88+
f = True
89+
90+
# check last 9 numbers for pandigitality
91+
92+
for x in range(9):
93+
if not check_last[x + 1]:
94+
f = False
95+
return f
96+
97+
98+
def solution() -> int:
99+
"""
100+
Outputs the answer is the least Fibonacci number pandigital from both sides.
101+
>>> solution()
102+
329468
103+
"""
104+
105+
a = 1
106+
b = 1
107+
c = 2
108+
# temporary Fibonacci numbers
109+
110+
a1 = 1
111+
b1 = 1
112+
c1 = 2
113+
# temporary Fibonacci numbers mod 1e9
114+
115+
# mod m=1e9, done for fast optimisation
116+
tocheck = [0] * 1000000
117+
m = 1000000000
118+
119+
for x in range(1000000):
120+
c1 = (a1 + b1) % m
121+
a1 = b1 % m
122+
b1 = c1 % m
123+
if check1(b1):
124+
tocheck[x + 3] = 1
125+
126+
for x in range(1000000):
127+
c = a + b
128+
a = b
129+
b = c
130+
# perform check only if in tocheck
131+
if tocheck[x + 3] and check(b):
132+
return x + 3 # first 2 already done
133+
return -1
134+
135+
136+
if __name__ == "__main__":
137+
print(f"{solution() = }")

0 commit comments

Comments
 (0)