プリミティブピタゴラストリプル


29

関連

A ピタゴラストリプルリストで(a, b, c)満たす式その2 + B 2 = C 2

プリミティブピタゴラストリプル(PPT)を一度ここでありabおよびc全てである互いに素(すなわち、三つの要素の間の唯一の公約数です1)。たとえば、(3, 4, 5)直角三角形は有名な原始的なピタゴラストリプルです。

チャレンジ

  • inputが与えられるとnnth PPTを出力します。または、
  • inputを指定するnと、最初のnPPTが出力されます。

これらのPPTを順序付けて適切な順序のリストを作成し、どちらがnthであるかを判断する方法は複数あります。アルゴリズムがすべての可能な一意のPPTを生成できることを証明できる(非公式には問題ありません)限り、任意の順序を選択できます。たとえば、コードは両方(3,4,5)を出力すべきではありません。(4,3,5)これらは同じトリプルの複製なので、どちらか一方を出力してください。

同様に、使用しているコードを記述している限り、コードのインデックスが0か1かは問題ありません。

以下の例では、1つのインデックスを使用し、nth PPTを出力し、最小値c、最小値a、最小値の順に並べていbます。

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

ルール

  • 入力と出力は、任意の便利な形式で指定できます
  • 提出する際には、エントリの順序、およびエントリのインデックスが0か1かを明記してください。
  • 選択した順序で複製を作成することはできません。
  • 完全なプログラムまたは機能のいずれかが受け入れられます。関数の場合、出力する代わりに出力を返すことができます。
  • 可能であれば、他の人があなたのコードを試すことができるように、オンラインテスト環境へのリンクを含めてください!
  • 標準的な抜け穴は禁止されています。
  • これはので、通常のゴルフルールがすべて適用され、最短のコード(バイト単位)が勝ちます。



サポートしなければならない最高のインプットは何ですか?選択した言語の機能に適合すると仮定できますか?
ミスターXcoder

1
@ Mr.Xcoderはい。これを使用して、抜け穴(たとえば、言語が1ビットの数値のみをサポートする)を利用して問題を些細なものにしない限り、これは標準的な安全な仮定です。
-AdmBorkBork

2
aとbが互いに素でなければならず、これは十分である:私は私の質問への答えを見つけたproofwiki.org/wiki/...
edc65

回答:


12

ゼリー27 25バイト

ジョナサンアランのおかげで2バイト。

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

オンラインでお試しください!

最初のn1インデックス付きトリプルを出力し、[b, a, c]増加してbからでソートしaます。

ウィキペディアのアルゴリズムを使用します:

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

これにより、奇数の整数のすべての一意の互いに素なペアに対してすべてのプリミティブトリプルが生成されますm > n > 0

説明

+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].

それは本当にいい説明です。ありがとう!
AdmBorkBork

g/Ị$Ðf-> g/ÐṂ2バイトを節約します(最小gcdは1であり、少なくとも1つのそのようなエントリがあるため)。
ジョナサンアラン

