Triplici pitagorici primitivi


29

( correlato )

Una tripla pitagorica è un elenco (a, b, c)che soddisfa l'equazione a 2 + b 2 = c 2 .

Un triplo pitagorico primitivo (PPT) è uno in cui a, be csono tutti coprimi (cioè, l'unico divisore comune tra i tre elementi è 1). Ad esempio, il (3, 4, 5)triangolo rettangolo è un famoso triplo pitagorico primitivo.

La sfida

  • Dato input n, emette il nth PPT. O,
  • Dato input n, output i primi nPPT.

Esistono diversi modi per ordinare questi PPT per formare un elenco ben ordinato, per determinare quale è il nth. Puoi scegliere qualsiasi ordine tu desideri, purché tu possa provare (informalmente va bene) che il tuo algoritmo può generare ogni possibile PPT unico. Ad esempio, il tuo codice non dovrebbe generare entrambi (3,4,5)e (4,3,5)poiché questi sono duplicati della stessa tripla, l'uno o l'altro, per favore.

Allo stesso modo, se il tuo codice è zero o uno-indicizzato va bene, purché dichiari quale stai usando.

Esempi

Per gli esempi seguenti, sto usando l'indicizzazione uno, l'output del nth PPT e l'ordinamento dal più piccolo c, quindi il più piccolo a, quindi il più piccolo b.

n | output
1 | (3, 4, 5)
2 | (5, 12, 13)
5 | (20, 21, 29)
12| (48, 55, 73)

Regole

  • L'input e l'output possono essere forniti in qualsiasi formato conveniente .
  • Nel tuo invio, indica come vengono ordinate le voci e se le voci sono indicizzate 0 o 1.
  • Il tuo ordine scelto non può creare duplicati.
  • È accettabile un programma completo o una funzione. Se una funzione, è possibile restituire l'output anziché stamparlo.
  • Se possibile, includi un collegamento a un ambiente di test online in modo che altre persone possano provare il tuo codice!
  • Sono vietate le scappatoie standard .
  • Si tratta di quindi si applicano tutte le normali regole del golf e vince il codice più breve (in byte).



Qual è l'input più elevato che dobbiamo supportare? Possiamo presumere che si adatti alle capacità della nostra lingua preferita?
Mr. Xcoder,

1
@ Mr.Xcoder Sì; questo è un presupposto sicuro standard, a meno che non lo si usi per sfruttare una scappatoia (ad esempio, il linguaggio supporta solo numeri a 1 bit) per rendere il problema banale.
AdmBorkBork,

2
Ho trovato la risposta alla mia domanda: aeb devono essere coprimi e questo è abbastanza proofwiki.org/wiki/…
edc65,

Risposte:


12

Gelatina , 27 25 byte

2 byte grazie a Jonathan Allan.

²IH;Pµ;ÆḊ
+2ḶḤ‘Œcg/ÐṂÇ€Ṣḣ

Provalo online!

Emette le prime ntriple indicizzate 1 [b, a, c], ordinate per crescente be poi a.

Utilizza l'algoritmo di Wikipedia :

a = mn, b = (m² - n²) / 2, c = (m² + n²) / 2

Questo genera tutte le triple primitive per tutte le coppie coprime uniche di numeri dispari m > n > 0.

Spiegazione

+2ḶḤ‘Œcg/ÐṂÇ€Ṣḣ    Main link. Argument: n
+2                   Add 2 to n, to get enough results.
  Ḷ                  Get integers [0, 1, ..., n+1].
   Ḥ                 Double to get [0, 2, ..., 2n+2].
    ‘                Increment to get [1, 3, ..., 2n+3].
     Œc              Get all ordered pairs [[1, 3], [1, 5], ..., [2n+1, 2n+3]].
       g/            GCD of each pair.
         ÐṂ          Grab the pairs with minimal GCD (which is 1).
           ǀ        Call the helper link on each pair to get the triples.
             Ṣ       Sort the triples first by a, then by b, then by c.
              ḣ      Get the last n.

²IH;Pµ;ÆḊ    Helper link. Argument: pair [m, n]
²              Square to get [m², n²].
 I             Increments: get [m²-n²].
  H            Halve: get [(m²-n²)/2], i.e. [b].
    P          Product: get mn, i.e. a.
   ;           Append to get [b, a].
     µ         Begin a new monadic chain with argument [b, a].
       ÆḊ      Get the length of the vector, i.e. c.
      ;        Append to get [b, a, c].

Questa è davvero una bella spiegazione. Grazie!
AdmBorkBork,

g/Ị$Ðf-> g/ÐṂper salvare due byte (poiché il minimo gcd è 1 e ci sarà sempre almeno una di queste voci).
Jonathan Allan,

Un altro byte può anche essere salvato (anche se rendendolo meno efficiente) sostituendo +2ḶḤ‘Œccon ²Rm2Œc- scrap che non funzionerà per un input di 1:(
Jonathan Allan

@JonathanAllan Grazie per il minimo. Ho provato molti intervalli di 2 byte, ma sfortunatamente nessuno era abbastanza grande. (è ²ḶḤ‘Œcstato uno dei primi a cui ho pensato.)
PurkkaKoodari il

8

MATL , 36 byte

`@:Ut&+wmR&fZd1Mhw/vXutnGE<]GY)t&2|h

L'input è basato su 1. L'ordine di uscita garantisce che ogni tripla appaia esattamente una volta. L'ordine è spiegato di seguito. La spiegazione richiede approfondire il funzionamento del programma.

Il codice continua ad aumentare un contatore kin un ciclo, a partire da 1. Per ogni kgenera tutte le coppie con a = 1,...,k, b = 1,...,k, a < b, e picconi quelle che danno una terna pitagorica con c <= k. Le coppie sono ottenute in ordine crescente b, quindi a.

Ogni coppia viene quindi divisa per il suo gcd. Le coppie risultanti (possibilmente duplicate) sono disposte come una matrice a due colonne. Questa matrice è concatenata verticalmente con una matrice simile contenente i risultati accumulati ottenuti per valori inferiori di k. Le righe della matrice vengono quindi deduplicate stabilmente. Ciò rimuove due tipi di duplicati:

  1. Coppie che sono state trovate più di una volta per la corrente k(come 3,4, che risulta anche 6,8quando si divide per il suo gcd);

  2. Coppie che erano già state trovate con dimensioni inferiori k.

In effetti, ogni iterazione ktrova tutte le coppie che erano già state trovate per iterazioni precedenti. Ma potrebbe trovarli in un ordine diverso . Ad esempio, k=25troverà la tripla 7,24,25e non 20,21,29(perché cnon può eccedere k). Più tardi, l'iterazione k=29troverà entrambi, ma con 20,21,29 prima 7,24,25 (l'ordine è in aumento b, quindi a). Questo è il motivo per cui, invece di mantenere tutte le coppie trovate per l'ultima k, le aggiungiamo alle precedenti e deduplichiamo stabilmente. In questo modo si garantisce che l'ordine è lo stesso per qualsiasi input n.

Quanto sopra garantisce che ogni tripla pitagorica primitiva apparirà alla fine e apparirà solo una volta. Per l'input n, il loop over ktermina quando nsono state ottenute almeno triple triple; e poi la nterza tripla è in uscita.

Provalo online!

Oppure usa questo codice modificato per vedere le prime ntriple:

`@:Ut&+wmR&fZd1Mhw/vXutnGE<]G:Y)tU&2sX^h

