Jetzt geht es beinahe schon Schlag auf Schlag: nach der Vorstellung der Lösung des achten folgt sofort die Lösung des neunten Problems. Das neunte Projecteuler-Problem beschäftigt sich mit dem Satz von Pythagoras und der Bildung von sogenannten Pythagoras-Tripeln. Wie gewohnt, erfolgt auch diesmal die Lösung mit Python.
Problemvorstellung
Das neunte Projecteuler-Problem dreht sich um den Satz von Pythagoras, welcher eine Aussage über die Seitenlängen eines rechtwinkligen Dreiecks liefert. Wie die meisten Schüler mehr oder weniger leidvoll erfahren haben, ergibt sich aus der Addition der Quadrate der zwei kürzeren Seiten, der Katheten, eines rechtwinkligen Dreiecks genau das Quadrat der längsten Seite, der Hypotenuse. Dass der Satz des Pythagoras auch heute noch bei Schülern sehr gefragt ist, lässt sich auf gutefrage.net nachlesen.
Ist nun die Länge der zwei Katheten und der Hypotenuse eines Dreiecks durch natürliche Zahlen (ganze Zahlen) beschreibbar, so bezeichnet man die drei Zahlen als pythagoreisches Tripel.
In dem neunten Projecteuler-Problem geht es darum, ein bestimmtes pythagoreisches Tripel zu finden. Dieses Tripel soll folgende Bedingungen erfüllen:
a + b + c = 1000,a < b < cund natürlicha^2 + b^2 = c^2
So viel sei zur Aufgabenstellung angemerkt.
Obwohl der Satz des Pythagoras eine elementare Unterrichtseinheit in der Schule darstellt, haben zum heutigen Zeitpunkt trotzdem nur 52711 der insgesamt 114860 Projecteuler-Teilnehmer die Aufgabe mit Erfolg gelöst und das richtige Ergebnis eingegeben.
Als Ergebnis werden übrigens nicht die drei Zahlen a, b, c erwartet, sondern ihr Produkt: a * b * c.
Problemeingrenzung
Geht man ganz unbedarft an das Problem heran, kommt man schnell auf die Lösung, einfach alle Zahlen für a und b einzusetzen, die die Bedingung a < b erfüllen. Dann muss die Hypotenuse errechnet werden. Was noch bleibt, ist zu testen, ob die Summe der drei Zahlen auch wirklich 1000 ergibt.
Damit hätte man zwei for-Schleifen und eine if-Abfrage und natürlich die Lösung des Problems. Eine elegante Lösung ist jedoch etwas anderes!
Ebenso unbedarft kann das Problem nur ein wenig genauer angeschaut werden. Ein Quäntchen Glück vorausgesetzt, erkennt man dabei, dass man bei drei Unbekannten genau zwei Gleichungen gegeben hat. Dies kann ausgenutzt werden, um die Lösung etwas komplizierter erscheinen zu lassen.
Dabei lässt sich zum Beispiel die erste Bedingung a + b + c = 1000 nach c auflösen und in die dritte einsetzen:
a + b + c = N
c = N - a - b
a^2 + b^2 - N^2 - 2*N*(a+b) - (a+b)^2 = 0
Die letzte Gleichung kann nun nach zum Beispiel b aufgelöst werden:
b = (0.5*N^2 - N*a)/(N - a)
Das Auflösen nach b lässt sich über die zweite Bedingung motivieren. Wenn wir nun Zahlen von 1 ausgehend für a einsetzen, dann wird die zweite Bedingung immer erfüllt bleiben.
Damit müssen wir nur noch die Zahlen für a vorgeben und testen, ob der Quotient eine natürliche Zahl ergibt.
Weiter wollen wir das Problem nicht mehr mit mathematischem Hintergrund aufblasen und gehen zur Lösung mit Python über.
Problemlösung
Abgesehen davon, dass dieses Problem eigentlich keiner Implementierung in einer Programmiersprache bedarf, wenn die Informationen zur Erzeugung eines pythagoreischen Tripels ausgenutzt werden, ist es wohl eines der kürzesten Lösungen, die ich im Rahmen dieser Serie bisher vorgestellt habe.
def search(a,N):
found = 0
while (found == False):
for i in a:
num = 0.5*N*N - N * i
denom = N - i
if (num%denom == 0.0):
found = 1
result = np.array([i,num/denom])
return result
N = 1000.0
aa = np.arange(int(N)/3)
erg = search(aa,N)
a = erg[0]
b = erg[1]
c = N-a-b
print(a,b,c,a*b*c)
Innerhalb dieser Zeilen habe ich die wenigen Gedanken aus der Problemeingrenzung verarbeitet. Der aufmerksame Leser wird gemerkt haben, dass noch eine zusätzliche Vereinfachung im Code berücksichtigt wurde.
Aufgrund der gegebenen Bedingungen wurde für a ein etwas kleinerer Suchbereich von maximal bis 300 eingestellt. Gehen wir von einem Extremfall aus:
a = 300
b = 301
a^2 + b^2 = c^2 = 180601
=> c = 424.972
Prüfen wir die erste Bedingung, so finden wir, dass die Summe bereits ca. 1026 beträgt. Das ist schon zu viel.
Lässt man sich nun das Ergebnis berechnen, so erhält man folgende Ausgabe:
(200.0, 375.0, 425.0, 31875000.0)
Damit wäre die gesuchte Zahl: 31875000.
Schlusswort
Ich gebe zu, dass der Lösungsvorschlag nicht der Weisheit letzter Schluss ist, doch für dieses Problem funktioniert er gut und zuverlässig. Die Grenzen, die Projecteuler vorgibt, werden nicht annähernd erreicht.
Natürlich wäre ich daher besonders froh, den einen oder anderen Lösungsvorschlag in den Kommentaren zu sehen
.
Artikel aus der selben Kategorie:
Meinungsfreiheit für alle!

Es gibt noch keine Kommentare zu “Projecteuler: Lösung zu Problem 9”.
Jede Meinung ist willkommen!