毕达哥拉斯三重序列


33

毕达哥拉斯三重由三个正整数a,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该序列的第一个元素(零或一个索引)。

您需要至少通过和包括支持输出28455997,但是如果您正在使用的数据类型的限制突然升高,则需要为该新限制工作。因此,您不能对数字列表进行硬编码。

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

OEIS A239381

相似的序列(不输出这些!):


有时间限制吗?
罗夫霍

@Loovjo不,但是您应该知道/证明您的输出正确。有一些相似的序列,其输出在之后为12325
mbomb007 '16

我正在考虑的类似序列在之后有所不同85...它的下一个术语是3613(您能猜出它是什么吗?)
Neil

@Neil快速搜索产生勾股勾股线A053630。不过,我在挑战中引用了这两个,因为在进行实现时,我不小心到达了这两个序列或与它们相似的序列。
mbomb007 '16

1
确实,如果我清醒的话,我本可以自己
尼尔

Answers:


11

果冻,19字节

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

@ Dennis通过重构为无限序列节省了一个字节。

不接受输入和参数,然后在计算它们时通过打印每个项来无限地输出序列。随着数量的增加,此方法会变慢,因为它取决于素因数分解。

在线尝试!

这通过计算当前项的素数功率因数分解来计算下一项。为12325,这是{5 2,17,29}。欧几里得公式的一种形式可以计算勾股三元组{ abc },

formula

其中m > n并且三元组是本原,而mn是互质。

要从12325计算下一个原始根,请找到mn,使mn = 12325,然后选择mn,使gcd(mn)=1。然后通过创建{5 2的所有子集,生成mn的所有对,17、29}并找到{1、25、17、29、425、725、493、12325}的每个子集的乘积。然后将12325除以每个值和对,以使每个对为mn。使用每对计算c的公式,并取最小值90733。

  • 在228034970321525425477033478437478475683098735674620405573717049066152557390539189785785849849205205​​之后,以前的方法无法确定下一项。当正确的选择是第三个和最后一个素数时,先前的方法选择了最后一个值作为因子。新方法速度较慢,但​​由于它会测试所有对互质数以找到最小斜边,因此它将始终有效。

说明

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 '16

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的解释器上几分钟90733后,我获得了12325。在此之后,我停止了它。

尽管它显然没有针对速度进行优化,但它不是完整的蛮力法,因为它使用约束条件来查找勾股三元组。

说明

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)

这基本上只是蛮力算法,因此非常慢。它需要输出的术语数量作为输入。

我不确定此算法的正确性,程序会检查另一条腿直到第一条腿的平方,我认为这是足够的,但是我还没有做完数学。

试试repl.it!(已过时)(请不要尝试大于10的数字,这将非常慢)


您可以切换到Python 3.5并使用math.gcd。另外,请使用p+=[...]代替p.append(...)。并且<2代替==1。并且if所有这些都可以在一条线上。
mbomb007 '16

1
您仍然可以完成我建议的最后2项改进。
mbomb007 '16


Loovjo,您是否会根据建议使用代码?
mbomb007 '18

2

MATL,27字节

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

这将产生序列的第一项。输入基于0。

代码效率很低。在线编译器超时输入大于5。输入内容6花了一个半分钟的时间离线(并生成了正确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

(此后在我的机器上出错)


打高尔夫球的代码仅打印出序列的斜边。Ungolfed版本会显示所有这三个版本,以澄清未提及的三元组。
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字节归功于英里使用n * n代替Math.pow(n,2)

英里,可节省-24个字节使用for循环而不是while来更改数据类型,并由于操作顺序而消除了()

()->{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。上面的函数查找满足此关系的N的最小值,同时使勾股勾股的第二个元素三倍成为整数并大于第一个元素。然后,它将第一个元素的值设置为第三个元素,并使用更新后的第一个元素重复。

取消高尔夫:

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

伊迪恩!

*由于时间限制,ideone不会打印最后一个必需的元素,但是您可以通过程序的逻辑和非高尔夫版本看到(打印28455997作为以前的勾股三元组的第三个元素,而不是Pythagorean三元组的第一个元素)下一个),则以较高的时间限制打印这些值。


您不能使用n*n代替Math.pow(n,2)吗?
2016年

我不知道为什么我没想到...我会立即添加。谢谢@miles
Mario Ishac '16

我使用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功能还不够好,但是如果精确地提高了精度,那就可以了。

非常简单易懂。c用2而不是1 递增将运行时间减半,并且无论如何都只需要检查奇数,因为元素始终是奇数。

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上运行,因为Ideone使用Python 3.4


为了使输出保持更长的准确性,我必须使用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}

测试ok直到14作为q的参数:

  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}

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.