Pythagoras Zahlentripel ohne Wiederholung

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
reece
User
Beiträge: 2
Registriert: Freitag 3. Mai 2019, 11:30

Liebes Forum,

Ich habe eine Funktion kreiert, die alle Pythagoras Zahlentripel bis n ausgeben soll. Wie bekomme ich es nun hin, dass diese Tripel ohne Wiederholungen ausgegeben werden? dh. nicht [(4, 3, 5), (3, 4, 5),...], sondern nur eins der Tripel.

Einen schönen Tag noch,
Reece

Code: Alles auswählen

def pythtriples(n):
    list = []
    for c in range(1, n):
        for b in range(1, n):
            for a in range(1, n):
                if (a ** 2) + (b ** 2) == (c ** 2):
                    list.append((a, b, c))
    return list
Benutzeravatar
ThomasL
User
Beiträge: 1378
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

müssen alle Schleifen bei 1 anfangen?
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
reece
User
Beiträge: 2
Registriert: Freitag 3. Mai 2019, 11:30

Hallo Thomas,

Nein, die Schleife kann auch bei 0 anfangen.
Benutzeravatar
__blackjack__
User
Beiträge: 14044
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@reece: Das wären dann ja noch *mehr* Schleifendurchläufe und offensichtlich wirst Du damit nicht die Wiederholungen los. Müssen alle Schleifen bei 0 oder 1 anfangen? Müssen alle Schleifen bei einem festen Wert anfangen?
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Sirius3
User
Beiträge: 18270
Registriert: Sonntag 21. Oktober 2012, 17:20

@reece: die Zahlen müssen größer als 0 sein, sonst hättest Du ja keine Zahlentripel mehr, sondern nur noch ein Duo. Und die Fragen sollen Dich der Lösung näher bringen.
So dass Du zum Schluß nicht nur keine Dopplung mehr hast, sondern auch nur noch einen Bruchteil der Schleifendurchgänge und Idealerweise auch einen Iterator, bei dem Du das Ende gar nicht mehr angeben mußt.
nezzcarth
User
Beiträge: 1760
Registriert: Samstag 16. April 2011, 12:47

Hier mal eine Variante für einen Iterator, der nicht alle Tripel berechnet, sondern nur einen der Untertypen:

Code: Alles auswählen

In [1]: from itertools import count                                                                                                                                                                                                                               

In [2]: def iter_stifel_triples(): 
   ...:     for p, q in zip(count(1), count(3, 2)): 
   ...:         a = q 
   ...:         b = p + p*q 
   ...:         c = max(a, b) + 1 
   ...:         yield a, b, c 
   ...:                                                                                                                                                       

In [3]: for _, triples in zip(range(10), iter_stifel_triples()): 
   ...:     print('{}² + {}² = {}²'.format(*triples)) 
   ...:                                                                                                                                                       
3² + 4² = 5²
5² + 12² = 13²
7² + 24² = 25²
9² + 40² = 41²
11² + 60² = 61²
13² + 84² = 85²
15² + 112² = 113²
17² + 144² = 145²
19² + 180² = 181²
21² + 220² = 221²
Mir war nicht klar, wie viele verschiedene Verfahren es dafür gibt. :)
Benutzeravatar
__blackjack__
User
Beiträge: 14044
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@nezzcarth: Anstelle des `zip()` würde sich `itertools.islice()` anbieten. Und was in der Schleife `triples` heisst ist nur ein `tripel`.
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
nezzcarth
User
Beiträge: 1760
Registriert: Samstag 16. April 2011, 12:47

Danke, __blackjack__ :) :

Code: Alles auswählen

In [1]: from itertools import count, islice                                                                                                                   

In [2]: def iter_ozanam_triples(): 
   ...:     for n in count(1): 
   ...:         p = 4 * n + 3 
   ...:         q = p + 1 
   ...:         a = p + n * q 
   ...:         b = q 
   ...:         c = max(a, b) + 2 
   ...:         yield a, b, c 
   ...:                                                                                                                                                       

In [3]: for triple in islice(iter_ozanam_triples(), 10): 
   ...:     print('{}² + {}² = {}²'.format(*triple)) 
   ...:                                                                                                                                                       
15² + 8² = 17²
35² + 12² = 37²
63² + 16² = 65²
99² + 20² = 101²
143² + 24² = 145²
195² + 28² = 197²
255² + 32² = 257²
323² + 36² = 325²
399² + 40² = 401²
483² + 44² = 485²
Benutzeravatar
__blackjack__
User
Beiträge: 14044
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@reece: Deinen Ansatz könnte man ohne Wiederholungen auch mit *einer* Schleife und `itertools.combinations()` lösen:

Code: Alles auswählen

from itertools import combinations


def pythtriples(n):
    result = list()
    for a, b, c in combinations(range(n), 3):
        if a**2 + b**2 == c**2:
            result.append((a, b, c))
    return result
Oder auch als „list comprehension“ ausgedrückt:

Code: Alles auswählen

def pythtriples(n):
    return [
        (a, b, c)
        for a, b, c in combinations(range(n), 3)
        if a**2 + b**2 == c**2
    ]
„A life is like a garden. Perfect moments can be had, but not preserved, except in memory. LLAP” — Leonard Nimoy's last tweet.
Antworten