Provalo online!


1
Bella spiegazione.
AdmBorkBork,


5

Gelatina , 19 18 byte

*g/²_/
4*œc3UṢÇÐḟḣ

Il programma prende un indice n basato su 1 e stampa i primi n PPT [c, b, a] in ordine lessicografico.

Questa è una soluzione O (64 n ) , quindi TIO si strozzerà sugli ingressi 4 e superiori. Lavorerò per renderlo più veloce.

Provalo online!

Versione alternativa, O (n 3 ), probabilmente valida

Per trovare il n ° tripletta - [c n , b n , un n ] - la soluzione sopra presuppone che c n ≤ 4 n , che è facile da verificare. Tuttavia, A020882 dimostra che c n ~ 2πn , quindi esiste una k tale che c n ≤ kn per tutto n .

Se possiamo prendere k = 7 , anche la soluzione seguente è valida (e molto, molto più veloce).

*g/²_/
×7œc3UṢÇÐḟḣ

Provalo online!

Come funziona

4*œc3UṢÇÐḟḣ  Main link. Argument: n

4*           Compute 4**n, the n-th power of 4.
  œc3        Take all 3-combinations of the set {1, ..., 4**n}, each sorted in
             ascending order. The triples themselves are sorted lexicographically.
     U       Upend; reverse each triple [a, b, c], yielding [c, b, a].
      Ṣ      Sort the descending triples lexicographically. This ensures that their
             order is independent of n.
       ÇÐḟ   Keep only triples for which the helper link returns a falsy value.
          ḣ  Dyadic head; take the first n triples.


