佩尔方程的基本解


28

给定一些非整数的正整数,找到相关的Pell方程的基本解ñXÿ

X2-ñÿ2=1个

细节

  • 基本是一对整数满足等式,其中最小且为正。(总有平凡的解未被计算。)XÿXÿXXÿ=1个0
  • 您可以假设不是正方形。ñ

例子

 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


佩尔方程式还没有遇到任何挑战,这让我感到惊讶,因为我认为它是众所周知的。至少,我确实记得有时会在Euler项目挑战赛中使用它。
凯文·克鲁伊森

@Fatalize“ 您可以假设不是正方形。ñ ”但是,如果测试用例省略了这些恕我直言,则可能会更清楚。
凯文·克鲁伊森

2
@KevinCruijssen我考虑过,但是我认为省略其中一些会更令人困惑n。(顺便说一句,我也感到惊讶,但我在沙盒中遇到了大约一年的挑战)
更加糟糕的

Answers:


16

Piet,612种编码

从标准输入中取n。输出y然后x,以空格分隔。

Codel大小1: 佩尔方程程序的代码大小为1

Codel大小4,以便于查看: 佩尔方程程序的代码大小为1

说明

此NPiet跟踪,该跟踪显示了针对输入值为99的计算解的程序。

我不确定在挑战之前是否听说过佩尔方程,因此我从维基百科获得了以下所有内容:具体来说,这三篇文章的这些部分:

基本上,我们要做的是:

  1. 从标准输入中获取ñ
  2. 查找ñ通过,直到其超过正方形递增计数器ñ,然后递减一次。(这是您在跟踪图中看到的第一个循环,位于左上方。)
  3. 设置一些变量以根据的连续分数计算Xÿñ
  4. 检查Xÿ是否符合Pell方程。如果是这样,则输出值(这是大约2/3的向下分支),然后退出(进入最左侧的红色块)。
  5. 如果不是,则迭代更新变量,然后返回到步骤4。(这是向右跳的宽循环,回到底部,然后重新跨过一半。)

坦率地说,我不知道强行方法是否会更短,而且我也不会尝试! 好吧,所以我尝试了。


9

Piet,184种编码

这是我不想写的(在其他答案中)的蛮力替代方法。计算n = 13 的解需要花费2分钟以上的时间。我真的不想在n = 29 上尝试...但是它最多每20个n都会检出一次,因此我相信它是正确的。

像其他答案一样,这从标准输入中取n,然后输出y,然后以空格分隔x

Codel大小1: Pell的等式程序(强力变量),编码大小为1

Codel大小4,以便于查看: 佩尔方程程序(强力变量),编码大小为4

说明

这是NPiet跟踪,输入值为5。

这是对Xÿ迭代的最残酷的蛮力。其他解决方案可能会遍历X,然后计算ÿ=X2-1个ñ,但是他们w弱

X=2ÿ=1个,这检查Xÿ是否已求解方程。如果有的话(叉子在右下方的底部),则输出值并退出。

如果不是,它将继续向左,其中ÿ递增并与X进行比较。(然后,有一些方向旋转可以跟随之字形路径移动。)

最后的比较是路径在左中角附近分开。如果它们相等,则将X递增,并将ÿ设置回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

Pari / GP,34个字节

PARI / GP几乎有一个内置的是:quadunit使基本单位的的二次域 d,其中d是该字段的判别式。换句话说,quadunit(4*n)解决了佩尔方程X2-ñÿ2=±1个。因此,当平方为-1个时,我必须采取平方。

我不知道它使用什么算法,但是即使ñ不是无平方的,它也可以工作。

答案的形式给出x + y*w,其中w表示ñ

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并获得第二个(基本的)解决方案的原因
J42161217

1
我希望这是真的,但是文档中似乎没有任何迹象表明....
Greg Martin

@GregMartin我已经使用了很多次此功能,并且已经知道它是如何工作的。我唯一关心的是跳过第一个解决方案,这使我多花了5个字节。您可以轻松地编写程序并对其进行测试(仅用于确认数百万个结果)
J42161217

4

05AB1E17 16 14字节

感谢Kevin Cruijssen节省了一个字节。
产出[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)保存一个字节。
Kevin Cruijssen

@KevinCruijssen:谢谢!是的,我也Ų首先注意到它没有按预期工作。
Emigna

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

-1个字节感谢@Arnauld
-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)
OlivierGrégoire

好吧,我实际上是在玩(x+1)*(x+1)-1等于的事实,这是-x*-(x+2)完全正确的。
OlivierGrégoire

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
Giuseppe

5
46个字节。找到的最小值x等于找到的最小值y。这使您可以节省2个字节,原因是表达x来讲y是不是周围的其他方法缩短,4个字节使用使用的伎俩T,其在1初始化
罗宾·莱德

