Sequência tripla de Pitágoras


33

Um triplo pitagórico consiste em três números inteiros positivos a, bec, de modo que a 2 + b 2 = c 2 . Esse triplo é comumente escrito (a, b, c) e um exemplo bem conhecido é (3, 4, 5). Se (a, b, c) é um triplo pitagórico, o mesmo acontece com (ka, kb, kc) para qualquer número inteiro positivo k. Um triplo pitagórico primitivo é aquele em que a, bec são coprimes .

Usando esse conhecimento, podemos criar uma sequência encadeando os menores comprimentos de triplos, onde o próximo elemento na sequência é a hipotenusa (maior número) do menor triplo pitagórico primitivo menor que contém o elemento anterior como o menor de seus comprimentos.

Comece com o menor triplo pitagórico primitivo (3, 4, 5). A sequência começa com 3, e a hipotenusa (próximo elemento da sequência) é 5. Em seguida, encontre o menor triplo pitagórico primitivo com 5uma perna e você obtém (5, 12, 13). Então a sequência continua com 13.

Faça a saída da sequência para sempre ou pegue uma entrada inteira ne faça a saída dos primeiros nelementos da sequência, zero ou um indexado.

Você precisa oferecer suporte à saída pelo menos através e inclusive 28455997, mas se o limite do tipo de dados que você está usando for subitamente aumentado, ele precisará trabalhar para esse novo limite. Portanto, você não pode codificar uma lista de números.

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

OEIS A239381

Sequências semelhantes (não as produzam!):


Existe algum limite de tempo?
Loovjo 28/10

@ Loovjo Não, mas você deve saber / provar que sua saída está correta. Existem algumas seqüências semelhantes em que a saída difere depois 12325.
mbomb007

A seqüência semelhante Estou pensando em difere depois 85... seu próximo mandato é 3613(você pode adivinhar o que é ainda?)
Neil

@ Neil Uma pesquisa rápida rende A053630 , a espiral pitagórica. No entanto, referenciei os dois no desafio, porque enquanto trabalhava na implementação, atingi acidentalmente essas duas seqüências ou similares.
mbomb007

1
Na verdade, se eu tivesse sido mais acordada que eu poderia ter apenas olhei para cima mim ...
Neil

Respostas:


11

Geléia , 19 bytes

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

Salvou um byte graças a @ Dennis , refatorando para uma sequência infinita.

Não aceita entrada e argumentos, em seguida, gera a sequência infinitamente, imprimindo cada termo à medida que os computa. Este método diminui à medida que os números aumentam, pois depende da fatoração primária.

Experimente online!

Isso calcula o próximo termo calculando a fatoração de potência principal do termo atual. Para 12325, este é {5 2 , 17, 29}. Existe uma variante da fórmula de Euclides para calcular triplos pitagóricos { a , b , c },

Fórmula

onde m > n e o triplo são primitivos se m e n são coprime.

Para calcular a próxima raiz primitiva de 12325, encontre m e n de modo que mn = 12325 e escolha m , n para que gcd ( m , n ) = 1. Em seguida, gere todos os pares de m , n criando todos os subconjuntos de {5 2 , 17, 29} e localizando o produto de cada um desses subconjuntos que são {1, 25, 17, 29, 425, 725, 493, 12325}. Em seguida, divida 12325 por cada valor e par para que cada par seja m , n . Calcule a fórmula para c usando cada par e calcule o mínimo que é 90733.

  • O método anterior falhou ao determinar o próximo termo após 228034970321525477033478437478475683098735674620405573717049066152557390539189785244849203205. O método anterior escolheu o último valor como um fator quando a escolha correta era a terceira e a última primas. O novo método é mais lento, mas sempre funcionará, uma vez que testa todos os pares de coprimes para encontrar a hipotenusa mínima.

Explicação

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

Uau, isso é muito rápido!
mbomb007

1
o3ṄÆfµṪ,P²SHßcom saída infinita salva um byte.
Dennis

5

Braquilog , 36 bytes

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

Experimente online!

Você precisa aguardar o tempo limite do programa (1 minuto) antes que o TIO libere a saída. No REPL do SWI-Prolog, isso é impresso assim que encontrar o valor.

Isso imprimirá a sequência para sempre.

Depois de alguns minutos no intérprete offline do SWI-Prolog, obtive 90733depois 12325. Eu parei depois deste ponto.