*g/²_/       Helper link. Argument: [c, b, a]

 g/          Reduce [c, b, a] by greatest common divisor, yielding g.
*            Elevate the integers to that power, computing [c**g, b**g, a**g].
   ²         Square, yielding [c**2g, b**2g, a**2g].
    _/       Reduce by subtraction, yielding c**2g - b**2g - a**2g.
             Fermat's Last Theorem assures that this difference will be non-zero
             whenever g > 1, so this yields 0 iff g = 1 and c² = a² = b².

4

JavaScript (ES7), 106 105 103 byte

Emette l'ennesimo PPT. I risultati sono 1-indicizzati e ordinati per il valore di b .

n=>(g=(a,b)=>b?g(b,a%b):a,F=a=>(x=a*a+b*b,c=x**.5|0)*c-x*g(a,g(b,c))||--n?F(a-b?a+1:!++b):[a,b,c])(b=1)

dimostrazione


4

MATL , 63 byte

3lvi:"t"[HlHllO;aOlOHl]!@Y*2eh]]!XuGY)&*tt[lO;Oa]*ssD2)ED2Xy*ss

Provalo online!

Una lezione di golf è andata terribilmente storto. Lo sto pubblicando comunque perché mi chiedo se ci sono modi per giocare a golf così meglio.

Ho basato questo su questa pagina di Wikipedia in combinazione con la formula di Euclide, per generare costruttivamente tutte le triple piuttosto che gli approcci di prova ed errore.

Innanzitutto, le coppie coprime dispari vengono generate come un albero ternario. Questo viene fatto come una grande moltiplicazione della matrice, che rappresenta la maggior parte del conteggio dei byte. Quindi, viene applicata la formula di Euclide, possibilmente anche in modo molto dispendioso. Se qualcuno ha suggerimenti per queste due parti, mi piacerebbe ascoltarle.

Si noti che, per salvare byte, questo programma genera un albero della stessa profondità dell'input, anziché log3(n). Inoltre, i figli vengono generati per ogni riga anziché solo per l'ultima riga dell'albero e quindi filtrati nuovamente con Xu. Questo per un approccio costruttivo efficiente.

3lv % Push root node of ternary tree
i:" % Generate a tree of depth of input (WAY too large, but golfy)
t"  % loop over all nodes (golfier than looping over last tree row)
[HlHllO;aOlOHl]! % Matrix to generate three children of current node
@Y* % Multiply with current node to get children
2e  % Reshape to get node pairs
h]] % Append to tree, exit loops
!Xu % Remove duplicates (more efficient to do it before last ] but golfier this way)
GY) % Select n-th odd coprime pair
&*tt % Multiply with it's own transpose to get [m²,m*n;m*n,n²]
[lO;Oa]*ssD % Sum of matrix multiplication = m²-n² to get a
2)ED % Second element doubled for b=2mn
2Xy*ss % Sum of matrix multiplication with identify matrix to get c=m²+n²

3

Haskell, 65 byte

