ペル方程式の基本解


28

正方形ではない正の整数nが与えられた場合、関連するペル方程式の基本解を見つけるバツy

バツ2ny2=1

詳細

  • 基本は、が最小で正の方程式を満たす整数ペアです。(数えられない些細な解が常にあります。)バツyバツyバツバツy=10
  • は正方形ではないと仮定できます。n

 n           x    y
 1           -    -
 2           3    2
 3           2    1
 4           -    -
 5           9    4
 6           5    2
 7           8    3
 8           3    1
 9           -    -
10          19    6
11          10    3
12           7    2
13         649    180
14          15    4
15           4    1
16           -    -
17          33    8
18          17    4
19         170    39
20           9    2
21          55    12
22         197    42
23          24    5
24           5    1
25           -    -
26          51    10
27          26    5
28         127    24
29        9801    1820
30          11    2
31        1520    273
32          17    3
33          23    4
34          35    6
35           6    1
36           -    -
37          73    12
38          37    6
39          25    4
40          19    3
41        2049    320
42          13    2
43        3482    531
44         199    30
45         161    24
46       24335    3588
47          48    7
48           7    1
49           -    -
50          99    14
51          50    7
52         649    90
53       66249    9100
54         485    66
55          89    12
56          15    2
57         151    20
58       19603    2574
59         530    69
60          31    4
61  1766319049    226153980
62          63    8
63           8    1
64           -    -
65         129    16
66          65    8
67       48842    5967
68          33    4
69        7775    936
70         251    30
71        3480    413
72          17    2
73     2281249    267000
74        3699    430
75          26    3
76       57799    6630
77         351    40
78          53    6
79          80    9
80           9    1
81           -    -
82         163    18
83          82    9
84          55    6
85      285769    30996
86       10405    1122
87          28    3
88         197    21
89      500001    53000
90          19    2
91        1574    165
92        1151    120
93       12151    1260
94     2143295    221064
95          39    4
96          49    5
97    62809633    6377352
98          99    10
99          10    1

関連するOEISシーケンス:A002350 A002349 A033313 A033317


ペル方程式はまだよく知られていたので、まだまだ問題がないことに驚いていました。少なくとも、プロジェクトオイラーチャレンジで時々使用したことを覚えています。
ケビンクルーッセン

@Fatalize " nは正方形ではないと仮定することができます。n "ただし、テストケースでこれらのimhoが省略されている場合は、おそらくより明確になります。
ケビンクルーッセン

