Pythagoreische Dreifachsequenz

33

Ein pythagoreisches Tripel besteht aus drei positiven ganzen Zahlen a, b und c, so dass a 2 + b 2 = c 2 . Ein solches Tripel wird üblicherweise geschrieben (a, b, c), und ein bekanntes Beispiel ist (3, 4, 5). Wenn (a, b, c) ein pythagoreisches Tripel ist, dann ist dies auch (ka, kb, kc) für eine positive ganze Zahl k. Ein primitives pythagoreisches Tripel ist eines, bei dem a, b und c Koprime sind .

Mit diesem Wissen können wir eine Sequenz erstellen, indem wir die kleinsten Längen von Tripeln miteinander verketten, wobei das nächste Element in der Sequenz die Hypotenuse (die größte Zahl) des kleinsten primitiven pythagoreischen Tripels ist, das das vorherige Element als das kleinste seiner Längen enthält.

Beginnen Sie mit dem kleinsten primitiven pythagoreischen Tripel (3, 4, 5). Die Sequenz beginnt mit 3und die Hypotenuse (das nächste Element in der Sequenz) ist 5. Dann finden Sie das kleinste primitive pythagoreische Tripel mit 5als Bein, und Sie erhalten (5, 12, 13). Also geht die Sequenz weiter mit 13.

Entweder geben Sie die Sequenz für immer aus, oder Sie nehmen eine Ganzzahleingabe nund geben die ersten nElemente der Sequenz aus, entweder null oder eins indiziert.

Sie müssen die Ausgabe mindestens durch und einschließlich 28455997unterstützen. Wenn jedoch das Limit des von Ihnen verwendeten Datentyps plötzlich angehoben wird, muss es für dieses neue Limit funktionieren. Sie können also eine Liste von Zahlen nicht hart codieren.

3
5
13
85
157
12325
90733
2449525
28455997
295742792965
171480834409967437
656310093705697045
1616599508725767821225590944157
4461691012090851100342993272805
115366949386695884000892071602798585632943213
12002377162350258332845595301471273220420939451301220405

OEIS A239381

Ähnliche Sequenzen (diese nicht ausgeben!):

mbomb007
quelle
Gibt es eine zeitliche Begrenzung?
Loovjo
@ Loovjo Nein, aber Sie sollten wissen / beweisen, dass Ihre Ausgabe korrekt ist. Es gibt einige ähnliche Sequenzen, bei denen sich die Ausgabe danach unterscheidet 12325.
mbomb007
Die ähnliche Sequenz, an die ich denke, unterscheidet sich nach 85... der nächsten Amtszeit 3613(können Sie sich vorstellen, was es noch ist?)
Neil
@Neil Eine schnelle Suche ergibt A053630 , die pythagoreische Spirale. Ich bezog mich jedoch auf die beiden in der Herausforderung, weil ich während der Arbeit an meiner Implementierung versehentlich diese beiden Sequenzen oder ähnliche erreicht habe.
mbomb007
1
Wäre ich wacher gewesen, hätte ich es einfach selbst nachschlagen können ...
Neil,

Antworten:

11

Jelly , 19 Bytes

o3ṄÆF*/€ŒPP€²+Ṛ$HṂß

Dank @ Dennis wurde ein Byte durch Umgestaltung in eine unendliche Sequenz gespeichert .

Nimmt keine Eingaben und Argumente entgegen und gibt die Sequenz unbegrenzt aus, indem jeder Term beim Berechnen gedruckt wird. Diese Methode verlangsamt sich, wenn die Zahlen größer werden, da sie von der Primfaktorisierung abhängt.

Probieren Sie es online!

Dies berechnet den nächsten Term, indem die Primärenergiefaktorisierung des aktuellen Terms berechnet wird. Für 12325 ist dies {5 2 , 17, 29}. Es gibt eine Variante von Euklids Formel zur Berechnung pythagoreischer Tripel { a , b , c },

Formel

wobei m > n und das Tripel primitiv ist, wenn m und n Koprime sind.

