三角形平方数


11

平方数是以n^2n为整数形式的数字。这些也称为完美平方,因为当您求平方根时,您会得到一个整数。

前10个平方数是:(OEIS

0, 1, 4, 9, 16, 25, 36, 49, 64, 81


三角数是可以形成等边三角形的数。第n个三角数等于1到n之间所有自然数的总和。

前10个三角形数字是:(OEIS

0, 1, 3, 6, 10, 15, 21, 28, 36, 45


正方形三角形数字是正方形和三角形的数字。

前10个方形三角数为:(OEIS

0, 1, 36, 1225, 41616, 1413721, 48024900, 1631432881, 55420693056, 1882672131025, 63955431761796


有无限多个平方数,三角形数和正方形三角形数。

编写一个给定输入(参数或标准输入)数的程序或命名函数n,计算出n第平方三角数并输出/返回,其中n是一个非零正数。(对于n = 1返回0)

为了使程序/功能有效提交,它至少应返回所有小于2 ^ 31-1的正方形三角形。

奖金

-4字节,能够输出小于2 ^ 63-1的所有平方三角数

-4个字节,理论上可以输出任何大小的平方三角数。

对于采用非多项式时间的解决方案,+ 8字节的惩罚。

奖金堆栈。

这是代码高尔夫挑战赛,因此以最少的字节数获胜。


对于需要> O(n)时间的解决方案,我增加了8个字节的罚款,以使其对于那些追求更快代码的人更加公平。
rodolphito

@Rodolvertice我不认为您是指线性时间。我拥有的迭代解决方案是二次时间,因为存在n步骤,并且在每一步中,算法都花费线性时间,因为in的位数呈线性增长n。我认为线性时间是不可能的。除非您说算术运算是恒定时间?
xnor

1
@Rodolvertice我的意思是我的迭代解决方案不是O(n)。我认为更清洁的方法是说“多项式时间”。如果您采用线性时间算术,则会得到一些奇怪的事情,例如使用幂运算的解决方案(称为恒定时间)。摊销在这里不起作用。
xnor

1
喜欢看到用最快的代码
Abr001am 2015年

2
“第一个10个方形三角数...”您确定是11个吗?:P
Alex A.

Answers:


8

CJam,12个 8字节

XUri{_34*@-Y+}*;

利用了Wikipedia文章中的递归关系。

该代码长16个字节,可以同时获得这两个奖励。

CJam解释器中在线尝试。

这个怎么运作

事实证明,我的代码在所有方面都与xnor的相同,除了我使用CJam的堆栈而不是变量。

XU               e# Push 1 and 0 on the stack.
                 e# Since 34 * 0 - 1 + 2 = 1, this compensates for 1-based indexing.
  ri{        }*  e# Do int(input()) times:
     _34*        e#   Copy the topmost integer and multiply it by 34.
         @-      e#   Subtract the bottommost integer from the result.
           Y+    e#   Add 2.
               ; e# Discard the last result.

它可以在非常大的输入下立即运行,但超过3000个会在在线解释器上显示Javascript范围错误。我打算在Java实现上尝试一下。
rodolphito

@Rodolvertice:我已经切换到迭代方法。它实际上更短,并且占用的内存更少。
丹尼斯

8

Python 2、45-4-4 = 37

a=1;b=0
exec"a,b=b,34*b-a+2;"*input()
print a

使用递归进行迭代

f(0) = 1
f(1) = 0
f(k) = 34*f(k-1)-f(k-2)+2

从理论上讲,这支持任何大小的数字,但以指数时间运行,因此它不符合获得奖金的资格。应该适用于任何大小的数字。例如,对于100,给出

1185827220993342542557325920096705939276583904852110550753333094088280194260929920844987597980616456388639477930416411849864965254621398934978872054025

递归解决方案使用41个字符,但不符合条件,因为它花费了指数时间。

f=lambda k:k>2and 34*f(k-1)-f(k-2)+2or~-k

那很骗人,是字符串乘法的“循环”,哈哈。
rodolphito

@Rodolvertice:一点都不作弊。相当聪明,而且在网站上确实相当普遍。
Alex A.

我相信您的递归解决方案有资格获得奖金#1,这将使它与exec解决方案挂钩。如果允许您更改递归限制,那么它还可以计算任意大小的正方形三角形数,从而使其具有#2的资格。但是,我不确定是否符合条件(@Rodolvertice)。
卡德2015年

7

Pyth,16-4-4 = 8个字节

使用OEIS文章中的递归公式。

K1uhh-*34G~KGtQZ

它使用了很新的post-assign命令,看起来很酷。n-1由于基于1的索引,因此使用减少来迭代时间。

K1            Set K=1
u       tQ    Reduce input()-1 times
         Z    With zero as base case
 hh            +2
  -           Subtract
   *34G       34 times iterating variable
   ~K         Assign to K and use old value
    G         Assign the iterating variable.

似乎是多项式的,因为它循环n次,并且每次迭代都进行数学和赋值运算,但是我不是计算机科学家。几乎立即完成n = 10000。

在线尝试一下


我认为如果从0,1(而不是1,0)开始一次迭代,则可以避免从输入中减去1 -请参阅我的Python答案。
xnor 2015年

@xnor:我想他已经做到了。但是,循环返回的结果是your b
丹尼斯

5

绿洲7-4-4 = -1(非竞争)

34*c-»T

在线尝试!

用途 a(0) = 0, a(1) = 1; for n >= 2, a(n) = 34 * a(n-1) - a(n-2) + 2

Oasis支持任意精度的整数,因此只要不发生堆栈溢出,它就应该可以增加到任意数量。让我知道这是否由于堆栈溢出而不能算作奖金。此特定算法也可能是非多项式的,请让我知道是否是这种情况。

不竞争,因为语言发布日期具有挑战性。

说明:

34*c-»T -> 34*c-»10

a(0) = 0
a(1) = 1
a(n) = 34*c-»

34*c-»
34*    # 34*a(n-1)
   c-  # 34*a(n-1)-a(n-2)
     » # 34*a(n-1)-a(n-2)+2

替代解决方案:

-35*d+T

改为使用 a(n) = 35*(a(n-1)-a(n-2)) + a(n-3)


问题说For n=1 return 0,但是返回1。这可以通过添加-O选项来解决
Grimmy

4

JavaScript(ES6),29-4 = 25字节

n=>n>1?34*f(n-1)-f(n-2)+2:n|0

@IsmaelMiguel节省了5个字节!

我不得不对0、1和负数进行硬编码,以避免无限递归。

控制台,我将函数命名为f

f(1);  // 0
f(13); // 73804512832419600
f(30); // 7.885505171090779e+42 or 7885505171090779000000000000000000000000000

编辑:事实证明JavaScript会将数字四舍五入为16(15)个数字(规范),因为这些数字太大会导致溢出。将714341252076979033放到JavaScript控制台中,然后自己看看。这更多是JavaScript的局限性


我认为这没有资格获得奖金。f(15)应该返回85170343853180456676,而不是85170343853180450000
丹尼斯2015年

@Dennis JavaScript必须将其截断。.-。是啊,JavaScript的舍入到16位的时候
Downgoat

试试这个:n=>n?n<2?0:34*f(n-1)-f(n-2)+2:1(31字节)。我已经测试到第五位了。
Ismael Miguel

1
现在,您有29字节长的解决方案:n=>n>1?34*f(n-1)-f(n-2)+2:!!n。它false0trueon 136on上返回2。如果您希望它返回一个数字,则可以替换!!n+!!n
Ismael Miguel

1
解决了问题。使用此命令:(n=>n>1?34*f(n-1)-f(n-2)+2:n|0相同的字节数,现在始终返回数字)
Ismael Miguel

3

Excel VBA-90字节

使用Wikipedia页面上的重复关系:

n = InputBox("n")
x = 0
y = 1
For i = 1 To n
Cells(i, 1) = x
r = 34 * y - x + 2
x = y
y = r
Next i

执行时,系统会提示您输入n,然后将直到n并包括n的序列输出到列A:

输出

在给出溢出错误之前,它最多可以运行n = 202。


2

[不竞争] Pyth(14-4-4 = 6字节)

K1u/^tG2~KGQ36

使用OEIS的第一个循环,在0,1,36之后您可以找到A n =(A n-1 -1)2 / A n-2。A不竞争,因为此解决方案从36开始,如果您走低,则除以零(因此输入0表示36)。还必须对36进行硬编码。

在这里尝试


2

Java,53-4 = 49字节

这是另一种简单的递归,但是我通常不会以低于50的分数发布Java,因此...

long g(int n){return n<2?n<1?1:0:34*g(n-1)-g(n-2)+2;}

现在,对于递归的东西,它变得更长了。这一个既较长(112-4 = 108),又较慢,所以我不确定为什么要发布它,但要进行迭代:

long f(int n){long a=0,b,c,d=0;for(;a<1l<<32&n>0;)if((c=(int)Math.sqrt(b=(a*a+a++)/2))*c==b){d=b;n--;}return d;}

2

朱莉娅,51字节-4-4 = 43

f(n)=(a=b=big(1);b-=1;for i=1:n a,b=b,34b-a+2end;a)

这将使用Wikipedia页面上列出的第一个递归关系来表示正方形三角形。它计算Ñ = 1000在0.006秒,和Ñ = 100000中6.93秒。它比递归解决方案不再是几个字节,但它的方式更快。

取消+说明:

function f(n)
    # Set a and b to be big integers
    a = big(1)
    b = big(0)

    # Iterate n times
    for i = 1:n
        # Use the recurrence relation, Luke
        a, b = b, 34*b - a + 2
    end

    # Return a
    a
end

例子:

julia> for i = 1:4 println(f(i)) end
0
1
36
1225

julia> @time for i = 1:1000 println(f(i)) end
0
... (further printing omitted here)
elapsed time: 1.137734341 seconds (403573226 bytes allocated, 38.75% gc time)

2

PHP,65 59 56-4 = 52字节

while($argv[1]--)while((0|$r=sqrt($s+=$f++))-$r);echo$s;

重复直到的平方根$s为∈ℤ:$f加到sum $s,递增$f
重复$argv[1]时间。
输出总和。


1

Prolog,70 74-4-4 = 66

n(X,R):-n(X,0,1,R).
n(X,A,B,R):-X=0,R=A;Z is X-1,E is 34*B-A+2,n(Z,B,E,R).

运行n(100,R)输出:

X = 40283218019606612026870715051828504163181534465162581625898684828251284020309760525686544840519804069618265491900426463694050293008018241080068813316496

n(10000,X)在我的计算机上运行大约需要1秒钟。

编辑:66版本是尾递归的。先前的非尾递归版本如下:

n(X,[Z|R]):-X>1,Y is X-1,n(Y,R),R=[A,B|_],Z is 34*A-B+2;X=1,Z=1,R=[0];Z=0.

它们具有相同的长度(以字节为单位),但是非尾递归生成堆栈溢出超过特定点(在我的计算机上大约为20500)。


1

JavaScript的ES6,77 75 71个字符

// 71 chars
f=n=>{for(q=t=w=0;n;++q)for(s=q*q;t<=s;t+=++w)s==t&&--n&console.log(s)}

// No multiplication, 75 chars
f=n=>{for(s=t=w=0,q=-1;n;s+=q+=2)for(;t<=s;t+=++w)s==t&&--n&console.log(s)}

// Old, 77 chars
f=n=>{for(s=t=w=0,q=-1;n;s+=q+=2){for(;t<s;t+=++w);s==t&&--n&console.log(s)}}
  • 解是线性的。
  • 由于数字类型,该解决方案可以输出小于2 ^ 53的所有数字。
  • 该算法本身可以用于无限数量。

测试:

f(11)

0
1
36
1225
41616
1413721
48024900
1631432881
55420693056
1882672131025
63955431761796


1

果冻13-8 = 5字节

这有资格获得两个奖金。

×8‘,µÆ²Ạ
0Ç#Ṫ

在线尝试!

聊天中聊天室一起

说明

×8',µÆ²Ạ〜助手链接。

×8〜8倍。
  '〜递增。
   ,〜与当前号码配对。
    µ〜开始一个新的monadic(1-arg)链接。
     〜〜矢量化的“是广场?”。
       Ạ〜全部。仅当两者均为真时才返回1。



0Ç#Ṫ〜主链接。

0#〜从0开始,使用时收集前N个具有真实结果的整数:
 Ç〜最后一个链接作为monad。
   Ṫ〜最后一个元素。隐式输出。



0

APL(NARS),67个字符,134个字节

r←f w;c;i;m
c←0⋄i←¯1⋄r←⍬
→2×⍳0≠1∣√1+8×m←i×i+←1⋄r←r,m⋄→2×⍳w>c+←1

测试:

  f 10
0 1 36 1225 41616 1413721 48024900 1631432881 55420693056 1882672131025 

f也会以二次序列搜索三角形数的元素,因此它们必须遵循APL中的三角形校验公式:0 = 1∣√1 + 8×m(数字m)进行校验。

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.