2
@KevinCruijssen私はそれを考えましたが、いくつかのns を省略するほうがもっと混乱するだろうと思いました。(ところで私も
驚き

回答:


16

Piet、612コーデル

標準入力からnを取得します。yを出力してからxをスペース区切りで出力します。

コーデルサイズ1: コーデルサイズ1のペルの方程式プログラム

Codelサイズ4、見やすくするため: コーデルサイズ1のペルの方程式プログラム

説明

入力値99の解を計算するプログラムを示すこのNPietトレースを確認してください。

この挑戦の前にペルの方程式を聞いたことがあるかどうかはわかりません。そのため、ウィキペディアから次のすべてを入手しました。具体的には、次の3つの記事のセクション:

基本的に、これは次のことです。

  1. 標準入力からnを取得します。
  2. 検索nそのカウンターがnを超えるまでカウンターを増分し、その後1回減分します。(これは、トレースの左上にある最初のループです。)
  3. √の連続分数からバツおよびyを計算するための変数を設定しますn
  4. バツyがまだペルの方程式に適合するかどうかを確認します。存在する場合、値を出力し(これは横断方向の約2/3の下向き分岐です)、終了します(一番左の赤いブロックに実行して)。
  5. そうでない場合は、変数を繰り返し更新し、手順4に戻ります(これは、右に出て、下に戻って、途中までではなく再結合します)。

率直に言って、ブルートフォースアプローチの方が短いかどうかはわかりません。試してみるつもりはありません。 さて、それで試してみました。


9

Piet、184コーデック

これは、私が書きたくないと言ったブルートフォースの選択肢です(他の答えで)。n = 13の解を計算するのに2分以上かかります。n = 29で試してみたいとは本当に思いませんが... 20 までのnごとにチェックアウトするので、正しいと確信しています。

他の回答のように、これはとりN標準入力と出力からY、次にX、スペースで区切られました。

コーデルサイズ1: コーデルサイズ1のペルの方程式プログラム(ブルートフォースバリアント)

Codelサイズ4、見やすくするため: コーデルサイズ4のペルの方程式プログラム(ブルートフォースバリアント)

説明

入力値5 のNPietトレース次のとおりです。

これはブルートフォースの中で最も残忍で、バツy両方を繰り返します。他のソリューションでは、バツを反復処理してからy = √を計算する場合がありますy=バツ21n、しかしそれらは弱虫です。

バツ=2およびy=1から開始し、バツおよびyが方程式をまだ解いているかどうかを確認します。(右近くの下部にあるフォーク)がある場合、値を出力して終了します。

そうでない場合は、左に進み、yが増分されてバツと比較されます。(それから、ジグザグの経路をたどる方向転換があります。)

この最後の比較では、パスが左中央付近で分割されます。それらが等しい場合、バツは増分され、yは1に戻されます。そして、それがまだ解決策であるかどうかのチェックに戻ります。

まだ空白が残っているので、プログラムを拡大せずに平方根計算を組み込むことができるかどうかを確認します。


2
ハハ私は平方根を使用する弱虫について同意します:D
flawr

6

Brachylog、16バイト

;1↔;Ċz×ᵐ-1∧Ċ√ᵐℕᵐ

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

説明

;1↔                Take the list [1, Input]
   ;Ċz             Zip it with a couple of two unknown variables: [[1,I],[Input,J]]
      ×ᵐ           Map multiply: [I, Input×J]
        -1         I - Input×J must be equal to 1
          ∧        (and)
           Ċ√ᵐ     We are looking for the square roots of these two unknown variables
              ℕᵐ   And they must be natural numbers
                   (implicit attempt to find values that match those constraints)

5

パリ/ GP、34バイト

PARI / GPには、ほとんどこれが組み込まれています。 quadunit与え基本単位二次フィールド QD、ここでDはフィールドの判別式です。換言すれば、quadunit(4*n)解決ペル方程式バツ2ny2=±1。そのため、そのノルムが1ときに正方形を取る必要があります。

使用するアルゴリズムはわかりませんが、nが平方フリーでない場合でも機能します。

回答は、フォームに記載されているx + y*ww意味n

n->(a=quadunit(4*n))*a^(norm(a)<0)

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


4

Wolfram言語(Mathematica)、46バイト

FindInstance[x^2-y^2#==1&&x>1,{x,y},Integers]&

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


1
これにより常に基本的な解決策が見つかることが保証されますか?
グレッグマーティン

@GregMartinはい、そうです。これは常に最初の(最小の)解決策を見つけます。この場合、これは常に{1,0}を返します。そのため、x> 1を選択し、2番目の(基本的な)ソリューションを取得する必要があります
J42161217

1
私はそれが真実になりたい、しかしでは何もドキュメントが ....それを示すように思わない
グレッグ・マーティン

@GregMartinこの関数を何度も使用しましたが、どのように機能するかはすでにわかっていました。私の唯一の懸念は、最初の解決策をスキップすることであり、それはそれらの5つの余分なバイトを犠牲にしました。プログラムを簡単に作成してテストできます(数百万の結果を確認するためだけに)
J42161217

4

05AB1E17 16 14バイト

Kevin Cruijssenのおかげで1バイト節約できました
出力[y, x]

∞.Δn*>t©1%_}®‚

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

説明

∞                 # from the infinite list of numbers [1 ...]
 .Δ        }      # find the first number that returns true under
   n              # square
    *             # multiply with input
     >            # increment
      t©          # sqrt (and save to register as potential x)
        1%        # modulus 1
          _       # logical negation
            ®‚    # pair result (y) with register (x)

そして、あなたは再び私に勝ちました.. 17バイトもありましたがŲ、小数でバグがあるために動作しませんでした..>。<とにかく、両方,を削除して末尾を追加できます(いいえ、コンマは同じ; p)バイトを保存します。
ケビンクルーッセン

@KevinCruijssen:ありがとう!ええ、私はまたŲ、期待どおりに機能しないことに最初に気付きました。
エミグナ

4

Java 8、74 73 72バイト

n->{int x=1;var y=.1;for(;y%1>0;)y=Math.sqrt(-x*~++x/n);return x+" "+y;}

@Arnauldのおかげで-1バイト。
-1バイトのおかげで@OlivierGrégoireの

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

説明:

n->{                 // Method with double parameter and string return-type
  int x=1;           //  Integer `x`, starting at 1
  var y=.1;          //  Double `y`, starting at 0.1
  for(;y%1>0;)       //  Loop as long as `y` contains decimal digits:
    y=               //   Set `y` to:
      Math.sqrt(     //    The square-root of:
        -x*          //     Negative `x`, multiplied by
           ~++x      //     `(-x-2)` (or `-(x+1)-1)` to be exact)
                     //     (because we increase `x` by 1 first with `++x`)
               /n);  //     Divided by the input
  return x+" "+y;}   //  After the loop, return `x` and `y` with space-delimiter as result

1
72バイトに変化するnことによってdouble、およびxに等しいintという事実でプレーx*x-1する(-x-1)*(-x+1)
オリビエグレゴワール

まあ、私は実際に、完全に正しい(x+1)*(x+1)-1と等しいという事実で遊んでい-x*-(x+2)ます。
オリビエグレゴワール

3

R、66 56 54 53 52 47 45バイト

完全なプログラム

n=scan();while((x=(1+n*T^2)^.5)%%1)T=T+1;x;+T

-1 -2 @Giuseppeに感謝

-7 @Giuseppe&@Robin Ryder -2 @JADに感謝


1
.5代わりに使用0.5
ジュゼッペ

5
46バイト。の最小値xを見つけることは、の最小値を見つけることと同等ですy。これは、あなたが表現するために2バイトを保存することができますxの面でy周りの他の方法よりも短く、使用してのトリック使って、4バイトT1に初期化されているが
ロビン・ライダー

1
@RobinRyderの最後にが必要になる場合がありますが、代わりに戻る+Tときy==1に確認する必要がありますが、完全にはわかりません。1TRUE
ジュゼッペ

3
@Giuseppeまあまあ!あなたが正しいです。それは47バイトになります
ロビン・ライダー

1
多数の問題が原因で、n = 61(ばかげた大規模なテストケース)で失敗するようです。言語の制限を考慮に入れても大丈夫だと思いますが、例外に注意してください。
CriminallyVulgar

3

ゼリー、40バイト

½©%1İ$<®‘¤$п¹;Ḋ$LḂ$?Ḟṭ@ṫ-ṚZæ.ʋ¥ƒØ.,U¤-ị

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

代替のゼリーの答え、ゴルフは少なくなりますが、xとyが大きい場合はアルゴリズム的に効率的です。これにより、nの平方根に近似する正規連続分数の収束が検出され、次に、Pell方程式を解くものがチェックされます。これで、通常の継続分数の期間が正しく検出されます。

@TimPederickのおかげで、任意の数を処理する整数ベースのソリューションも実装しました。

ゼリー、68バイト

U×_ƭ/;²®_$÷2ị$}ʋ¥µ;+®Æ½W¤:/$$
¹©Æ½Ø.;ÇƬṪ€F¹;Ḋ$LḂ$?ṭ@ṫ-ṚZæ.ʋ¥ƒØ.,U¤-ị

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

たとえば、1234567890ソリューションでは、分子と分母にそれぞれ1936桁と1932桁が使用されます。


いいね!私は答えで同じアプローチを取りました。私はゼリーを読んでいませんので、なぜ61で問題が発生しているのか分かりません。各収束関数を整数のペア(分子と分母)として保存していますか?
ティムペデリック

@TimPederickはい。問題が発生した場所がわからない
ニックケネディ

私はこれがどのように機能するかを学ぼうとしたので、デバッグを手伝うことができましたが、頭を包み込むことができませんでした!(これ私のアルゴリズムと同じアルゴリズムを使用する場合)中間値はすべて整数として出力されるため、フロートのフロアを取得することのみを提案できます。
ティムペデリック

@TimPederickこれは浮動小数点の不正確さでした。期間に達した後、継続分数のさらなる継続を探すのをやめました。これは、150まで動作しますが、私はもう一度考えていることの上に、私は、例えば151で浮動小数点精度誤差に遭遇
ニック・ケネディ

@TimPederickは、整数演算で行われる収束ではなく、問題のある連続分数の生成でもあります。
ニックケネディ


2

TI-BASIC、 44  42 41バイト

Ans→N:"√(N⁻¹(X²-1→Y₁:1→X:Repeat not(fPart(Ans:X+1→X:Y₁:End:{X,Ans

n
バツy

