将我的斐波那契除数相加!


14

著名的斐波那契数列是F(0) = 0; F(1) = 1; F(N+1) = F(N) + F(N-1)(对于这个挑战,我们从0开始)。

您的挑战:由于ñ,输出所有的总和d个斐波那契数为所有除数Ð的的ñ个Fibonacci数。如果您希望使用更正式的符号,

总和

输入:正整数n

输出:总和

例如,考虑n=4F(4) = 33的除数是1和3,因此输出应为F(1) + F(3) = 1 + 2 = 3

对于n=6F(6) = 8和,8的除数是1,2,4,8,因此输出是F(1) + F(2) + F(4) + F(8) = 1 + 1 + 3 + 21 = 26

测试用例:

1 => 1
2 => 1
3 => 2
4 => 3
5 => 6
6 => 26

这是,最短答案以字节为单位。有标准漏洞

Answers:


2

实际上,5个字节

F÷♂FΣ

在线尝试!

怎么运行的

       (implicit) Read n from STDIN.
F      Compute F(n).
 ÷     Get F(n)'s divisors.
  ♂F   Map F over the divisors.
    Σ  Take the sum.

语言的名称使它看起来像是被动的,激进的,这是故意的吗?
Rohan Jhunjhunwala

1
我对此表示怀疑。由于该评论,该语言的第一个版本被称为“认真” 。对于第二个版本,作者选择继续使用形容词。
丹尼斯,

6

果冻,7个字节

ÆḞÆDÆḞS

在线尝试!

说明:

ÆḞÆDÆḞS Main link (Arguments: z)
ÆḞ      zth Fibonacci number's
  ÆD                           divisors'
    ÆḞ                                   Fibonacci numbers'
      S                                                     sum

绝对离谱!我不知道这些外来语言中的任何一种,但是对我来说,如何用几个字符编写整个算法似乎很自然。
Bogdan Alexandru

@BogdanAlexandru您可以看到,这里使用的大多数内建函数每个都占用2个字节,因为它们不适合1个字节。有关更少的字符,请参见Dennis的“实际答案”。同样,Jelly是一种“高尔夫语言”,是一种专门针对代码高尔夫使用的语言,它是此处效率最高的语言之一(尽管没有一种“效率最高”的语言)。
暴民埃里克(Erik the Outgolfer)'17年

您是在说这些语言没有在实践中使用,它们仅用于挑战吗?
Bogdan Alexandru


4

Mathematica简体,14字节

Fi@#~Div9`~Fi&

哦,好了,这最终与@MartinEnder的解决方案相同...


好吧...使用相同语言的较短版本...我想这可行。
尼尔·

Mathematica中没有单字母函数名称,对吗?您能否匹配由大写字母开头和一个字节组成的所有两个字符串?如果是这样,您将拥有26 * 256 = 6656个简化的2字节函数名,足以容纳6356 11.1.1个名称,并保留300个。
乔纳森·艾伦