別のバイトはまた置換することによって(それはあまり効率化が)保存することができる+2ḶḤ‘Œc²Rm2Œc-スクラップそのことを入力するための習慣作業1:(
ジョナサンアラン

@JonathanAllan最小限のものをありがとう。2バイトの範囲をたくさん試しましたが、残念ながら十分な大きさのものはありませんでした。(²ḶḤ‘Œc私が考えた最初の1つだった。)
PurkkaKoodari

8

MATL、36バイト

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

入力は1ベースです。出力順序により、各トリプルが1回だけ出現することが保証されます。以下に順序を説明します。この説明では、プログラムの動作を少し掘り下げる必要があります。

コードはk、で始まるループ内のカウンターを増やし続け1ます。それぞれk、、、ですべてのペアを生成しa = 1,...,kb = 1,...,ka < bピタゴラスのトリプルを与えるものを選択しc <= kます。ペアが増加する順に取得されb、その後、a

次に、各ペアをgcdで分割します。結果の(おそらく複製された)ペアは、2列の行列として配置されます。この行列は、の小さい値で得られた累積結果を含む同様の行列と垂直に連結されますk。その後、マトリックスの行は安定して重複排除されます。これにより、2種類の重複が削除されます。

  1. 電流に対して複数回見つかったペアk(gcdで除算したときに3,4も発生するなど6,8)。

  2. より小さいですでに見つかったペアk

実際、各反復kは、以前の反復ですでに見つかったすべてのペアを検出します。しかし、それらは異なる順序で見つかるかもしれません。たとえばk=25、トリプルを検索しますが、検索できませ7,24,2520,21,29(をc超えることはできませんk)。後で、反復k=29は両方を検出しますが、20,21,29 beforeを使用します 7,24,25(順序は増加しb、次にa)。これが、最新kので見つかったすべてのペアを保持する代わりに、前のペアに追加して安定して重複排除する理由です。そうすることで、入力がどの順序でも同じになることが保証されますn

上記により、各プリミティブピタゴラストリプルが最終的に表示され、一度だけ表示されることが保証されます。入力の場合、少なくとも有効なトリプルが取得されるnと、ループオーバーがk終了しnます。そして、n-thトリプルは出力です。

オンラインでお試しください!

または、この変更されたコードを使用して、最初のnトリプルを確認します。

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

オンラインでお試しください!


1
いい説明。
-AdmBorkBork


5

ゼリー19 18バイト

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

プログラムは1から始まるインデックスnを取得し、最初のn個の PPT [c、b、a]を辞書式順序で出力します。

これはO(64 nソリューションであるため、TIOは入力4以上でチョークします。私はそれをより速くすることに取り組みます。

オンラインでお試しください!

代替バージョン、O(n 3)、おそらく有効

見つけるためにN 番目 -トリプレット[C 、N、B NN ] -上記の溶液と、その前提とし、C N ≤4 Nを確認することは容易です。しかし、A020882は、その証明C N〜2πNをそれほどあり、kのようにC 、N ≤KNすべてについて、nは

k = 7をとることができる場合、以下の解も有効です(はるかに高速です)。

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

オンラインでお試しください!

使い方

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バイト

N番目のPPTを出力します。結果には1のインデックスが付けられ、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)

デモ


4

MATL、63バイト

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

オンラインでお試しください!

ゴルフのレッスンはひどく間違っていました。とにかくこれを投稿しているのは、これをもっと良くする方法があるかどうか疑問に思っているからです。

このウィキペディアのページに基づいて、ユークリッドの式と組み合わせて、試行錯誤のアプローチではなく、すべてのトリプルを建設的に生成しました。

最初に、奇数の素数ペアが三分木として生成されます。これは、バイトカウントの大部分を占める大きな行列乗算として行われます。次に、ユークリッドの式が適用されますが、これも非常にバイトを浪費する可能性があります。誰かがこれらの2つの部分のヒントを持っているなら、私はそれらを聞きたいです。

バイトを節約するために、このプログラムはを入力するのではなく、入力と同じ深さのツリーを生成することに注意してくださいlog3(n)。また、子はツリーの最後の行だけでなく、各行ごとに生成され、で再度フィルタリングされXuます。効率的で建設的なアプローチにはこれで終わりです。

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バイト

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

0ベースのインデックス付け。与えられたためにcbまで走るcaまでbそう、c > b > a常に保持しています。

オンラインでお試しください!


3

Python、 67 50 48 46バイト

ウィキペディアにある式を使用して、

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

どこm>n>0mncoprimesと奇数です。ここにコードがあります

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

@Martin Enderのおかげで-17バイト

オンラインで試す

いつもの値を有する作品nつまり、1である式の変数をm単にこの場合に、任意の他の奇数値である原始的ピタゴラス三重の数です。これにより、すべての値に対して1の値を想定できます。3+2*nnn


PPCGへようこそ!名前のない関数は問題ないので、ラムダを割り当てる必要はありませんa(その場合、2つのスペースを削除できます)。またprint、なぜそこにいるのかわかりませんが、ラムダ自体から値を返すことができます。
マーティンエンダー

「アルゴリズムがすべての可能な一意のPPTを生成できることを証明できます(非公式には問題ありません)。」ただし、この方法では、斜辺が脚よりも1長いもののみが生成されます。たとえば、8,15,17を生成することはありません。
ロージーF

2

、18バイト

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

オンラインでお試しください!

デニスからインスピレーションを得て、Zgarbに4バイト感謝

超低速のブルートフォースアプローチ。1より大きい入力のTIOでは機能しません。a、b≤200に制限された、より管理しやすいバージョンを試すことができます。 、ここで

説明

↑ü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バイト、さらに遅くなります。
ズガルブ

@Zgarbありがとう!私は余分なバイトをゴルフすることに成功しました:)
レオ

