Secuencia Triple Pitágora


33

Un triple pitagórico consta de tres enteros positivos a, byc, de modo que a 2 + b 2 = c 2 . Tal triple se escribe comúnmente (a, b, c), y un ejemplo bien conocido es (3, 4, 5). Si (a, b, c) es un triple pitagórico, entonces también lo es (ka, kb, kc) para cualquier entero positivo k. Un triple pitagórico primitivo es aquel en el que a, byc son coprimos .

Usando este conocimiento, podemos crear una secuencia al encadenar las longitudes de triples menos largas, donde el siguiente elemento en la secuencia es la hipotenusa (número más grande) del triple pitagórico primitivo más pequeño que contiene el elemento anterior como el más pequeño de sus longitudes.

Comience con el triple pitagórico primitivo más pequeño (3, 4, 5). La secuencia comienza con 3, y la hipotenusa (siguiente elemento de la secuencia) es 5. Luego, encuentra el triple pitagórico primitivo más pequeño con 5una pierna, y obtienes (5, 12, 13). Entonces la secuencia continúa con 13.

O emite la secuencia para siempre, o toma una entrada entera ny emite los primeros nelementos de la secuencia, ya sea cero o uno indexado.

Debe admitir la salida al menos a través de e incluyendo 28455997, pero si el límite del tipo de datos que está utilizando se elevó repentinamente, tendría que funcionar para ese nuevo límite. Por lo tanto, no puede codificar una lista de números.

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

OEIS A239381

Secuencias similares (¡no muestres estas!):


¿Hay algún límite de tiempo?
Loovjo

@Loovjo No, pero debe saber / probar que su salida es correcta. Hay algunas secuencias similares donde la salida difiere después 12325.
mbomb007

La secuencia similar en la que estoy pensando difiere después de 85... su próximo término es 3613(¿puedes adivinar qué es todavía?)
Neil

@Neil Una búsqueda rápida produce A053630 , la espiral de Pitágoras. Sin embargo, hice referencia a los dos en el desafío, porque mientras trabajaba en mi implementación, accidentalmente llegué a esas dos secuencias o similares a ellas.
mbomb007

1
De hecho, si hubiera estado más despierto, podría haberlo buscado yo mismo ...
Neil

Respuestas:


11

Jalea , 19 bytes

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

Ahorré un byte gracias a @ Dennis refactorizando a una secuencia infinita.

No toma datos ni argumentos, luego emite la secuencia infinitamente imprimiendo cada término a medida que los computa. Este método se ralentiza a medida que los números aumentan, ya que depende de la factorización prima.

Pruébalo en línea!

Esto calcula el próximo término calculando la factorización de potencia prima del término actual. Para 12325, esto es {5 2 , 17, 29}. Hay una variante de la fórmula de Euclides para calcular triples pitagóricos { a , b , c },

fórmula

donde m > ny el triple es primitivo si m y n son coprimos.

Para calcular el siguiente raíz primitiva de 12.325, encontrar m y n tales que mn = 12.325 y elegir m , n de modo que gcd ( m , n ) = 1. Entonces generar todos los pares de m , n mediante la creación de todos los subconjuntos de {5 2 , 17, 29} y encontrar el producto de cada uno de esos subconjuntos que son {1, 25, 17, 29, 425, 725, 493, 12325}. Luego divida 12325 por cada valor y par de modo que cada par sea m , n . Calcule la fórmula para c usando cada par y tome el mínimo que es 90733.

  • El método anterior falló para determinar el siguiente término después de 228034970321525477033478437478475683098735674620405573717049066152557390539189785244849203205. El método anterior eligió el último valor como factor cuando la elección correcta fue el 3er y último primo. El nuevo método es más lento, pero siempre funcionará, ya que prueba todos los pares de coprimos para encontrar la hipotenusa mínima.

Explicación

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

¡Guau, esto es realmente rápido!
mbomb007

1
o3ṄÆfµṪ,P²SHßcon salida infinita guarda un byte.
Dennis

5

Brachylog , 36 bytes

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

Pruébalo en línea!

Debe esperar a que se agote el tiempo del programa (1 minuto) antes de que TIO descargue la salida. En REPL de SWI-Prolog, esto se imprime tan pronto como encuentra el valor.

Esto imprimirá la secuencia para siempre.

Después de unos minutos en el intérprete de SWI-Prolog fuera de línea, obtuve 90733después 12325. Lo detuve después de este punto.

Esto no es fuerza bruta completa, ya que utiliza restricciones para encontrar triples pitagóricos, aunque obviamente no está optimizado para la velocidad.

Explicación

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

4

Perl, 73 bytes

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