1
@RobinRyder您可能需要+T在末尾确保a 而不是y==1返回1TRUE但是我不确定。
朱塞佩

3
@Giuseppe好发现!你是对的。这使它成为47个字节
Robin Ryder

1
由于数量过多,似乎在n = 61(愚蠢的大型测试用例)上失败。我认为允许语言限制是很好的,只是要注意例外情况。
刑事

3

果冻,40个字节

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

在线尝试!

如果X和y较大,则可替代果冻答案,减少高尔夫球运动,但算法上更有效。这将找到近似n的平方根的正则连续分数的收敛,然后检查将其求解为Pell方程。现在正确地找到规则连续分数的周期。

感谢@TimPederick,我还实现了一个基于整数的解决方案,该解决方案可以处理任何数字:

果冻,68字节

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

在线尝试!

例如,1234567890解决方案的分子和分母分别为1936和1932。


真好!我在回答中采用了相同的方法。我不读Jelly,所以我不确定为什么您在使用61时会遇到问题。您是否将每个会聚项存储为一对整数(分子和分母)?
Tim Pederick

@TimPederick是的。不确定问题出在哪里
Nick Kennedy

我尝试学习了它的工作原理,以便我可以帮助调试它,但是我无法解决这个问题!我唯一可以建议的是浮动,因为(如果确实使用与我的算法相同的算法)所有中间值无论如何都应以整数形式出现。
Tim Pederick

@TimPederick这是浮点数错误。现在,我让它停止寻找连续分数到达周期的进一步延续。最多可以达到150,但是在此之上,我想我再次遇到浮点精度错误,例如151
Nick Kennedy

@TimPederick也是有问题的连续分数的生成,而不是用整数算术完成的收敛。
尼克·肯尼迪

2

JavaScript(ES7),47个字节

n=>(g=x=>(y=((x*x-1)/n)**.5)%1?g(x+1):[x,y])(2)

在线尝试!

X²-1个X

n=>[(g=x=>(y=(x/n)**.5)%1?1+g(x+=k+=2):2)(k=3),y]

在线尝试!

或者我们可以采用50字节的非递归方式:

n=>eval('for(x=1;(y=((++x*x-1)/n)**.5)%1;);[x,y]')

在线尝试!


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

ñ
Xÿ

ÿ=X2-1个ñX2
Xÿÿ1个=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~

在线尝试!

说明

该代码不断增加的计数器ķ = 1,2,3,...各ķ,溶液Xÿ用1≤ Xķ,1个≤ ÿķ被搜索。找到某些解决方案的过程。

确保此过程仅找到一种解决方案,而这正是基本解决方案。要了解原因,请注意

  1. 对于n > 1的任何解x > 0,y > 0都满足x > y
  2. 如果xy是一个解决方案,而x ',y '是一个不同的解决方案,则必然xx ' yy '。

由于1和2,

  • 当程序在给定的站ķ,只有一个解决方案存在着对ķ,因为如果有两个解决方案,其中之一会被发现较早,并且进程将停止以较小ķ
  • 这个解决方案是最基本的解决方案,因为同样,如果有一个解决方案,它的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

2

Python 2,49个字节

a=input()**.5
x=2
while x%a*x>1:x+=1
print x,x//a

在线尝试!

查找x大于1的最小数字,其中x % sqrt(n) <= 1/x。然后,发现yx作为y = floor(x / sqrt(n))


2

Haskell,46个字节

XÿX2-ñÿ2=1个ÿX

f n=[(x,y)|x<-[1..],y<-[1..x],x^2-n*y^2==1]!!0

在线尝试!


似乎您需要更改nxin y<-[1..n]才能进行计算f 13
Christian Sievers

@ChristianSievers感谢您指出,我已更正!
flawr



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î²*)_°▼Þ√î

在线尝试!

关于输出格式,我要抛出一个冰雹玛丽。如果不允许,我有一个解决方案,该解决方案的长度增加了1个字节。输出格式为x.0y,其中.0两个数字之间是分隔符。

说明

ö       ▼      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

上面有2个函数sqrti函数,它们将查找最小平方根,而pell函数将返回Zilde以获取错误,并且基于阅读http://mathworld.wolfram.com/PellEquation.html页面 ,它将使用算法来了解数字trhu的sqrt继续小数(即使我使用牛顿方法对已知sqrt使用一个算法),并在找到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是否汇聚所有可能的输入,并且也具有相同的Pell功能)



0

Pyth,15个字节

fsIJ@ct*TTQ2 2J

在这里在线尝试。x然后y用换行符分隔输出。



0

> <>,45个字节

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

在线尝试!

蛮力算法,x=2向上搜索,y=x-1每个循环递减,到0 x时递增。y输出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)

在线尝试!

说明

X<一世一世
X一世

该代码也可以在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]

在线尝试!


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.