Triples pythagoriciens primitifs

29

( lié )

Un triple de Pythagore est une liste (a, b, c)qui satisfait l'équation a 2 + b 2 = c 2 .

Un triple pythagoricien primitif (PPT) est celui où a, bet csont tous des coprimes (c'est-à-dire que le seul diviseur commun entre les trois éléments est 1). Par exemple, le (3, 4, 5)triangle rectangle est un fameux triple primitif de Pythagore.

Le défi

  • Étant donné l'entrée n, la sortie du nth PPT. Ou,
  • Étant donné l'entrée n, nsortez les premiers PPT.

Il existe plusieurs façons de commander ces PPT pour former une liste bien ordonnée, afin de déterminer quel est le nth. Vous pouvez choisir n'importe quel ordre que vous souhaitez, tant que vous pouvez prouver (informellement, c'est bien) que votre algorithme peut générer tous les PPT uniques possibles. Par exemple, votre code ne devrait pas sortir les deux (3,4,5)et (4,3,5)puisque ce sont des doublons du même triple - l'un ou l'autre, s'il vous plaît.

De même, que votre code soit à zéro ou à un index est correct, tant que vous indiquez lequel vous utilisez.

Exemples

Pour les exemples ci-dessous, j'utilise l'indexation unique, la sortie du nPPT et la commande par le plus petit c, puis le plus petit a, puis le plus petit b.

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

Règles

  • L'entrée et la sortie peuvent être données dans n'importe quel format pratique .
  • Dans votre soumission, veuillez indiquer comment vos entrées sont classées et si vos entrées sont indexées 0 ou 1.
  • La commande que vous avez choisie ne peut pas créer de doublons.
  • Un programme complet ou une fonction sont acceptables. S'il s'agit d'une fonction, vous pouvez renvoyer la sortie plutôt que de l'imprimer.
  • Si possible, veuillez inclure un lien vers un environnement de test en ligne afin que d'autres personnes puissent essayer votre code!
  • Les failles standard sont interdites.
  • Il s'agit de donc toutes les règles de golf habituelles s'appliquent et le code le plus court (en octets) l'emporte.
AdmBorkBork
la source
Connexes
miles
2
A103606 .
miles
Quelle est la contribution la plus élevée que nous devons soutenir? Pouvons-nous supposer qu'il correspond aux capacités de notre langue de choix?
M. Xcoder
1
@ Mr.Xcoder Oui; c'est une hypothèse sûre standard, à moins que vous ne l'utilisiez pour exploiter une faille (par exemple, le langage ne prend en charge que les nombres à 1 bit) pour rendre le problème trivial.
AdmBorkBork
2
J'ai trouvé la réponse à ma question: a et b doivent être coprimes et c'est suffisant proofwiki.org/wiki/…
edc65

Réponses:

12

Gelée , 27 25 octets

2 octets merci à Jonathan Allan.

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

Essayez-le en ligne!

Génère les premiers ntriplets indexés sur 1 [b, a, c], triés par augmentation bpuis a.

Utilise l'algorithme de Wikipedia :

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

Cela génère tous les triplets primitifs pour toutes les paires uniques de nombres entiers impairs m > n > 0.

Explication

