ピタゴラスのトリプルシーケンス


33

A ピタゴラストリプルように3つの正の整数、B、及びC、から成る2 + B 2 = C 2。このようなトリプルは一般的に(a、b、c)で記述され、よく知られた例は(3、4、5)です。(a、b、c)がピタゴラスのトリプルの場合、正の整数kの場合も(ka、kb、kc)です。原始的なピタゴラスのトリプルは、a、b、およびcが互いに素であるトリプルです。

この知識を使用して、最小長のトリプルを連結することでシーケンスを作成できます。シーケンスの次の要素は、長さの最小要素として前の要素を含む最小プリミティブピタゴラストリプルの斜辺(最大数)です。

最小のプリミティブピタゴラストリプル(3、4、5)から始めます。シーケンスはで始まり3、斜辺(シーケンスの次の要素)は5です。次に5、足として最小の原始的なピタゴラスのトリプルを見つけて、(5、12、13)を取得します。したがって、シーケンスはに続き13ます。

シーケンスを永久に出力するか、整数入力nを取りn、シーケンスの最初の要素(0または1のインデックス付き)を出力します。

少なくともを含む出力をサポートする必要があり28455997ますが、使用しているデータ型の制限が突然引き上げられた場合、その新しい制限に対応する必要があります。したがって、数字のリストをハードコーディングすることはできません。

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

OEIS A239381

同様のシーケンス(これらを出力しないでください!):


時間制限はありますか?
-Loovjo

@Loovjoいいえ、ただし、出力が正しいことを知っている/証明する必要があります。後に出力が異なる類似したシーケンスがいくつかあります12325
mbomb007

私が考えている同様のシーケンスは、後に異なり85ます...次の用語は3613(それが何であるかを推測できますか?)
ニール

@Neilすばやく検索すると、ピタゴラスのらせんであるA053630が得られます。ただし、実装の作成中に誤ってこれらの2つのシーケンスまたはそれらに類似したものに到達したため、チャレンジで2つを参照しました。
mbomb007

1
確かに、もっと目が覚めていたら、自分で調べただけだったかもしれません
ニール

回答:


11

ゼリー、19バイト

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

@ Dennisのおかげで、無限のシーケンスにリファクタリングして1バイト節約しました。

入力と引数を取りません。その後、各項を計算するたびに出力することにより、シーケンスを無限に出力します。この方法は、素因数分解に依存するため、数値が大きくなるにつれて遅くなります。

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

これは、現在の項の主な力の因数分解を計算することにより、次の項を計算します。12325の場合、これは{5 2、17、29}。ピタゴラスのトリプル{ abc } を計算するためのユークリッドの式の変形があります

formula

ここで、M > Nと三重プリミティブのIFFであり、M及びnは互いに素です。

12325から次のプリミティブルートを計算するには、mn = 12325になるようにmnを見つけ、gcd(mn)= 1になるようにmnを選択します。その後、{5 2のすべてのサブセットを作成して、mnのすべてのペアを生成します、17、29}および{1、25、17、29、425、725、493、12325}である各サブセットの積を見つけます。次に、12325を各値とペアで除算し、各ペアがmnになるようにします。各ペアを使用してcの式を計算し、最小値である90733を取得します。

  • 前の方法は、228034970321525477033478437478475683098735674620405573717049066152557390539189785244849203205の後の次の項を決定するために失敗しました。前の方法は、正しい選択が3番目と最後の素数である場合、最後の値を要因として選択しました。新しい方法はより低速ですが、すべてのコプリムのペアをテストして最小の斜辺を見つけるため、常に機能します。

説明

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

うわー、これは本当に速いです!
mbomb007

1
o3ṄÆfµṪ,P²SHß出力を無限にすると、バイトが節約されます。
デニス

5

Brachylog、36バイト

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

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

TIOが出力をフラッシュする前に、プログラムがタイムアウト(1分)するのを待つ必要があります。SWI-PrologのREPLでは、これは値が見つかるとすぐに印刷します。

これにより、シーケンスが永久に出力されます。

オフラインのSWI-Prologの通訳で数分後、私はを取得しまし9073312325。この時点で停止しました。

これは、ピタゴラスのトリプルを見つけるために制約を使用するため、完全なブルートフォースではありませんが、明らかに速度が最適化されていません。