([(a,b,c)|c<-[5..],b<-[1..c],gcd c b<2,a<-[1..b],a^2+b^2==c^2]!!)

Indicizzazione basata su 0. Per un dato c, bcorre fino a ce afino a b, quindi c > b > avale sempre.

Provalo online!


3

Python, 67 50 48 46 byte

Utilizzando le formule trovate su Wikipedia,

a=m*n, b=(m^2-n^2)/2, c=(m^2+n^2)/2

dove m>n>0e me nsono coprimi e dispari. Ecco il codice

lambda n:[3+2*n,~-(3+2*n)**2-1/2,-~(3+2*n)**2/2]

-17 byte grazie a @Martin Ender

Provalo online

Funziona avendo sempre il valore della nvariabile nell'equazione pari a 1, il che significa che mè semplicemente qualsiasi altro valore dispari, in questo caso, 3+2*ndove nè il numero della tripla pitagorica primitiva. Questo ci consente di assumere il valore 1 per tutti i nvalori.


Benvenuti in PPCG! Le funzioni senza nome vanno bene, quindi non è necessario assegnare lambda a a(e se lo facessi, potresti sbarazzarti dei due spazi lì). Inoltre non sono sicuro del perché tu printci sia, potresti semplicemente restituire i valori dalla stessa lambda.
Martin Ender,

"puoi provare (informalmente va bene) che il tuo algoritmo può generare ogni possibile PPT unico". Ma questo metodo genera solo quelli in cui l'ipotenusa è 1 più lunga di una gamba. Non genera mai 8,15,17, per esempio.
Rosie F

2

Buccia , 18 byte

↑üOf§=F⌋ȯ¬Ḟ-m□ΠR3N

Provalo online!

-4 byte grazie a Zgarb, con ispirazione da Dennis

Approccio a forza bruta super-lenta, non funzionerà su TIO per input più grandi di 1. Puoi provare una versione più gestibile, limitata a a, b≤200 qui

Spiegazione

↑üOf§=F⌋ȯ¬Ḟ-m□ΠR3N
              ΠR3N   Get all triples of natural numbers
   f                 Keep only those triples where
      F⌋                their GCD
    §=                  is equal to
        ȯ¬Ḟ-m□          the logical negation of c²-b²-a²
 üO                  Remove duplicates by their sorted version
↑                    Get the first <input> values of this sequence

20 byte combinando la mappa e il filtro, anche più lentamente.
Zgarb,

@Zgarb grazie! Sono riuscito a giocare a golf un byte in più :)
Leo,

18 byte con il trucco di sottrazione dalla risposta Jelly di Dennis.
Zgarb,

@Zgarb nice! Anche se sto avendo dei dubbi: potrebbero esserci due triple diverse con la stessa c? in tal caso, questa soluzione dovrebbe essere risolta
Leo,

Hmm, in realtà ci sono molte triple con lo stesso c. Questa soluzione a 18 byte (che utilizza un altro trucco di Dennis) funziona indipendentemente.
Zgarb,

1

Mathematica, 89 byte

usando Risolvi ordinato da c