@JonathanAllan好主意。(但有单个名称函数,例如N
JungHwan Min


2

05AB1E,11个字节

!ÅFDI<èÑ<èO

在线尝试!

说明

!            # factorial of input
 ÅF          # get the list of fibonacci numbers (starting at 1)
             # smaller than or equal to this
   D         # duplicate list of fibonacci number
    I<è      # get the element at index (input-1)
       Ñ     # get the list of its divisors
        <    # decrement each
         è   # get the fibonacci numbers at those indices
          O  # sum


2

爱丽丝38 36字节

感谢Leo节省2个字节。

/ow;B1dt&w;31J
\i@/01dt,t&w.2,+k;d&+

在线尝试!

几乎可以肯定不是最佳的。控制流程相当复杂,尽管我对以前的版本中保存了多少字节感到非常满意,但我觉得我过于复杂了,可能会有一个更简单更短的解决方案。

说明

首先,我需要详细介绍Alice的返回地址堆栈(RAS)。像许多其他fungeoid一样,Alice也有一个在代码中跳转的命令。但是,它也有命令可以返回您的来源,这使您可以非常方便地实现子例程。当然,这是一种2D语言,子例程实际上仅按约定存在。除了返回命令(或子例程中的任何点)以外,没有什么可以阻止您通过其他方式进入或离开子例程,并且根据您使用RAS的方式,可能始终没有干净的跳转/返回层次结构。

通常,这是通过使跳转命令在跳转j之前将当前IP地址推送到RAS来实现的。然后,return命令k会弹出RAS的地址并跳转到该地址。如果RAS为空,k则什么也不做。

还有其他方法可以操作RAS。其中两个与此程序有关:

  • w将当前IP地址推送到RAS,而不会跳转到任何地方。如果您重复此命令,则可以像一样方便地编写简单的循环&w...k,我已经在过去的答案中做了。
  • J就像j记得RAS上的当前IP地址。

同样重要的是要注意,RAS不存储有关IP 方向的信息。因此,返回到的地址k将始终保留当前的 IP方向(因此也无论我们处于基数还是序数模式),无论我们如何首先通过jw推动IP地址。

有了这样的方式,让我们开始研究以上程序中的子例程:

01dt,t&w.2,+k

该子例程将堆栈的底部元素n拉到顶部,然后计算斐波那契数F(n)F(n + 1)(将它们放在堆栈顶部)。我们永远不需要F(n + 1),但是由于&w...k循环与RAS的交互方式(这种要求将这些循环放在子例程的末尾,它将在子例程外部被丢弃。我们从底部而不是顶部获取元素的原因是,这使我们更像堆栈一样对待堆栈,这意味着我们可以一次性计算所有斐波那契数,而不必将其存储在其他位置。

该子例程的工作方式如下:

                                                          Stack
01    Push 0 and 1, to initialise Fibonacci sequence.     [n ... 0 1]
dt,   Pull bottom element n to top.                       [... 0 1 n]
t&w   Run this loop n times...                            [... F(i-2) F(i-1)]

  .     Duplicate F(i-1).                                 [... F(i-2) F(i-1) F(i-1)]
  2,    Pull up F(i-2).                                   [... F(i-1) F(i-1) F(i-2)]
  +     Add them together to get F(i).                    [... F(i-1) F(i)]

k     End of loop.

循环的结尾有些棘手。只要堆栈上有“ w”地址的副本,它就会开始下一次迭代。一旦这些耗尽,结果取决于子例程的调用方式。如果用“ j”调用子例程,则最后一个“ k”返回那里,因此循环结束是子例程返回的两倍。如果用“ J”调用该子例程,并且在堆栈的前面还有一个地址,我们跳转到那里。这意味着,如果子例程本身是在外循环中调用的,则此“ k”将返回该循环的开头。如果用“ J”调用该子例程,但是RAS现在为空,则此“ k”不执行任何操作,并且IP在循环之后只是继续移动。我们将在程序中使用所有这三种情况。

最后,进入程序本身。

/o....
\i@...

这只是进入序数模式的两个快速操作,以读取和打印十进制整数。

之后的i,由于存在第二个,所以有一个w在进入子例程之前记住当前位置/。这个子程序的第一次调用计算F(n)F(n+1)输入n。之后,我们跳回此处,但现在我们要向东移动,因此其余程序操作员将处于基数模式。主程序如下所示:

;B1dt&w;31J;d&+
        ^^^

此处31J是对子例程的另一个调用,因此计算了斐波那契数。

                                              Stack
                                              [F(n) F(n+1)]
;     Discard F(n+1).                         [F(n)]
B     Push all divisors of F(n).              [d_1 d_2 ... d_p]
1     Push 1. This value is arbitrary.        [d_1 d_2 ... d_p 1]
      The reason we need it is due to
      the fact that we don't want to run
      any code after our nested loops, so
      the upcoming outer loop over all
      divisors will *start* with ';' to
      discard F(d+1). But on the first
      iteration we haven't called the
      subroutine yet, so we need some 
      dummy value we can discard.
dt&w  Run this loop once for each element     [d_1 d_2 ... d_p 1]
      in the stack. Note that this is once    OR
      more than we have divisors. But since   [d_i d_(i+1) ... F(d_(i-1)) F(d_(i-1)+1)] 
      we're treating the stack as a queue,
      the last iteration will process the 
      first divisor for a second time. 
      Luckily, the first divisor is always 
      1 and F(1) = 1, so it doesn't matter 
      how often we process this one.

  ;     Discard the dummy value on the        [d_1 d_2 ... d_p]
        first iteration and F(d+1) of         OR
        the previous divisor on subsequent    [d_i d_(i+1) ... F(d_(i-1))]
        iterations.
  31J   Call the subroutine without pushing   [d_(i+1) ... F(d_i) F(d_i+1)]
        the current address on the RAS.
        Thereby, this doubles as our outer
        loop end. As long as there's an
        address left from the 'w', the end
        of the subroutine will jump there
        and start another iteration for the
        next divisor. Once that's done, the
        'k' at the end of the subroutine will
        simply do nothing and we'll continue
        after it.

;     Discard the final F(d_i+1).
d&+   Get the stack depth D and add the top   [final result]
      D+2 values. Of course that's two more
      than we have divisors, but the stack is
      implicitly padded with zeros, so that
      doesn't matter.

1

公理,68字节

g==>fibonacci;f(x:NNI):NNI==(x<3=>1;reduce(+,map(g,divisors(g(x)))))

一些测试

(46) -> [[i,f(i)] for i in [0,1,2,3,4,5,6,10,15] ]
   (46)
   [[0,1], [1,1], [2,1], [3,2], [4,3], [5,6], [6,26], [10,139583862540],
     [15,
      135823697912782666169062844948067355657769395021071830756126284114988028_
       12823029319917411196081011510136735503204397274473084444
     ]
   ]
                                       Type: List List NonNegativeInteger



1

R,77个字节

F=gmp::fibnum;N=F(scan());i=n=N-N;while(i<N)if(N%%(i=i+1)<1)n=n+F(i);print(n)

利用“ gmp”库。它具有内置的斐波那契功能,并提供了进行大量运算的能力。尽管它比创建我自己的斐波那契函数还小,但它却导致了seqs和应用的一些问题。

说明

F=gmp::fibnum;               # Set F as fibnum function
N=F(scan());                 # get input and set N to the fibonacci number of that index
i=n=N-N;                     # set i and n to 0 with data type bigz
while(i<N)                   # loop while i < N
   if(N%%(i=i+1)<1)          # if incremented i is divisor of N 
       n=n+F(i);             # add F(i) to rolling sum
print(n)                     # output final result

测试

> F=gmp::fibnum;N=F(scan());i=n=N-N;while(i<N)if(N%%(i=i+1)<1)n=n+F(i);print(n)
1: 6
2: 
Read 1 item
Big Integer ('bigz') :
[1] 26
> F=gmp::fibnum;N=F(scan());i=n=N-N;while(i<N)if(N%%(i=i+1)<1)n=n+F(i);print(n)
1: 10
2: 
Read 1 item
Big Integer ('bigz') :
[1] 139583862540
> F=gmp::fibnum;N=F(scan());i=n=N-N;while(i<N)if(N%%(i=i+1)<1)n=n+F(i);print(n)
1: 15
2: 
Read 1 item
Big Integer ('bigz') :
[1] 13582369791278266616906284494806735565776939502107183075612628411498802812823029319917411196081011510136735503204397274473084444

不使用gmp

81字节,递归函数在选择大数(9+)时速度很慢

F=function(n)`if`(n<2,n,F(n-1)+F(n-2));sum(sapply(which((N=F(scan()))%%1:N<1),F))

88字节,Binet的公式可以很好地处理较大的数字,但仍然很快达到整数限制

F=function(n)round(((5+5^.5)/10)*((1+5^.5)/2)^(n-1));sum(F(which(F(N<-scan())%%1:N<1)))

0

Perl 6,49个字节

{my \f=0,1,*+*...*;sum f[grep f[$_]%%*,1..f[$_]]}

0

CJam,26个字节

qi_[XY@{_2$+}*]_@\f%:!.*:+

在线尝试!

我相信可以做得更好。说明:

这个想法是有一个斐波纳契数的数组,如果该数字是输入的除数或不是输入的除数,则将其与1和0组成的数组进行点积。

qi                                 Read the input (n)
   [XY        ]                    Array starting with [1,2,...]
  _   @{_2$+}*                     Append n times the sum of the previous two
               _                   Duplicate the array
                @\f%               Modulo each item with n (0 if divisor, a number otherwise)
                    :!             Logical NOT everything (1 if divisor, 0 otherwise) 
                      .*:+         Dot product those two arrays

0

JavaScript(ES6),76 65字节

f=(n,i=k=(F=n=>n>1?F(n-1)+F(n-2):n)(n))=>i&&(k%i?0:F(i))+f(n,i-1)

测试用例


0

的JavaScript(ES6),105个 104 103 101 97字节

i=>[...Array((g=(n,x=0,y=1)=>n--?g(n,y,x+y):x)(i)+1)].map((_,y)=>s+=g((z=g(i)/y)%1?0:z|0),s=0)&&s

尝试一下

f=
i=>[...Array((g=(n,x=0,y=1)=>n--?g(n,y,x+y):x)(i)+1)].map((_,y)=>s+=g((z=g(i)/y)%1?0:z|0),s=0)&&s
o.innerText=f(j.value=4)
oninput=_=>o.innerText=f(+j.value)
<input id=j type=number><pre id=o>


认为您可以更改(z=g(i)/y)>~~z(z=g(i)/y)%1,如果您只是检查z是否为整数。
ETHproductions's

@ETHproductions会产生溢出,可以通过将其更改g(z)为来解决,g(z|0)但会使我们回到相同的字节数。
毛茸茸的



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.