-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathproblem75.py
More file actions
79 lines (71 loc) · 2.29 KB
/
problem75.py
File metadata and controls
79 lines (71 loc) · 2.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
"""
Singular Integer Right Triangles
Project Euler Problem #75
by Muaz Siddiqui
It turns out that 12 cm is the smallest length of wire that can be bent to form an
integer sided right angle triangle in exactly one way, but there are many more
examples.
12 cm: (3,4,5)
24 cm: (6,8,10)
30 cm: (5,12,13)
36 cm: (9,12,15)
40 cm: (8,15,17)
48 cm: (12,16,20)
In contrast, some lengths of wire, like 20 cm, cannot be bent to form an integer
sided right angle triangle, and other lengths allow more than one solution to be
found; for example, using 120 cm it is possible to form exactly three different
integer sided right angle triangles.
120 cm: (30,40,50), (20,48,52), (24,45,51)
Given that L is the length of the wire, for how many values of L ≤ 1,500,000 can
exactly one integer sided right angle triangle be formed?
"""
from euler_helpers import timeit
import numpy as np
"""
We generate all the primitive Pythagorean triples and check their multiples up to
1,500,000 by creating a primitive tree with the root at (3,4,5) and by using
F.J.M Barnings matrices to generate 3 children.
"""
a = np.matrix('1 -2 2; 2 -1 2; 2 -2 3')
b = np.matrix('1 2 2; 2 1 2; 2 2 3')
c = np.matrix('-1 2 2; -2 1 2; -2 2 3')
def generate_children(triple):
root = np.array(triple)
child1 = a.dot(root).tolist()
child2 = b.dot(root).tolist()
child3 = c.dot(root).tolist()
return [child1[0], child2[0], child3[0]]
def make_primitive_tree(limit):
tree = [[3,4,5]]
leaves = generate_children([3,4,5])
found = False
next = []
while True:
for leaf in leaves:
perimeter = sum(leaf)
if perimeter <= limit:
tree.append(leaf)
next.extend(generate_children(leaf))
else:
found = True
if found:
return tree
leaves = next
@timeit
def answer():
limit = 1500000
primitive_triples = make_primitive_tree(limit)
wires = [0] * (limit + 1)
count = 0
# for each triple check all it's
for triple in primitive_triples:
length = sum(triple)
wire = length
while(wire <= limit):
wires[wire] += 1
if wires[wire] == 1:
count += 1
if wires[wire] == 2:
count -= 1
wire += length
return count