方程式使用しますy=バツ21nバツ2
バツyymod1=0

例:

6
               6
prgmCDGF12
           {5 2}
10
              10
prgmCDGF12
          {19 6}
13
              13
prgmCDGF12
       {649 180}

説明:

Ans→N:"√(N⁻¹(X²+1→Y₁:1→X:Repeat not(fPart(Ans:X+1→X:Y₁:End:{X,Ans  ;full logic

Ans→N                                                              ;store the input in "N"
      "√(N⁻¹(X²+1→Y₁                                               ;store the aforementioned
                                                                   ; equation into the first
                                                                   ; function variable
                     1→X                                           ;store 1 in "X"
                         Repeat not(fPart(Ans          End         ;loop until "Ans" is
                                                                   ; an integer
                                              X+1→X                ;increment "X" by 1
                                                    Y₁             ;evaluate the function
                                                                   ; stored in this variable
                                                                   ; at "X" and leave the
                                                                   ; result in "Ans"
                                                           {X,Ans  ;create a list whose
                                                                   ; values contain "X" and
                                                                   ; "Ans" and leave it in
                                                                   ; "Ans"
                                                                   ;implicitly print "Ans"

注: TI-BASICはトークン化された言語です。文字数がバイト数と等しくありませ


2

MATL、17バイト

`@:Ut!G*-!1=&fts~

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

説明

コードは、カウンタ増加し続けるK = 1、2、3、...それぞれについてK、溶液はxはY 1≤ XK、1≤ Ykが探索されます。何らかの解決策が見つかった場合のプロセス。

この手順では、正確に基本的な解決策を1つだけ見つけることが保証されています。理由を確認するには、

  1. n > 1の解x > 0、y > 0は、x > yを満たします。
  2. 場合のxyは溶液であり、X ' Y 'は異なる溶液で、次に、必ずしもXX ' 及び YY '。

1と2の結果として、

  • プロシージャが特定のkで停止すると、そのkに対して1つの解のみが存在します。これは、2つの解がある場合、そのうちの1つが以前に検出され、プロセスがより小さいkで停止したためです。
  • このソリューションは基本的なものです。なぜなら、より小さなxのソリューションがあれば、それは以前に発見されていたからです。

`       % Do...while
  @:U   %   Push row vector [1^2, 2^2, ..., k^2] where k is the iteration index
  t!    %   Duplicate and transpose. Gives the column vector [1^2; 2^2; ...; k^2]
  G*    %   Multiply by input n, element-wise. Gives [n*1^2; n*2^2; ...; n*k^2]
  -     %   Subtract with broadcast. Gives a square matrix of size n
  !     %   Transpose, so that x corresponds to row index and y to column index
  1=&f  %   Push row and column indices of all entries that equal 1. There can
        %   only be (a) zero such entries, in which case the results are [], [],
        %   or (b) one such entry, in which case the results are the solution x, y
  ts~   %   Duplicate, sum, negate. This gives 1 in case (a) or 0 in case (b)
        % End (implicit). Proceed with next iteration if top of the stack is true;
        % that is, if no solution was found.
        % Display (implicit). The stack contains copies of [], and x, y on top.
        % The empty array [] is not displayed





1

、12バイト

ḟΛ¤ȯ=→*⁰□π2N

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

説明

ḟΛ¤ȯ=→*⁰□π2N  Input is n, accessed through ⁰.
           N  Natural numbers: [1,2,3,4,..
         π2   2-tuples, ordered by sum: [[1,1],[1,2],[2,1],[1,3],[2,2],..
ḟ             Find the first that satisfies this:
 Λ             All adjacent pairs x,y satisfy this:
  ¤     □       Square both: x²,y²
   ȯ  *⁰        Multiply second number by n: x²,ny²
     →          Increment second number: x²,ny²+1
    =           These are equal.

1

MathGolf、12バイト

ökî²*)_°▼Þ√î

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

出力のフォーマットに関しては、Hail Maryをスローしています。許可されていない場合は、1バイト長いソリューションがあります。出力形式はx.0y、です。ここ.0で、2つの数値の区切り文字です。

説明

ö       ▼      do-while-true with popping
 k             read integer from input
  î²           index of current loop (1-based) squared
    *          multiply the two
     )         increment (gives the potential x candidate
      _        duplicate TOS
       °       is perfect square
         Þ     discard everything but TOS
          √    square root
           î   index of previous loop (1-based)

Emignaの05AB1Eの回答からインスピレーションを得ましたが、いくつかの改善点を見つけることができました。選択した区切り記号が許可されていない場合は、バイトカウント13の最後のバイトの前にスペースを追加します。


1

APL(NARS)、906バイト

r←sqrti w;i;c;m
m←⎕ct⋄⎕ct←0⋄r←1⋄→3×⍳w≤3⋄r←2⋄→3×⍳w≤8⋄r←w÷2⋄c←0
i←⌊(2×r)÷⍨w+r×r⋄→3×⍳1≠×r-i⋄r←i⋄c+←1⋄→2×⍳c<900⋄r←⍬
⎕ct←m

r←pell w;a0;a;p;q2;p2;t;q;P;P1;Q;c;m
   r←⍬⋄→0×⍳w≤0⋄a0←a←sqrti w⋄→0×⍳a≡⍬⋄m←⎕ct⋄⎕ct←0⋄Q←p←1⋄c←P←P1←q2←p2←0⋄q←÷a
L: t←p2+a×p⋄p2←p⋄p←t
   t←q2+a×q
   :if c≠0⋄q2←q⋄:endif
   q←t           
   P←(a×Q)-P
   →Z×⍳Q=0⋄Q←Q÷⍨w-P×P
   →Z×⍳Q=0⋄a←⌊Q÷⍨a0+P
   c+←1⋄→L×⍳(1≠Qׯ1*c)∧c<10000
   r←p,q
   :if c=10000⋄r←⍬⋄:endif
Z: ⎕ct←m

そこにエラーのためZildeを返します床平方根とペル機能を見つけるだろう2つの機能sqrti関数であり、そしてページ読み込み基づいて、上記http://mathworld.wolfram.com/PellEquation.htmlを 知るためには、アルゴを使用します数trhuのsqrtは分数を継続し(newtonメソッドを使用してsqrtを知っているために1つのアルゴリズムを使用しても)、pおよびqが見つかると停止します。

 p^2-w*q^2=1=((-1)^c)*Qnext

テスト:

  ⎕fmt pell 1x
┌0─┐
│ 0│
└~─┘
  ⎕fmt pell 2x
┌2───┐
│ 3 2│
└~───┘
  ⎕fmt pell 3x
┌2───┐
│ 2 1│
└~───┘
  ⎕fmt pell 5x
┌2───┐
│ 9 4│
└~───┘
  ⎕fmt pell 61x
┌2────────────────────┐
│ 1766319049 226153980│
└~────────────────────┘
  ⎕fmt pell 4x
┌0─┐
│ 0│
└~─┘
  ⎕fmt pell 7373x
┌2───────────────────────────────────────────────────────────┐
│ 146386147086753607603444659849 1704817376311393106805466060│
└~───────────────────────────────────────────────────────────┘
  ⎕fmt pell 1000000000000000000000000000002x
┌2────────────────────────────────────────────────┐
│ 1000000000000000000000000000001 1000000000000000│
└~────────────────────────────────────────────────┘

sqrti関数のループのサイクルには制限があり、Pell関数のループのサイクルには制限があります。考えられるケース番号の両方が大きすぎるか、アルゴリズムが収束しない...(sqrtiかどうかはわかりませんすべての可能な入力を収束し、同じペル関数も)



0

Pyth、15バイト

fsIJ@ct*TTQ2 2J

こちらからオンラインでお試しください。出力がされx、その後y、改行で区切られています。



0

> <>、45バイト

11v
+$\~:1
:}/!?:-1v?=1-*}:{*:@:{*:
$  naon;>

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

ブルートフォースアルゴリズム。x=2上から検索し、y=x-1各ループで増減しxy0 に達すると増分します。出力のx後にy、改行で区切られたが続きます。



0

Python 3、75バイト

lambda i:next((x,y)for x in range(2,i**i)for y in range(x)if~-x**2==i*y**2)

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

説明

バツ<
バツ

このコードはPython 2でも実行されます。ただし、Python 2のrange()関数は、Python 3のようなジェネレーターの代わりにリストを作成するため、非常に非効率的です。


時間とメモリが無限であれば、イテレータの代わりにリスト内包表記を使用して、次のように3バイト節約できます。

Python 3、72バイト

lambda i:[(x,y)for x in range(i**i)for y in range(x)if~-x**2==i*y**2][1]

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


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