Um die nächste Primitivwurzel aus 12325 zu berechnen, finden Sie m und n so, dass mn = 12325 und wählen Sie m , n, so dass gcd ( m , n ) = 1. Generieren Sie dann alle Paare von m , n, indem Sie alle Teilmengen von {5 2 erstellen , 17, 29} und Finden des Produkts jeder dieser Untergruppen, die {1, 25, 17, 29, 425, 725, 493, 12325} sind. Teilen Sie dann 12325 durch jeden Wert und jedes Paar, sodass jedes Paar m , n ist . Berechnen Sie die Formel für c mit jedem Paar und nehmen Sie das Minimum von 90733.

  • Die vorherige Methode schlug zur Bestimmung des nächsten Terms nach 228034970321525477033478437478475683098735674620405573717049066152557390539189785244849203205 fehl. Die vorherige Methode wählte den letzten Wert als Faktor, wenn die richtige Wahl die dritte und letzte Primzahl war. Die neue Methode ist langsamer, funktioniert jedoch immer, da alle Paare von Koprimen auf die minimale Hypotenuse getestet werden.

Erläuterung

o3ṄÆF*/€ŒPP€²+Ṛ$HṂß  Main link. Input: 0 if none, else an integer P
o3                   Logical OR with 3, returns P if non-zero else 3
  Ṅ                  Println and pass the value
   ÆF                Factor into [prime, exponent] pairs
     */€             Reduce each pair using exponentation to get the prime powers
        ŒP           Powerset of those
          P€         Product of each
            ²        Square each
               $     Monadic chain
             +         Add vectorized with
              Ṛ        the reverse
                H    Halve
                 Ṃ   Minimum
                  ß  Call recursively on this value
Meilen
quelle
Wow, das geht wirklich schnell!
mbomb007
1
o3ṄÆfµṪ,P²SHßbei unendlicher ausgabe spart ein byte.
Dennis
5

Brachylog , 36 Bytes

