Skip to content

Commit f8c1a3b

Browse files
fpringlegithub-actions
authored andcommitted
Add solution for Project Euler problem 107 (TheAlgorithms#4066)
* Added solution for Project Euler problem 107 * Doctests and better variable names * Type hints * Small edits * Forward reference for typing hint * updating DIRECTORY.md Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com>
1 parent cbb2d56 commit f8c1a3b

File tree

5 files changed

+178
-0
lines changed

5 files changed

+178
-0
lines changed

DIRECTORY.md

+3
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,7 @@
499499
* [Minimum Cut](https://github.com/TheAlgorithms/Python/blob/master/networking_flow/minimum_cut.py)
500500

501501
## Neural Network
502+
* [2 Hidden Layers Neural Network](https://github.com/TheAlgorithms/Python/blob/master/neural_network/2_hidden_layers_neural_network.py)
502503
* [Back Propagation Neural Network](https://github.com/TheAlgorithms/Python/blob/master/neural_network/back_propagation_neural_network.py)
503504
* [Convolution Neural Network](https://github.com/TheAlgorithms/Python/blob/master/neural_network/convolution_neural_network.py)
504505
* [Perceptron](https://github.com/TheAlgorithms/Python/blob/master/neural_network/perceptron.py)
@@ -748,6 +749,8 @@
748749
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_101/sol1.py)
749750
* Problem 102
750751
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_102/sol1.py)
752+
* Problem 107
753+
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_107/sol1.py)
751754
* Problem 112
752755
* [Sol1](https://github.com/TheAlgorithms/Python/blob/master/project_euler/problem_112/sol1.py)
753756
* Problem 113

project_euler/problem_107/__init__.py

Whitespace-only changes.
+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
-,-,-,427,668,495,377,678,-,177,-,-,870,-,869,624,300,609,131,-,251,-,-,-,856,221,514,-,591,762,182,56,-,884,412,273,636,-,-,774
2+
-,-,262,-,-,508,472,799,-,956,578,363,940,143,-,162,122,910,-,729,802,941,922,573,531,539,667,607,-,920,-,-,315,649,937,-,185,102,636,289
3+
-,262,-,-,926,-,958,158,647,47,621,264,81,-,402,813,649,386,252,391,264,637,349,-,-,-,108,-,727,225,578,699,-,898,294,-,575,168,432,833
4+
427,-,-,-,366,-,-,635,-,32,962,468,893,854,718,427,448,916,258,-,760,909,529,311,404,-,-,588,680,875,-,615,-,409,758,221,-,-,76,257
5+
668,-,926,366,-,-,-,250,268,-,503,944,-,677,-,727,793,457,981,191,-,-,-,351,969,925,987,328,282,589,-,873,477,-,-,19,450,-,-,-
6+
495,508,-,-,-,-,-,765,711,819,305,302,926,-,-,582,-,861,-,683,293,-,-,66,-,27,-,-,290,-,786,-,554,817,33,-,54,506,386,381
7+
377,472,958,-,-,-,-,-,-,120,42,-,134,219,457,639,538,374,-,-,-,966,-,-,-,-,-,449,120,797,358,232,550,-,305,997,662,744,686,239
8+
678,799,158,635,250,765,-,-,-,35,-,106,385,652,160,-,890,812,605,953,-,-,-,79,-,712,613,312,452,-,978,900,-,901,-,-,225,533,770,722
9+
-,-,647,-,268,711,-,-,-,283,-,172,-,663,236,36,403,286,986,-,-,810,761,574,53,793,-,-,777,330,936,883,286,-,174,-,-,-,828,711
10+
177,956,47,32,-,819,120,35,283,-,50,-,565,36,767,684,344,489,565,-,-,103,810,463,733,665,494,644,863,25,385,-,342,470,-,-,-,730,582,468
11+
-,578,621,962,503,305,42,-,-,50,-,155,519,-,-,256,990,801,154,53,474,650,402,-,-,-,966,-,-,406,989,772,932,7,-,823,391,-,-,933
12+
-,363,264,468,944,302,-,106,172,-,155,-,-,-,380,438,-,41,266,-,-,104,867,609,-,270,861,-,-,165,-,675,250,686,995,366,191,-,433,-
13+
870,940,81,893,-,926,134,385,-,565,519,-,-,313,851,-,-,-,248,220,-,826,359,829,-,234,198,145,409,68,359,-,814,218,186,-,-,929,203,-
14+
-,143,-,854,677,-,219,652,663,36,-,-,313,-,132,-,433,598,-,-,168,870,-,-,-,128,437,-,383,364,966,227,-,-,807,993,-,-,526,17
15+
869,-,402,718,-,-,457,160,236,767,-,380,851,132,-,-,596,903,613,730,-,261,-,142,379,885,89,-,848,258,112,-,900,-,-,818,639,268,600,-
16+
624,162,813,427,727,582,639,-,36,684,256,438,-,-,-,-,539,379,664,561,542,-,999,585,-,-,321,398,-,-,950,68,193,-,697,-,390,588,848,-
17+
300,122,649,448,793,-,538,890,403,344,990,-,-,433,596,539,-,-,73,-,318,-,-,500,-,968,-,291,-,-,765,196,504,757,-,542,-,395,227,148
18+
609,910,386,916,457,861,374,812,286,489,801,41,-,598,903,379,-,-,-,946,136,399,-,941,707,156,757,258,251,-,807,-,-,-,461,501,-,-,616,-
19+
131,-,252,258,981,-,-,605,986,565,154,266,248,-,613,664,73,-,-,686,-,-,575,627,817,282,-,698,398,222,-,649,-,-,-,-,-,654,-,-
20+
-,729,391,-,191,683,-,953,-,-,53,-,220,-,730,561,-,946,686,-,-,389,729,553,304,703,455,857,260,-,991,182,351,477,867,-,-,889,217,853
21+
251,802,264,760,-,293,-,-,-,-,474,-,-,168,-,542,318,136,-,-,-,-,392,-,-,-,267,407,27,651,80,927,-,974,977,-,-,457,117,-
22+
-,941,637,909,-,-,966,-,810,103,650,104,826,870,261,-,-,399,-,389,-,-,-,202,-,-,-,-,867,140,403,962,785,-,511,-,1,-,707,-
23+
-,922,349,529,-,-,-,-,761,810,402,867,359,-,-,999,-,-,575,729,392,-,-,388,939,-,959,-,83,463,361,-,-,512,931,-,224,690,369,-
24+
-,573,-,311,351,66,-,79,574,463,-,609,829,-,142,585,500,941,627,553,-,202,388,-,164,829,-,620,523,639,936,-,-,490,-,695,-,505,109,-
25+
856,531,-,404,969,-,-,-,53,733,-,-,-,-,379,-,-,707,817,304,-,-,939,164,-,-,616,716,728,-,889,349,-,963,150,447,-,292,586,264
26+
221,539,-,-,925,27,-,712,793,665,-,270,234,128,885,-,968,156,282,703,-,-,-,829,-,-,-,822,-,-,-,736,576,-,697,946,443,-,205,194
27+
514,667,108,-,987,-,-,613,-,494,966,861,198,437,89,321,-,757,-,455,267,-,959,-,616,-,-,-,349,156,339,-,102,790,359,-,439,938,809,260
28+
-,607,-,588,328,-,449,312,-,644,-,-,145,-,-,398,291,258,698,857,407,-,-,620,716,822,-,-,293,486,943,-,779,-,6,880,116,775,-,947
29+
591,-,727,680,282,290,120,452,777,863,-,-,409,383,848,-,-,251,398,260,27,867,83,523,728,-,349,293,-,212,684,505,341,384,9,992,507,48,-,-
30+
762,920,225,875,589,-,797,-,330,25,406,165,68,364,258,-,-,-,222,-,651,140,463,639,-,-,156,486,212,-,-,349,723,-,-,186,-,36,240,752
31+
182,-,578,-,-,786,358,978,936,385,989,-,359,966,112,950,765,807,-,991,80,403,361,936,889,-,339,943,684,-,-,965,302,676,725,-,327,134,-,147
32+
56,-,699,615,873,-,232,900,883,-,772,675,-,227,-,68,196,-,649,182,927,962,-,-,349,736,-,-,505,349,965,-,474,178,833,-,-,555,853,-
33+
-,315,-,-,477,554,550,-,286,342,932,250,814,-,900,193,504,-,-,351,-,785,-,-,-,576,102,779,341,723,302,474,-,689,-,-,-,451,-,-
34+
884,649,898,409,-,817,-,901,-,470,7,686,218,-,-,-,757,-,-,477,974,-,512,490,963,-,790,-,384,-,676,178,689,-,245,596,445,-,-,343
35+
412,937,294,758,-,33,305,-,174,-,-,995,186,807,-,697,-,461,-,867,977,511,931,-,150,697,359,6,9,-,725,833,-,245,-,949,-,270,-,112
36+
273,-,-,221,19,-,997,-,-,-,823,366,-,993,818,-,542,501,-,-,-,-,-,695,447,946,-,880,992,186,-,-,-,596,949,-,91,-,768,273
37+
636,185,575,-,450,54,662,225,-,-,391,191,-,-,639,390,-,-,-,-,-,1,224,-,-,443,439,116,507,-,327,-,-,445,-,91,-,248,-,344
38+
-,102,168,-,-,506,744,533,-,730,-,-,929,-,268,588,395,-,654,889,457,-,690,505,292,-,938,775,48,36,134,555,451,-,270,-,248,-,371,680
39+
-,636,432,76,-,386,686,770,828,582,-,433,203,526,600,848,227,616,-,217,117,707,369,109,586,205,809,-,-,240,-,853,-,-,-,768,-,371,-,540
40+
774,289,833,257,-,381,239,722,711,468,933,-,-,17,-,-,148,-,-,853,-,-,-,-,264,194,260,947,-,752,147,-,-,343,112,273,344,680,540,-

project_euler/problem_107/sol1.py

+128
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
"""
2+
The following undirected network consists of seven vertices and twelve edges
3+
with a total weight of 243.
4+
5+
The same network can be represented by the matrix below.
6+
7+
A B C D E F G
8+
A - 16 12 21 - - -
9+
B 16 - - 17 20 - -
10+
C 12 - - 28 - 31 -
11+
D 21 17 28 - 18 19 23
12+
E - 20 - 18 - - 11
13+
F - - 31 19 - - 27
14+
G - - - 23 11 27 -
15+
16+
However, it is possible to optimise the network by removing some edges and still
17+
ensure that all points on the network remain connected. The network which achieves
18+
the maximum saving is shown below. It has a weight of 93, representing a saving of
19+
243 - 93 = 150 from the original network.
20+
21+
Using network.txt (right click and 'Save Link/Target As...'), a 6K text file
22+
containing a network with forty vertices, and given in matrix form, find the maximum
23+
saving which can be achieved by removing redundant edges whilst ensuring that the
24+
network remains connected.
25+
26+
Solution:
27+
We use Prim's algorithm to find a Minimum Spanning Tree.
28+
Reference: https://en.wikipedia.org/wiki/Prim%27s_algorithm
29+
"""
30+
31+
import os
32+
from typing import Dict, List, Mapping, Set, Tuple
33+
34+
EdgeT = Tuple[int, int]
35+
36+
37+
class Graph:
38+
"""
39+
A class representing an undirected weighted graph.
40+
"""
41+
42+
def __init__(self, vertices: Set[int], edges: Mapping[EdgeT, int]) -> None:
43+
self.vertices: Set[int] = vertices
44+
self.edges: Dict[EdgeT, int] = {
45+
(min(edge), max(edge)): weight for edge, weight in edges.items()
46+
}
47+
48+
def add_edge(self, edge: EdgeT, weight: int) -> None:
49+
"""
50+
Add a new edge to the graph.
51+
>>> graph = Graph({1, 2}, {(2, 1): 4})
52+
>>> graph.add_edge((3, 1), 5)
53+
>>> sorted(graph.vertices)
54+
[1, 2, 3]
55+
>>> sorted([(v,k) for k,v in graph.edges.items()])
56+
[(4, (1, 2)), (5, (1, 3))]
57+
"""
58+
self.vertices.add(edge[0])
59+
self.vertices.add(edge[1])
60+
self.edges[(min(edge), max(edge))] = weight
61+
62+
def prims_algorithm(self) -> "Graph":
63+
"""
64+
Run Prim's algorithm to find the minimum spanning tree.
65+
Reference: https://en.wikipedia.org/wiki/Prim%27s_algorithm
66+
>>> graph = Graph({1,2,3,4},{(1,2):5, (1,3):10, (1,4):20, (2,4):30, (3,4):1})
67+
>>> mst = graph.prims_algorithm()
68+
>>> sorted(mst.vertices)
69+
[1, 2, 3, 4]
70+
>>> sorted(mst.edges)
71+
[(1, 2), (1, 3), (3, 4)]
72+
"""
73+
subgraph: Graph = Graph({min(self.vertices)}, {})
74+
min_edge: EdgeT
75+
min_weight: int
76+
edge: EdgeT
77+
weight: int
78+
79+
while len(subgraph.vertices) < len(self.vertices):
80+
min_weight = max(self.edges.values()) + 1
81+
for edge, weight in self.edges.items():
82+
if (edge[0] in subgraph.vertices) ^ (edge[1] in subgraph.vertices):
83+
if weight < min_weight:
84+
min_edge = edge
85+
min_weight = weight
86+
87+
subgraph.add_edge(min_edge, min_weight)
88+
89+
return subgraph
90+
91+
92+
def solution(filename: str = "p107_network.txt") -> int:
93+
"""
94+
Find the maximum saving which can be achieved by removing redundant edges
95+
whilst ensuring that the network remains connected.
96+
>>> solution("test_network.txt")
97+
150
98+
"""
99+
script_dir: str = os.path.abspath(os.path.dirname(__file__))
100+
network_file: str = os.path.join(script_dir, filename)
101+
adjacency_matrix: List[List[str]]
102+
edges: Dict[EdgeT, int] = dict()
103+
data: List[str]
104+
edge1: int
105+
edge2: int
106+
107+
with open(network_file, "r") as f:
108+
data = f.read().strip().split("\n")
109+
110+
adjaceny_matrix = [line.split(",") for line in data]
111+
112+
for edge1 in range(1, len(adjaceny_matrix)):
113+
for edge2 in range(edge1):
114+
if adjaceny_matrix[edge1][edge2] != "-":
115+
edges[(edge2, edge1)] = int(adjaceny_matrix[edge1][edge2])
116+
117+
graph: Graph = Graph(set(range(len(adjaceny_matrix))), edges)
118+
119+
subgraph: Graph = graph.prims_algorithm()
120+
121+
initial_total: int = sum(graph.edges.values())
122+
optimal_total: int = sum(subgraph.edges.values())
123+
124+
return initial_total - optimal_total
125+
126+
127+
if __name__ == "__main__":
128+
print(f"{solution() = }")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
-,16,12,21,-,-,-
2+
16,-,-,17,20,-,-
3+
12,-,-,28,-,31,-
4+
21,17,28,-,18,19,23
5+
-,20,-,18,-,-,11
6+
-,-,31,19,-,-,27
7+
-,-,-,23,11,27,-

0 commit comments

Comments
 (0)