SortBy[{a,b,c}/.Solve[a^2+b^2==c^2&&GCD[a,b]==1&&0<a<b<c<9#,{a,b,c},Integers],Last][[#]]&

Mathematica, 124 byte

(s={};Table[If[IntegerQ[c=Sqrt[a^2+b^2]]&&GCD[a,b]==1,AppendTo[s,{a,b,c}]],{a,9#},{b,9#}];SortBy[Union[Sort/@s],Last][[#]])&

1

R (+ numeri), 88 byte

n=scan();while(all(nrow(T)<n))T=numbers::pythagorean_triples(5,5+(F<-F+1));T[n,3:5]

Per usare un built-in per generare i numeri, ci vuole in realtà una quantità sorprendente di byte per ottenere ciò che vogliamo. L'incorporato accetta due argomenti c1e c2, e restituisce quelle terzine che hanno c >= c1 & c <= c2. Questo rende leggermente fastidioso arrivare alla nterza terzina. Ciò continuerà ad aumentare di c21 alla volta fino a quando l'output non è appena abbastanza righe.


1

PHP , 273 byte

function t($n){$x=[];for($c=3;;$c++)for($b=2;$b<$c;$b++)for($a=2;$a<$b;$a++)if(d($a,$b,$c)&&$a**2+$b**2==$c**2){$x[]=[$a,$b,$c];if(--$n==0)return $x;}}function d($a,$b,$c){for($i=2;$i<$a;$i++)if($a%$i==0&&$b%$i==0||$a%$i==0&&$c%$i==0||$b%$i==0&&$c%$i==0)return 0;return 1;}
  • t($n) restituisce una matrice di [a, b, c] con l'ordinamento a < b < c
  • Restituisce un indice in base zero

Provalo online! (il codice è leggibile anche lì)


1

C, 158 byte

Credo che questa sia la mia prima presentazione qui, quindi molto probabilmente puoi fare di meglio.

#include<stdio.h>
void f(n){int i=0,j=3,k,l;while(1){for(k=1;k<j;k++){for(l=k;l<j;l++){if(j*j==k*k+l*l)i++;if(i==n){printf("%d %d %d",j,k,l);return;}}}j++;};}

E versione non golfata:

#include <stdio.h>

void f(n)
{
  int i=0, j=3, k, l;
  while (1) {
    for (k=1; k<j; k++) {
      for (l=k; l<j; l++) {
        if (j*j==k*k+l*l)
          i++;
        if (i==n) {
          printf("%d %d %d\n", j, k, l);
          return;
        }
      }
    }
    j++;
  };
}

void main()
{
  int i;

  scanf("%d", &i);

  f(i);
  printf("\n");
}

Per a 2 + b 2 = c 2 , l'ordinamento aumenta c quindi aumenta a .

Non ci può essere nessun due volte lo stesso PPT di b è a LEA una in questo algoritmo.


Benvenuti in PPCG!
JAD,

1

Gelatina , 27 25 byte

⁽0(ḃs
Ɠḃd2Ḥ’×€Ç
3r5DṭÇæ×/

Questa è un'implementazione dell'approccio albero dalla risposta Haskell di @ AndersKaseorg , con un diverso ordine di diramazione. Il programma utilizza l'indicizzazione basata su 0 e accetta input da STDIN.

Provalo online!

sfondo

Come menzionato nella pagina Wikipedia Albero delle triple triple pitagoriche , ogni PPT può essere ottenuto moltiplicando ripetutamente a sinistra il vettore di riga (3, 4, 5) per matrici con determinate proprietà.

In ogni iterazione, il risultato precedente può essere moltiplicato a sinistra per A , B o C , che può essere scelto come segue.

matrici

Quando A , B e C sono fissi, ogni PPT può essere ottenuto in modo unico.

Come funziona

3r5DṭÇæ×/  Main link. No arguments.

3          Set the argument and the return value to 3.
 r5        Create a range from 3 to 5, i.e., [3, 4, 5].
   D       Decimal; convert each integer to base 10, yielding [[3], [4], [5]].
     Ç     Call the second helper link with argument 3.
    ṭ      Tack; append [[3], [4], [5]] to the result.
      æ×/  Reduce by matrix multiplication.
Ɠḃd2Ḥ’×€Ç  Second helper link. Argument: 3

Ɠ          Read and evaluate one line of input, yielding an integer n.
 ḃ         Convert n to bijective base 3.
  d2       Divmod 2; map each digit d to [d/2, d%2].
    Ḥ      Unhalve; multiply the results by 2.
     ’     Decrement the doubled results.
           The previous four atoms apply the following mapping to the digits.
               1 -> [0, 1] -> [0, 2] -> [-1,  1]
               2 -> [1, 0] -> [2, 0] -> [ 1, -1]
               3 -> [1, 1] -> [2, 2] -> [ 1,  1]
        Ç  Call the helper link with argument 3, yielding the following 2D array.
               [[ 1,  2,  2],
                [ 2,  1,  2],
                [ 2,  2,  3]]
      ×€   Multiply each [-1,  1], [ 1, -1], and [ 1,  1] by that matrix, using
           vectorizing multiplication (not matrix multiplication), yielding one 
           of the following three 2D arrays.

               [[-1,  2,  2],    [[ 1, -2,  2],    [[ 1,  2,  2],
                [-2,  1,  2],     [ 2, -1,  2],     [ 2,  1,  2],
                [-2,  2,  3]]     [ 2, -2,  3]]     [ 2,  2,  3]]
⁽0(ḃs      First helper link. Argument: 3

⁽0(        Numeric literal; yield 13041.
   ḃ       Convert 13041 to bijective base 3, yielding [1, 2, 2, 2, 1, 2, 2, 2, 3].
    s      Split the result into chunks of length 3, yielding the aforementioned
           2D array.

1

APL (NARS), 90 caratteri, 180 byte

{a⊃⍨⍵⊃⍋↑¨a←{⍵[⍋⍵]}¨a/⍨{1=∨/⍵}¨a←{(-/k),(×/2,⍵),+/k←⍵*2}¨a/⍨{>/⍵}¨a←,a∘.,a←⍳(⌊2⍟2+⍵)×9+⌊√⍵}

se l'argomento della funzione sopra è ⍵, la funzione sopra restituisce l'elemento dell'indice ⍵ (basato su 1) dell'array ha elementi triple pitagorici (a, b, c) dove a <= b <= c e quell'array è l'ordine prima per a, (il lato più corto), poi per b (l'altro lato non ipotenuso). Ci sarebbe qualcosa di sbagliato perché non si vede dove ordino anche b ... test:

  f←{a⊃⍨⍵⊃⍋↑¨a←{⍵[⍋⍵]}¨a/⍨{1=∨/⍵}¨a←{(-/k),(×/2,⍵),+/k←⍵*2}¨a/⍨{>/⍵}¨a←,a∘.,a←⍳(⌊2⍟2+⍵)×9+⌊√⍵}
  f¨1..10
3 4 5  5 12 13  7 24 25  8 15 17  9 40 41  11 60 61  12 35 37  13 84 85  15 112 113  16 63 65  

è in relazione con http://oeis.org/A020884 e http://oeis.org/A020884/b020884.txt

A020884: Ordinate gambe corte di triangoli pitagorici primitivi.

  ↑¨f¨1..23
3 5 7 8 9 11 12 13 15 16 17 19 20 20 21 23 24 25 27 28 28 29 31 
  f 999
716 128163 128165 
  f 1000
717 28556 28565 

Non so se sia giusto, sembra che la funzione dia il risultato corretto del primo lato del triangolo fino a 1000, ma non so per il resto, e possibile potrebbe essere un triplo non giusto nemmeno <1000.


0

JavaScript, 101 byte

Con la formula di Euclide, tutte le triple triple pitagoriche primitive possono essere generate da numeri interi me ncon m>n>0, m+ndispari gcd(m,n)==1( Wikipedia )

Questa funzione enumera tutte le m,ncoppie che incrementano m a partire da m=2e diminuendo ndi 2 a partire da m-1(quindi m+nè dispari)

c=>eval("g=(a,b)=>b?g(b,a%b):a;for(m=2,n=1;c-=g(m,n)<2;(n-=2)>0||(n=m++));[m*m-n*n,2*m*n,m*m+n*n]")

Meno golf

c => {
  g = (a,b) => b ? g(b,a%b) : a;
  for( m = 2, n = 1; 
       g(m,n) < 2 ? --c : c; 
       (n -= 2) > 0 || (n = m++))
    /* empty for body */;
  return [m*m - n*n, 2*m*n, m*m + n*n]
}

Test

F=
c=>eval("g=(a,b)=>b?g(b,a%b):a;for(m=2,n=1;c-=g(m,n)<2;(n-=2)>0||(n=m++));[m*m-n*n,2*m*n,m*m+n*n]")

for(i=1;i<=50;i++) console.log(i+' '+F(i))

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.