説明

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

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

すべてのピタゴラストリプルa²+b²=c²a=r(m²-n²), b=2rmn, c=r(m²+n²)、いくつかの整数を満たしますr,m,n。場合r=1m,n正確に一つが2で割り切れることと互いに素であり、次いでa,b,c場合、三重プリミティブであるa,b,c全ての対の互いに素であるが。

これを念頭に置いて、いくつかを考えればa、ブルートフォースアルゴリズムを使用して、正方形nなどの最小値を計算しa²-n²ます。次に、cはに等しくなりn²+m²ます。


あなたの説明で考えられるタイプミス:あなたはnそれa+n²が正方形であることを探します。
ニール

2

Python 3、178バイト

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)

これは基本的にはブルートフォースアルゴリズムであり、非常に遅いです。入力として出力する用語の量が必要です。

このアルゴリズムの正確性については100%確信がありません。プログラムは最初のレッグの2乗まで他のレッグをチェックします。

repl.itで試してみてください!(期限切れ)(10より大きい数値では試さないでください。非常に遅くなります)


Python 3.5に切り替えてを使用できますmath.gcd。また、のp+=[...]代わりに使用しますp.append(...)。そして、<2代わりに==1。そして、ifすべてを1行に収めることができます。
mbomb007

1
私が提案した最後の2つの改善を行うことができます。
mbomb007


Loovjo、提案を使用してコードをゴルフするつもりですか?
mbomb007

2

MATL、27バイト

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

これにより、シーケンスの最初の項が生成されます。入力は0ベースです。

コードは非常に非効率的です。オンラインコンパイラは、を超える入力に対してタイムアウトし5ます。入力に6はオフラインで1分半かかりました(そして90733、6番目の用語として正しいものを作成しました)。

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

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

ラケット106バイト

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

ゴルフをしていない:

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

テスト:

(f)

ゴルフバージョンの出力:

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

改変されていないバージョンの出力:

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

(私のマシンでこの後のエラー)


ゴルフコードは、シーケンスの斜辺のみを出力します。非ゴルフバージョンでは、3つすべてを表示して、問題になっていないトリプレットを明確にします。
rnso


1

PHP、139バイト

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

上記のコードは、32ビットシステムで28455997の後に壊れます。より大きな数値が必要な場合、156バイトになります。

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

マイルのおかげで-25バイトMath.pow(n、2)の代わりにn * nを使用

マイルのおかげで-24バイトwhileの代わりにforループを使用し、データ型を変更し、操作の順序による()を排除

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

という事実を使用します

関係

整数の任意のペアm> n>0。したがって、CはAプラス2(N)2に等しいます。上記の関数は、ピタゴラスのトリプルの2番目の要素を整数にし、最初の要素よりも大きくする一方で、この関係を満たすNの最小値を見つけます。次に、最初の要素の値を3番目の要素に設定し、更新された最初の要素で繰り返します。

ゴルフをしていない:

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

できた!

*イデオンは時間制限のために最後の必要な要素を印刷しませんが、プログラムのロジックと非ゴルフバージョン(28455997を最初の要素ではなく以前のピタゴラスのトリプルの3番目の要素として印刷します)次)、値は、より高い制限時間で印刷されます。


n*n代わりに使用できませんMath.pow(n,2)か?
マイル

どうしてそんなことを考えなかったのか分かりません…それをすぐに追加します。ありがとう@miles
マリオ

forループを使用して133バイトに減らすためにもう少し削りました()->{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;}};
マイル

1

Python 3.5、97バイト

28455997浮動小数点データ型の制限のため、の後の出力が間違っています。このsqrt関数は十分ではありませんが、精度が魔法のように向上した場合は機能します。

わかりやすい。c1の代わりに2をインクリメントすると、ランタイムが半分になり、要素が常に奇数であるため、とにかく奇数のみをチェックする必要があります。

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

オンラインで試す

IdeoneはPython 3.4を使用しているため、プログラムをIdeoneで実行することはできません


出力をより正確に保つには、次を使用する必要があります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

オンラインで試す

いつまでも正確に保つために、私はこのような恐ろしいことをすることができます(反復ごとに必要な精度を上げる:

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

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}

qの引数として14までテストok:

  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
  ∧

これは、その引数のすべての約数を見つけるでしょう...

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

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