+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].
PurkkaKoodari
la source
Voilà une très belle explication. Merci!
AdmBorkBork
g/Ị$Ðf-> g/ÐṂpour enregistrer deux octets (car le gcd minimal est 1 et il y aura toujours au moins une telle entrée).
Jonathan Allan
Un autre octet peut également être enregistré (bien qu'il le rende moins efficace) en remplaçant +2ḶḤ‘Œcpar ²Rm2Œc- scrap qu'il ne fonctionnera pas pour une entrée de 1:(
Jonathan Allan
@JonathanAllan Merci pour le minimum. J'ai essayé beaucoup de plages de 2 octets, mais malheureusement aucune n'était assez grande. (a ²ḶḤ‘Œcété l'un des premiers
auxquels
8

MATL , 36 octets

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

L'entrée est basée sur 1. L'ordre de sortie garantit que chaque triple apparaît exactement une fois. L'ordre est expliqué ci-dessous. L'explication nécessite d'approfondir un peu le fonctionnement du programme.

Le code continue d'augmenter un compteur kdans une boucle, à partir de 1. Pour chaque kil génère toutes les paires avec a = 1,...,k, b = 1,...,k, a < b, et des pics ceux qui donnent une triple avec Pythagore c <= k. Les paires sont obtenues par ordre croissant b, puisa .

Chaque paire est ensuite divisée par son pgcd. Les paires résultantes (éventuellement dupliquées) sont organisées sous forme de matrice à deux colonnes. Cette matrice est concaténée verticalement avec une matrice similaire contenant les résultats cumulés obtenus pour des valeurs plus petites de k. Les lignes de la matrice sont ensuite dédupliquées de manière stable. Cela supprime deux types de doublons:

  1. Paires qui ont été trouvées plus d'une fois pour le courant k(comme 3,4, qui résulte également de la 6,8division par son pgcd);

  2. Des paires qui étaient déjà trouvées avec des plus petites k.

En fait, chaque itération ktrouve toutes les paires qui ont déjà été trouvées pour les itérations précédentes. Mais il peut les trouver dans un ordre différent . Par exemple, k=25trouvera le triple 7,24,25et non 20,21,29(car cne peut pas dépasser k). Plus tard, l'itération k=29trouvera les deux, mais avec 20,21,29 avant 7,24,25 (l'ordre augmente balors a). C'est pourquoi, au lieu de conserver toutes les paires trouvées pour la dernière k, nous les ajoutons aux précédentes et dédupliquons de manière stable. Cela garantit que l'ordre est le même pour n'importe quelle entrée n.

Ce qui précède garantit que chaque triple primitif de Pythagore apparaîtra finalement et n'apparaîtra qu'une seule fois. Pour l'entrée n, la boucle se ktermine quand au moins des ntriplets valides ont été obtenus; puis le n-ième triple est ouput.

Essayez-le en ligne!

Ou utilisez ce code modifié pour voir les premiers ntriplets:

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

Essayez-le en ligne!

Luis Mendo
la source
1
Belle explication.
AdmBorkBork
5

Gelée , 19 18 octets

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

Le programme prend un index n basé sur 1 et imprime les n premiers PPT [c, b, a] dans l'ordre lexicographique.

Il s'agit d'une solution O (64 n ) , donc TIO s'étouffera sur les entrées 4 et supérieures. Je vais travailler pour le rendre plus rapide.

Essayez-le en ligne!

Version alternative, O (n 3 ), probablement valide

Pour trouver le n ième triplet - [c n , b n , a n ] - la solution ci - dessus suppose que c n ≤ 4 n , est de vérifier facilement. Cependant, A020882 prouve que c n ~ 2πn , donc il y a un k tel que c n ≤ kn pour tout n .

Si nous pouvons prendre k = 7 , la solution ci-dessous est également valide (et beaucoup plus rapide).

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

Essayez-le en ligne!

Comment ça marche

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².
Dennis
la source
4

JavaScript (ES7), 106 105 103 octets

Sort le Nth PPT. Les résultats sont indexés 1 et classés par la valeur de 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)

Démo

Arnauld
la source
4

MATL , 63 octets

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

Essayez-le en ligne!

Une leçon de golf a terriblement mal tourné. Je le poste quand même parce que je me demande s'il existe des moyens de mieux jouer au golf.

J'ai basé ça sur ça page Wikipédia en combinaison avec la formule d'Euclide, pour générer de manière constructive tous les triplets plutôt que les approches par essais et erreurs.

Tout d'abord, les paires de coprimes impaires sont générées sous forme d'arbre ternaire. Cela se fait comme une grande multiplication matricielle, représentant la majeure partie du nombre d'octets. Ensuite, la formule d'Euclide est appliquée, peut-être aussi d'une manière très gaspilleuse d'octets. Si quelqu'un a des conseils pour ces deux parties, j'aimerais bien les entendre.

Notez que, pour économiser des octets, ce programme génère un arbre de la même profondeur que l'entrée, plutôt que log3(n). En outre, les enfants sont générés pour chaque ligne plutôt que uniquement pour la dernière ligne de l'arborescence, puis filtrés à nouveau avec Xu. Voilà pour une approche constructive efficace.

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²
Sanchises
la source
3

Haskell, 65 octets

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

Indexation basée sur 0. Pour une donnée c, bva jusqu'à cet ajusqu'à b, donc c > b > atient toujours.

Essayez-le en ligne!

nimi
la source
3

Python, 67 50 48 46 octets

En utilisant les formules trouvées sur wikipedia,

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

m>n>0et met nsont des nombres premiers et impairs. Voici le code

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

-17 octets grâce à @Martin Ender

Essayez-le en ligne

Fonctionne en ayant toujours la valeur de la nvariable dans l'équation étant 1, ce qui signifie qu'il ms'agit simplement de toute autre valeur impaire, dans ce cas, 3+2*nnest le numéro du triple de Pythagore primitif. Cela nous permet de supposer la valeur 1 pour toutes les nvaleurs.

Professor_Joykill
la source
Bienvenue chez PPCG! Les fonctions sans nom sont très bien, vous n'avez donc pas besoin d'attribuer le lambda a(et si vous le faisiez, vous pourriez vous débarrasser des deux espaces). Je ne sais pas non plus pourquoi vous printlà-bas, vous pouvez simplement retourner les valeurs du lambda lui-même.
Martin Ender
"vous pouvez prouver (officieusement bien) que votre algorithme peut générer tous les PPT uniques possibles". Mais cette méthode ne génère que celles où l'hypoténuse est 1 plus longue qu'une jambe. Il n'en génère jamais 8,15,17, par exemple.
Rosie F
2

Husk , 18 octets

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

Essayez-le en ligne!

-4 octets merci à Zgarb, avec l'inspiration de Dennis

Approche de force brute ultra-lente, ne fonctionnera pas sur TIO pour des entrées supérieures à 1. Vous pouvez essayer une version plus facile à gérer, limitée à a, b≤200 ici

Explication

↑ü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
Leo
la source
20 octets en combinant la carte et le filtre, encore plus lentement.
Zgarb
@Zgarb merci! J'ai réussi à jouer au golf un octet supplémentaire :)
Leo
18 octets avec l'astuce de soustraction de la réponse Jelly de Dennis.
Zgarb
@Zgarb nice! Bien que j'aie un doute: pourrait-il y avoir deux triplets différents avec le même c? dans ce cas, cette solution devrait être corrigée
Leo
Hmm, en fait il y a beaucoup de triples avec le même c. Cette solution de 18 octets (qui utilise une autre astuce de Dennis) fonctionne malgré tout.
Zgarb
1

Mathematica, 89 octets

en utilisant Solve ordonné par 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 octets

(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][[#]])&
J42161217
la source
1

R (+ numéros), 88 octets

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

Pour utiliser une fonction intégrée pour générer les nombres, il faut en fait une quantité surprenante d'octets pour obtenir ce que nous voulons. Le builtin prend deux arguments c1et c2, et retourne les triplets qui ont c >= c1 & c <= c2. Cela rend légèrement ennuyeux le ntriplet. Cela ne fera qu'augmenter c21 à la fois jusqu'à ce que la sortie soit juste assez de lignes.

JAD
la source
1

PHP , 273 octets

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) renvoie un tableau de [a, b, c] avec ordre a < b < c
  • Renvoie un index de base zéro

Essayez-le en ligne! (le code y est également lisible)

Mic1780
la source
1

C, 158 octets

Je crois que c'est ma première soumission ici, vous pouvez donc probablement faire mieux.

#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++;};}

Et version non golfée:

#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");
}

Pour a 2 + b 2 = c 2 , l'ordre augmente c puis augmente a .

Il ne peut pas y avoir deux fois le même PPT que b est au moins a dans cet algorithme.

Tsathoggua
la source
Bienvenue chez PPCG!
JAD
1

Gelée , 27 25 octets

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

Il s'agit d'une implémentation de l'approche arborescente de la réponse Haskell de @ AndersKaseorg , avec un ordre de branchement différent. Le programme utilise une indexation basée sur 0 et prend les données de STDIN.

Essayez-le en ligne!

Contexte

Comme mentionné sur la page Wikipedia Arbre des triplets pythagoriciens primitifs , chaque PPT peut être obtenu en multipliant à plusieurs reprises à gauche le vecteur ligne (3, 4, 5) par des matrices ayant certaines propriétés.

Dans chaque itération, le résultat précédent peut être multiplié à gauche par A , B ou C , qui peuvent être choisis comme suit.

matrices

Lorsque A , B et C sont fixes, chaque PPT peut être obtenu d'une manière unique.

Comment ça marche

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.
Dennis
la source
1

APL (NARS), 90 caractères, 180 octets

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

si l'argument de la fonction ci-dessus est ⍵, la fonction ci-dessus retournerait l'élément de l'index ⍵ (basé sur 1) du tableau a des éléments triplets pythagoriciens (a, b, c) où a <= b <= c et ce tableau est d'ordre d'abord pour a, (le côté le plus court), puis pour b (l'autre côté n'est pas hypoténuse). Il y aurait quelque chose de mal car on ne voit pas où je commande pour b aussi ... 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  

il est lié à http://oeis.org/A020884 et http://oeis.org/A020884/b020884.txt

A020884: Jambes courtes ordonnées de triangles pythagoriciens primitifs.

  ↑¨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 

Je ne sais pas si c'est vrai, il semble que la fonction donne un résultat correct du premier côté du triangle jusqu'à 1000, mais je ne sais pas pour le reste, et il pourrait y avoir un triple non pas trop, même <1000.

RosLuP
la source
0

JavaScript, 101 octets

Par la formule d'Euclide, tous les triplets primitifs de Pythagore peuvent être générés à partir d'entiers met navec m>n>0, m+nimpair gcd(m,n)==1( Wikipedia )

Cette fonction énumère toutes les m,npaires incrémentant m à partir de m=2et décrémentant nde 2 à partir de m-1(ce qui m+nest impair)

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]")

Moins 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]
}

Tester

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

edc65
la source