デニスのゼリーの回答からの減算のトリックを使用した18バイト
ズガルブ

@Zgarbいいね!疑問がありますが、同じトリプルが2つある可能性はありますcか?その場合、この解決策を修正する必要があります
レオ

うーん、実際には同じを持つ多くのトリプルがありcます。この18バイトのソリューション(デニスの別のトリックを使用)は、関係なく動作します。
ズガルブ

1

Mathematica、89バイト

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バイト

(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(+数字)、88バイト

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

組み込み関数を使用して数値を生成する場合、実際に必要なものを取得するには驚くべき量のバイトが必要です。組み込み関数は2つの引数c1とを取りc2、を持つ3 つ組を返しますc >= c1 & c <= c2。これにより、n-thトリプレットに到達するのが少し面倒になります。これはただ増え続けますc2、出力が十分な行になるまで、一度に1ずつます。


1

PHP、273バイト

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) [a、b、c]の配列を順序付けして返します a < b < c
  • ゼロベースのインデックスを返します

オンラインでお試しください!(コードもそこに読み取り可能です)


1

C、158バイト

私はこれがここでの私の最初の提出であると信じているので、おそらくあなたはもっと良くすることができます。

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

そして、無料版:

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

ため2 + B 2 = C 2、順序が増加して、Cを次に増やします。

何回同じPPTがあってはいけませんbはのLEAにあるこのアルゴリズムインチ


PPCGへようこそ!
-JAD

1

ゼリー27 25バイト

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

これは、分岐順序が異なる@AndersKaseorgのHaskell answerからのツリーアプローチの実装です。プログラムは0から始まるインデックスを使用し、STDINから入力を受け取ります。

オンラインでお試しください!

バックグラウンド

Wikipediaページのプリミティブピタゴラストリプルのツリーで述べたように、すべてのPPTは、行ベクトル(3、4、5)に特定のプロパティを持つ行列を繰り返し左乗算することで取得できます。

各反復で、前の結果にAB、またはCを左乗じることができます。これは次のように選択できます。

行列

場合AB、及びCが固定され、各PPTは、ユニークな方法で得ることができます。

使い方

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文字、180バイト

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

上記の関数の引数がifの場合、上記の関数は配列のインデックスelement(1から始まる)の要素を返します。最初にa(より短い側)の順序、次にb(斜辺ではない反対側)の順序です。私もbを注文した場所が見られないので、何か間違っているでしょう...テスト:

  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  

http://oeis.org/A020884およびhttp://oeis.org/A020884/b020884.txtと関連しています

A020884:原始的なピタゴラスの三角形の短い脚を注文しました。

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

私はそれが正しいかどうかはわかりません、それは関数が1000まで三角形の最初の辺の正しい結果を与えるようですが、私は残りについては知りません、そして可能性は<1000でも正しくないトリプルかもしれません。


0

JavaScript、101バイト

ユークリッドの式では、すべての原始的ピタゴラスのトリプルは、整数から生成することができるmnしてm>n>0m+n奇数gcd(m,n)==1ウィキペディア

この関数は、すべての列挙m,n対増分Mから出発m=2し、デクリメントnから出発2によってm-1(その結果がm+n奇数です)

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

少ないゴルフ

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

テスト

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.