Skip to content

Commit f859634

Browse files
committed
Solve Project Euler 61
1 parent 5827aac commit f859634

File tree

2 files changed

+133
-0
lines changed

2 files changed

+133
-0
lines changed

project_euler/problem_061/__init__.py

Whitespace-only changes.

project_euler/problem_061/sol1.py

+133
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
"""
2+
Project Euler Problem 61: https://projecteuler.net/problem=61
3+
4+
Triangle, square, pentagonal, hexagonal, heptagonal, and octagonal numbers are a
5+
ll figurate (polygonal) numbers and are generated by the following formulae:
6+
7+
Triangle P(3,n)=n(n+1)/2 1, 3, 6, 10, 15, ...
8+
Square P(4,n)=n^2 1, 4, 9, 16, 25, ...
9+
Pentagonal P(5,n)=n(3n-1)/2 1, 5, 12, 22, 35, ...
10+
Hexagonal P(6,n)=n(2n-1) 1, 6, 15, 28, 45, ...
11+
Heptagonal P(7,n)=n(5n-3)/2 1, 7, 18, 34, 55, ...
12+
Octagonal P(8,n)=n(3n-2) 1, 8, 21, 40, 65, ...
13+
14+
The ordered set of three 4-digit numbers: 8128, 2882, 8281, has
15+
three interesting properties.
16+
17+
1. The set is cyclic, in that the last two digits of each number is the first two
18+
digits of the next number (including the last number with the first).
19+
2. Each polygonal type: triangle (P(3,127) = 8128), square (P(4,91) = 8281), and
20+
pentagonal (P(5,44) = 2882),is represented by a different number in the set.
21+
3. This is the only set of 4-digit numbers with this property.
22+
23+
Find the sum of the only ordered set of six cyclic 4-digit numbers for which each
24+
polygonal type: triangle, square, pentagonal, hexagonal, heptagonal, and octagonal,
25+
is represented by a different number in the set.
26+
"""
27+
28+
from itertools import permutations
29+
30+
31+
def solution() -> int:
32+
"""
33+
For this task is good to know some basics of combinatorial analysis, and
34+
know how to solve a quadratic equation.
35+
36+
On the first sight we can see that number of possibilities is quite big. But
37+
from the description of the task, we can get to know that:
38+
1. We are only looking for 4 digits numbers
39+
2. All numbers are naturals numbers.
40+
41+
By knowing that we can try to limit range of numbers that
42+
we will be looking for specific formulae.
43+
44+
We need to solve some quadratic equation to get that range:
45+
1. Triangle:
46+
Lower: n(n+1)/2 = 1000 // 45
47+
48+
######
49+
We get two solutions one positive, one negative. From previous observation
50+
we take positive one, and round it down or up, so
51+
we get maximum 4 digit result. We doing that for rest of formulae.
52+
######
53+
54+
Upper: n(n+1)/2 = 10000 // 140
55+
56+
2. Square:
57+
Lower: n^2 = 1000 // 32
58+
Upper: n^2 = 9999 // 99
59+
3. Pentagonal:
60+
Lower: n(3n-1)/2 = 1000 // 26
61+
Upper: n(3n-1)/2 = 9999 // 81
62+
4. Hexagonal:
63+
Lower: n(2n-1) = 1000 // 23
64+
Upper: n(2n-1) = 9999 // 70
65+
5. Heptagonal:
66+
Lower: n(5n-3)/2 = 1000 // 21
67+
Upper: n(5n-3)/2 = 9999 // 63
68+
6. Octagonal
69+
Lower: n(3n-2) = 1000 // 19
70+
Upper: n(3n-2) = 9999 // 59
71+
72+
Then we just need to check if the last two digits of each number
73+
is the first two digits of the next number, and if they are not the same.
74+
75+
I created a function is_cyclic to check if it the last two digits of number is
76+
the first two digits of the next number.
77+
78+
Then program iterates through all permutations of polygonal types. (itertools).
79+
For each permutation, it iterates through the corresponding lists of
80+
polygonal numbers stored in the polygonals dictionary.
81+
82+
At the end if 6 polygonal numbers form a cyclic set, it returns the sum of them.
83+
"""
84+
85+
triangle = [int(x * (x + 1) * 0.5) for x in range(45, 141)]
86+
87+
square = [int(x * x) for x in range(32, 100)]
88+
89+
pentagonal = [int(x * (3 * x - 1) * 0.5) for x in range(26, 82)]
90+
91+
hexagonal = [int(x * (2 * x - 1)) for x in range(23, 71)]
92+
93+
heptagonal = [int(x * (5 * x - 3) * 0.5) for x in range(21, 64)]
94+
95+
octagonal = [int(x * (3 * x - 2)) for x in range(19, 60)]
96+
97+
polygonals = {
98+
3: triangle,
99+
4: square,
100+
5: pentagonal,
101+
6: hexagonal,
102+
7: heptagonal,
103+
8: octagonal,
104+
}
105+
106+
for perm in permutations(range(3, 9)):
107+
for t in polygonals[perm[0]]:
108+
for s in polygonals[perm[1]]:
109+
if not is_cyclic(t, s):
110+
continue
111+
for p in polygonals[perm[2]]:
112+
if not is_cyclic(s, p):
113+
continue
114+
for hx in polygonals[perm[3]]:
115+
if not is_cyclic(p, hx):
116+
continue
117+
for hp in polygonals[perm[4]]:
118+
if not is_cyclic(hx, hp):
119+
continue
120+
for o in polygonals[perm[5]]:
121+
if not is_cyclic(hp, o) or not is_cyclic(o, t):
122+
continue
123+
return sum([t, s, p, hx, hp, o])
124+
125+
return 0
126+
127+
128+
def is_cyclic(a: int, b: int):
129+
return str(a)[2:] == str(b)[:2]
130+
131+
132+
if __name__ == "__main__":
133+
print(f"{solution() = }")

0 commit comments

Comments
 (0)