Todos los triples pitagóricos a²+b²=c²satisfacen a=r(m²-n²), b=2rmn, c=r(m²+n²)para algunos enteros r,m,n. Cuando r=1ym,n son coprimos con exactamente uno divisible por 2, entonces a,b,ces un triple primitivo, donde a,b,ctodos son coprimos por pares.

Con esto en mente, dado algunos a, utilizo un algoritmo de fuerza bruta para calcular el más pequeño n, que a²-n²es un cuadrado, a saber . Entonces, ces igual a n²+m².


Posible error tipográfico en su explicación: busca ntal que a+n²sea ​​un cuadrado.
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)

Esto es básicamente un algoritmo de fuerza bruta y, por lo tanto, es muy lento. Se necesita la cantidad de términos para generar como entrada.

No estoy 100% seguro de la exactitud de este algoritmo, el programa verifica el otro tramo hasta el primer tramo cuadrado, lo cual creo que es suficiente, pero no he hecho los cálculos.

Pruébalo en repl.it! (Anticuado) (Por favor, no lo intente para números mayores que 10, será muy lento)


Puede cambiar a Python 3.5 y usar math.gcd. Además, use en p+=[...]lugar de p.append(...). Y <2en lugar de ==1. Y iftodos pueden estar en una línea.
mbomb007

1
Todavía puede hacer las últimas 2 mejoras que sugerí.
mbomb007


Loovjo, ¿vas a jugar tu código usando las sugerencias o no?
mbomb007

2

MATL , 27 bytes

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

Esto produce los primeros términos de la secuencia. La entrada está basada en 0.

El código es muy ineficiente. El compilador en línea agota el tiempo de espera para entradas mayores que 5. La entrada 6tardó un minuto y medio fuera de línea (y produjo el correcto 90733como sexto término).

Pruébalo en línea!

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

2

Raqueta 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)))))

Sin golf:

(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))))))

Pruebas:

(f)

Salida de la versión de golf:

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

Salida de la versión sin golf:

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

(Error después de esto en mi máquina)


El código de golf imprime solo hipotenusa de secuencia. Las versiones sin golf muestran los tres para aclarar trillizos no mencionados en la pregunta.
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++);

El código anterior se rompe después de 28455997 en sistemas de 32 bits. Si se necesitan números más altos, se convierte en 156 bytes:

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++);

1

Java 8, 133 bytes

-25 bytes gracias a millas Usando n * n en lugar de Math.pow (n, 2)

-24 bytes gracias a millas Uso de bucles en lugar de while, cambio de tipo de datos, eliminación () debido al orden de las operaciones

()->{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;}};

Utiliza el hecho de que

Relación

para cualquier par de enteros m> n> 0. Por lo tanto, C es igual a A más 2 (N) 2 . La función anterior encuentra el menor valor de N que satisface esta relación, al tiempo que hace que el segundo elemento del pitagórico triplique un número entero y mayor que el primer elemento. Luego establece el valor del primer elemento en el tercer elemento y se repite con el primer elemento actualizado.

Sin golf:

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 it!

* La ideona no imprime el último elemento requerido debido a los límites de tiempo, sin embargo, como puede ver a través de la lógica del programa y la versión no protegida (que imprime el 28455997 como el tercer elemento del triple pitagórico anterior en lugar del primer elemento de el siguiente), los valores son, con un límite de tiempo más alto, impresos.


¿No podrías usar en n*nlugar de Math.pow(n,2)?
millas

No sé por qué no pensé en eso ... Lo agregaré de inmediato. Gracias @miles
Mario Ishac

Me afeité un poco más usando for bucles para reducirlo a 133 bytes()->{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;}};
millas

1

Python 3.5, 97 bytes

Salida incorrecta después 28455997, debido a los límites del tipo de datos de coma flotante. La sqrtfunción no es lo suficientemente buena, pero si la precisión aumentara mágicamente, funcionaría.

Bastante simple de entender. Incrementar cen dos en lugar de uno reduce el tiempo de ejecución a la mitad, y de todos modos solo se deben verificar los números impares, porque los elementos siempre son impares.

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

Pruébalo en línea

El programa no se puede ejecutar en Ideone, porque Ideone usa Python 3.4


Para que la salida se mantenga precisa por más tiempo, tendría que usar 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

Pruébalo en línea

Para mantener la precisión indefinidamente, podría hacer algo horrible como esto (aumentar la precisión requerida cada iteración :

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



1

APL (NARS), 169 caracteres, 338 bytes

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}

prueba ok hasta 14 como argumento de 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
  ∧

esto a continuación encontraría todos los divisores de su argumento ...

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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.