3{@wB:?>:^a+~^=C:B:?:{$pd}ac#d,C:1&}

Probieren Sie es online!

Sie müssen warten, bis das Programm abgelaufen ist (1 Minute), bevor TIO den Ausgang spült. In SWI-Prologs REPL wird dies gedruckt, sobald es den Wert findet.

Dadurch wird die Sequenz für immer gedruckt.

Nach ein paar Minuten mit dem Offline-Interpreter von SWI-Prolog erhielt ich 90733nach 12325. Ich habe es nach diesem Punkt gestoppt.

Dies ist keine vollständige Bruteforce, da sie Einschränkungen verwendet, um pythagoreische Tripel zu finden, obwohl sie offensichtlich nicht für die Geschwindigkeit optimiert ist.

Erläuterung

3{                                 }    Call this predicate with 3 as Input
  @w                                    Write the Input followed by a line break
    B:?>                                B > Input
           +                            The sum...
        :^a                             ...of Input^2 with B^2...
            ~^                          ...must equal a number which is itself a square
              =C                        Assign a fitting value to that number and call it C
               C:B:?:{$pd}a             Get the lists of prime factors of C, B and Input
                                          without duplicates
                           c#d,         Concatenate into a single list; all values must be
                                          different
                               C:1&     Call recursively with C as Input
Tödlich
quelle
4

Perl, 73 Bytes

for($_=3;$_<1e9;$_=$a**2+$b**2){$a++until($b=($_+$a**2)**.5)==($b|0);say}

Alle pythagoreischen Dreiergruppen a²+b²=c²erfüllen a=r(m²-n²), b=2rmn, c=r(m²+n²)einige ganze Zahlen r,m,n. Wenn r=1und m,nKoprime sind, wobei genau eines durch 2 teilbar ist, dann a,b,cist es ein primitives Tripel, bei dem a,b,calle Koprime paarweise sind.

In diesem Sinne, da einige a, verwende ich einen Brute-Force - Algorithmus , um die kleinste zu berechnen , nso dass a²-n²ein Quadrat ist, nämlich . Dann cist gleich n²+m².

Gabriel Benamy
quelle
Mögliche Tippfehler in Ihrer Erklärung: Sie suchen , nso dass a+n²ein Quadrat ist.
Neil
2

Python 3, 178 Bytes

from math import*
p,n=[3,5],int(input())
while len(p)<n:
 for i in range(p[-1],p[-1]**2):
  v=sqrt(i**2+p[-1]**2)
  if v==int(v)and gcd(i,p[-1])==1:
   p+=[int(v)];break
print(p)

Dies ist im Grunde genommen nur ein Brute-Force-Algorithmus und daher sehr langsam. Die Anzahl der auszugebenden Terme wird als Eingabe verwendet.

Ich bin mir nicht hundertprozentig sicher, ob dieser Algorithmus korrekt ist. Das Programm überprüft das andere Bein bis zum ersten Bein im Quadrat.

Probieren Sie es auf repl.it! (Veraltet) (Bitte versuchen Sie es nicht mit Zahlen über 10, da dies sehr langsam sein wird.)

Loovjo
quelle
Sie können zu Python 3.5 wechseln und verwenden math.gcd. Verwenden Sie auch p+=[...]anstelle von p.append(...). Und <2statt ==1. Und das ifkann alles auf einer Linie sein.
mbomb007
1
Sie können immer noch die letzten 2 Verbesserungen vornehmen, die ich vorgeschlagen habe.
mbomb007
1
161 Bytes
Mr. Xcoder
Loovjo, spielst du deinen Code mit den Vorschlägen oder nicht?
mbomb007
2

MATL , 27 Bytes

Ii:"`I@Yyt1\~?3MZdZdq]}6MXI

Dies erzeugt die ersten Terme der Sequenz. Die Eingabe ist 0-basiert.

Der Code ist sehr ineffizient. Der Online-Compiler läuft bei Eingaben ab, die größer als sind 5. Die Eingabe 6dauerte anderthalb Minuten offline (und ergab den korrekten 90733sechsten Ausdruck).

Probieren Sie es online!

I            % Push 3 (predefined value of clipboard I)
i            % Input n
:"           % For each (i.e. execute n times)
  `          %   Do...while
    I        %     Push clipboard I. This is the latest term of the sequence
    @        %     Push iteration index, starting at 1
    Yy       %     Hypotenuse of those two values
    t1\      %     Duplicate. Decimal part
    ~?       %     If it is zero: we may have found the next term. But we still
             %     need to test for co-primality
      3M     %       Push the two inputs of the latest call to the hypotenuse 
             %       function. The stack now contains the hypotenuse and the
             %       two legs
      ZdZd   %       Call GCD twice, to obtain the GCD of those three numbers
      q      %       Subtract 1. If the three numbers were co-prime this gives
             %       0, so the do...while loop will be exited (but the "finally" 
             %       part will be executed first). If they were not co-prime  
             %       this gives non-zero, so the do...while loop proceeds 
             %       with the next iteration
    ]        %     End if
             %     If the decimal part was non-zero: the duplicate of the 
             %     hypotenuse that is now on the top of the stack will be used
             %     as the (do...while) loop condition. Since it is non-zero, 
             %     the loop will proceed with the next iteration
  }          %   Finally (i.e. execute before exiting the do...while loop)
    6M       %     Push the second input to the hypotenuse function, which is
             %     the new term of the sequence
    XI       %     Copy this new term into clipboard I
             %   Implicitly end do...while
             % Implicitly end for each
             % Implicitly display the stack, containing the sequence terms
Luis Mendo
quelle
2

Schläger 106 Bytes

(let p((h 3))(println h)(let p2((i 1))(define g(sqrt(+(* h h)(* i i))))(if(integer? g)(p g)(p2(add1 i)))))

Ungolfed:

(define (f)
  (let loop ((h 3))
    (let loop2 ((i 1))
      (define g (sqrt (+(* h h) (* i i))))
      (if (not(integer? g))
          (loop2 (add1 i))
          (begin (printf "~a ~a ~a~n" h i g)
                 (loop g))))))

Testen:

(f)

Ausgabe der Golfversion:

3
5
13
85
157
12325
12461
106285
276341
339709
10363909
17238541

Ausgabe der ungolfed version:

3 4 5
5 12 13
13 84 85
85 132 157
157 12324 12325
12325 1836 12461
12461 105552 106285
106285 255084 276341
276341 197580 339709
339709 10358340 10363909
10363909 13775220 17238541

(Fehler danach auf meinem Rechner)

rnso
quelle
Der Golf-Code gibt nur die Hypotenuse der Sequenz aus. Ungolfed-Versionen zeigen alle drei zur Verdeutlichung nicht in Frage kommender Drillinge.
RNSO
1

PHP, 139 Bytes

for($k=3;$i=$k,print("$k\n");)for($j=$i+1;($k=sqrt($m=$i*$i+$j*$j))>(int)$k||gmp_intval(gmp_gcd(gmp_gcd((int)$i,(int)$j),(int)$k))>1;$j++);

Der obige Code bricht nach 28455997 auf 32-Bit-Systemen. Wenn höhere Zahlen benötigt werden, werden 156 Bytes benötigt:

for($k=3;$i=$k,print("$k\n");)for($j=$i+1;!gmp_perfect_square($m=bcadd(bcpow($i,2),bcpow($j,2)))||gmp_intval(gmp_gcd(gmp_gcd($i,$j),$k=bcsqrt($m)))>1;$j++);
Chocochaos
quelle
1

Java 8, 133 Bytes

-25 Bytes dank Meilen Verwenden von n * n anstelle von Math.pow (n, 2)

-24 Bytes dank Meilen Verwenden von for-Schleifen anstelle von while, Ändern des Datentyps und Eliminieren von () aufgrund der Reihenfolge der Operationen

()->{long b=3,c,n;for(;;){for(n=1;;n++){c=b+2*n*n;double d=Math.sqrt(c*c-b*b);if(d==(int)d&b<d){System.out.println(b);break;}}b=c;}};

Nutzt die Tatsache, dass

Beziehung

für jedes Paar von ganzen Zahlen ist m> n> 0. Daher ist C gleich A plus 2 (N) 2 . Die obige Funktion ermittelt den kleinsten Wert von N, der diese Beziehung erfüllt, während das zweite Element des pythagoreischen Tripels eine ganze Zahl und größer als das erste Element ist. Dann setzt es den Wert des ersten Elements auf das dritte Element und wiederholt ihn mit dem aktualisierten ersten Element.

Ungolfed:

void printPythagoreanTriples() {
    long firstElement = 3, thirdElement, n;
    while (true) {
        for (n = 1; ; n++) {
            thirdElement = firstElement + (2 * n * n);
            double secondElement = Math.sqrt(thirdElement * thirdElement - firstElement * firstElement);
            if (secondElement == (int) secondElement && firstElement < secondElement) {
                System.out.println("Found Pythagorean Triple [" +
                        firstElement + ", " +
                        secondElement + ", " +
                        thirdElement + "]");
                break;
            }
        }
        firstElement = thirdElement;
    }
}

Ideone es!

* Die Ideone druckt aus zeitlichen Gründen nicht das letzte erforderliche Element, wie Sie jedoch anhand der Logik des Programms und der ungolfed Version (die den 28455997 als drittes Element des vorherigen pythagoreischen Tripels anstelle des ersten Elements von druckt) erkennen können Im nächsten Schritt werden die Werte mit einem höheren Zeitlimit ausgedruckt.

Mario Ishac
quelle
Könnten Sie nicht n*nanstelle von verwenden Math.pow(n,2)?
Meilen
Ich weiß nicht, warum ich nicht daran gedacht habe ... Ich werde das sofort hinzufügen. Vielen Dank @ Meilen
Mario Ishac
Ich habe mit Hilfe von forSchleifen etwas mehr Zeit gespart, um es auf 133 Bytes zu bringen()->{long b=3,c,n;for(;;){for(n=1;;n++){c=b+2*n*n;double d=Math.sqrt(c*c-b*b);if(d==(int)d&b<d){System.out.println(b);break;}}b=c;}};
Meilen
1

Python 3.5, 97 Bytes

Falsche Ausgabe nach 28455997wegen der Grenzen des Gleitkomma-Datentyps. Die sqrtFunktion ist nicht gut genug, aber wenn die Präzision auf magische Weise erhöht würde, würde es funktionieren.

Ziemlich einfach zu verstehen. Das Inkrementieren cum zwei statt eins halbiert die Laufzeit und es müssen ohnehin nur ungerade Zahlen überprüft werden, da die Elemente immer ungerade sind.

import math
c=a=3
while 1:
	c+=2;b=(c*c-a*a)**.5;i=int(b)
	if math.gcd(a,i)<2<a<b==i:print(a);a=c

Probieren Sie es online aus

Das Programm kann nicht auf Ideone ausgeführt werden, da Ideone Python 3.4 verwendet


Damit die Ausgabe länger präzise bleibt, muss Folgendes verwendet werden decimal:

import math
from decimal import*
c=a=3
while 1:
	c+=2;b=Decimal(c*c-a*a).sqrt();i=int(b)
	if i==b>a>2>math.gcd(a,i):print(a);a=c

Probieren Sie es online aus

Um auf unbestimmte Zeit genau zu bleiben, könnte ich so etwas Schreckliches tun (um die Genauigkeit zu erhöhen, die für jede einzelne Iteration erforderlich ist :

import math
from decimal import*
c=a=3
while 1:
	c+=2;b=Decimal(c*c-a*a).sqrt();i=int(b);getcontext().prec+=1
	if i==b>a>2>math.gcd(a,i):print(a);a=c
mbomb007
quelle
1

J , 54 47 Bytes

-:@+/@:*:@((*/:~)/)@,.&1@x:@(^/)@(2&p:)^:(<12)3

TIO

gierige Aufspaltung von Primfaktoren in Coprime-Faktoren

alte 54 Bytes TIO

Jayprich
quelle
1

APL (NARS), 169 Zeichen, 338 Byte

h←{{(m n)←⍵⋄(mm nn)←⍵*2⋄(2÷⍨nn+mm),(2÷⍨nn-mm),m×n}a⊃⍨b⍳⌊/b←{⍵[2]}¨a←a/⍨{(≤/⍵)∧1=∨/⍵}¨a←(w÷a),¨a←∪×/¨{k←≢b←1,π⍵⋄∪{b[⍵]}¨↑∪/101 1‼k k}w←⍵}⋄p←{⍺=1:⍵⋄⍵,(⍺-1)∇↑h ⍵}⋄q←{⍵p 3x}

teste ok bis 14 als Argument von q:

  q 1
3 
  q 2
3 5 
  q 10
3 5 13 85 157 12325 90733 2449525 28455997 295742792965 
  q 12
3 5 13 85 157 12325 90733 2449525 28455997 295742792965 171480834409967437 656310093705697045 
  q 13
3 5 13 85 157 12325 90733 2449525 28455997 295742792965 171480834409967437 656310093705697045 
  1616599508725767821225590944157 
  q 14
NONCE ERROR
  q 14
  ∧

das unten würde alle Teiler seines Arguments finden ...

∪×/¨{k←≢b←1,π⍵⋄∪{b[⍵]}¨↑∪/101 1‼k k}
RosLuP
quelle
0

JavaScript (Node.js) , 101 Byte

_=>{for(var a=3,b,c;;){for(c=1;;c++)if(b=a+2*c*c,d=Math.sqrt(b*b-a*a),d==+d&a<d){alert(a);break}a=b}}

Probieren Sie es online!

Vorschläge zum Golfen sind willkommen

Muhammad Salman
quelle