Isso não é força bruta completa, pois usa restrições para encontrar triplos pitagóricos, embora obviamente não seja otimizado para velocidade.

Explicação

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 os triplos pitagóricos a²+b²=c²satisfazem a=r(m²-n²), b=2rmn, c=r(m²+n²)alguns números inteiros r,m,n. Quando r=1e m,nsão coprimes, com exatamente um sendo divisível por 2, então a,b,cé um triplo primitivo, onde a,b,ctodos são coprimes em pares.

Com isso em mente, dado um pouco a, eu uso um algoritmo de força bruta para calcular o menor ntal que a²-n²seja um quadrado, a saber . Então, cé igual a n²+m².


Possível erro de digitação em sua explicação: você procurar ntal que a+n²é um quadrado.
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)

Isso é basicamente apenas um algoritmo de força bruta e, portanto, é muito lento. É preciso a quantidade de termos para a saída como entrada.

Não tenho 100% de certeza sobre a correção desse algoritmo, o programa verifica a outra perna até a primeira perna ao quadrado, o que acredito ser suficiente, mas ainda não fiz as contas.

Experimente em repl.it! (Desatualizado) (por favor, não tente números maiores que 10, será muito lento)


Você pode mudar para o Python 3.5 e usar math.gcd. Além disso, use em p+=[...]vez de p.append(...). E ao <2invés de ==1. E iftudo pode estar em uma linha.
mbomb007

1
Você ainda pode fazer as duas últimas melhorias que sugeri.
mbomb007


Loovjo, você vai jogar seu código usando as sugestões ou não?
Mbomb007

2

MATL , 27 bytes

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

Isso produz os primeiros termos da sequência. A entrada é baseada em 0.

O código é muito ineficiente. O compilador online atinge o tempo limite para entradas maiores que 5. A entrada 6ficou offline por um minuto e meio (e produziu o correto 90733como sexto termo).

Experimente 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

2

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

Teste:

(f)

Saída da versão golfed:

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

Saída da versão ungolfed:

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

(Erro depois disso na minha máquina)


O código golfado imprime apenas hipotenusa de sequência. Versões ungolfed mostram todos os três para esclarecer trigêmeos não mencionados na pergunta.
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++);

O código acima quebra após 28455997 em sistemas de 32 bits. Se forem necessários números mais altos, eles se tornarão 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 graças a milhas Usando n * n em vez de Math.pow (n, 2)

-24 bytes graças a milhas Usando loops for em vez de while, alterando o tipo de dados, eliminando () devido à ordem das operações

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

Usa o fato de que

Relação

para qualquer par inteiro m> n> 0. Portanto, C é igual a A mais 2 (N) 2 . A função acima encontra o menor valor de N que satisfaz essa relação, enquanto faz com que o segundo elemento do Pitágoras triplique um número inteiro e maior que o primeiro elemento. Em seguida, define o valor do primeiro elemento para o terceiro elemento e se repete com o primeiro elemento atualizado.

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

* O ideone não imprime o último elemento necessário devido a limites de tempo, no entanto, como você pode ver através da lógica do programa e da versão não destruída (que imprime o 28455997 como o terceiro elemento do triplo pitagórico anterior, em vez de o primeiro elemento de o próximo), os valores são impressos com um limite de tempo maior.


Você não poderia usar em n*nvez de Math.pow(n,2)?
miles

Não sei por que não pensei nisso ... vou acrescentar isso imediatamente. Obrigado @miles
Mario Ishac

Fiz a barba um pouco mais fora de usar forloops para obtê-lo para baixo para 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;}};
milhas

1

Python 3.5, 97 bytes

Saída errada após 28455997 , devido aos limites do tipo de dados de ponto flutuante. A sqrtfunção não é boa o suficiente, mas se a precisão fosse aumentada magicamente, funcionaria.

Muito simples de entender. Incrementar cpor dois em vez de um reduz o tempo de execução pela metade e apenas números ímpares precisam ser verificados de qualquer maneira, porque os elementos são sempre ímpares.

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

Experimente online

O programa não pode ser executado no Ideone, porque o Ideone usa o Python 3.4


Para que a saída permaneça precisa por mais tempo, eu precisaria 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

Experimente online

Para manter a precisão indefinidamente, eu poderia fazer algo horrível como este (aumentar a precisão necessária a cada iteração :

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}

teste ok até 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
  ∧

isso abaixo encontraria todos os divisores de seu argumento ...

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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.