내 Fibonaccified divisors를 요약하십시오!


14

유명한 피보나치 수열은 F(0) = 0; F(1) = 1; F(N+1) = F(N) + F(N-1)(이 도전을 위해 우리는 0으로 시작합니다)입니다.

챌린지 : n이 주어지면 , n 번째 피보나치 수 의 모든 제수 d 에 대한 모든 d 번째 피보나치 수 의 합을 출력하십시오 . 좀 더 공식적인 표기법을 선호한다면

합

입력 : 양의 정수 n

출력 : 합계

예를 들어을 고려하십시오 n=4. F(4) = 33의 제수는 1과 3이므로 출력은이어야합니다 F(1) + F(3) = 1 + 2 = 3.

내용 n=6, F(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

이것은 이며 바이트 단위의 최단 답변입니다. 표준 허점이 적용됩니다.

답변:


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.

언어의 이름은 수동적 인 공격적인 것처럼 보이나요?
로한 j 준 왈라

1
나는 그것을 의심한다. 이 주석으로 인해 언어의 첫 번째 버전이 심각하게 호출되었습니다 . 두 번째 버전의 경우 저자는 형용사를 계속 사용하기로 결정했습니다.
Dennis

6

젤리 , 7 바이트

ÆḞÆDÆḞS

온라인으로 사용해보십시오!

설명:

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

절대적으로 터무니 없다! 나는이 이국적인 언어를 모른다. 그러나 몇 개의 문자로 전체 알고리즘을 작성하는 방법은 나에게 초자연적이다.
Bogdan Alexandru

@BogdanAlexandru 여기에 사용 된 대부분의 내장은 1 바이트에 맞지 않기 때문에 각각 2 바이트를 소비한다는 것을 알 수 있습니다. 더 적은 수의 문자에 대해서는 Dennis의 Actually answer를 참조하십시오. 또한 Jelly는 "golfing language"로 code-golf 전용 언어 이며 "가장 효율적인"언어는 없지만 여기서 가장 효율적인 언어 중 하나입니다.
Outgolfer Erik

이 언어들은 실제로 사용되지 않으며 단지 도전을위한 것이라는 말입니까?
Bogdan Alexandru


4

매스 매 티카 단순화 , 14 바이트

Fi@#~Div9`~Fi&

아, 이것은 결국 @MartinEnder의 솔루션과 동일합니다 ...


글쎄요 ... 같은 언어의 짧은 버전을 사용하는 것 같습니다.
Neil A.

Mathematica에는 단일 문자 함수 이름이 없습니다. 대문자 대문자와 단일 바이트로 구성된 두 문자열을 모두 일치시킬 수 없습니까? 그렇다면 26 * 256 = 6656 단순화 된 2 바이트 함수 이름을 가지게되며, 6356 11.1.1 이름은 300으로 충분합니다.
Jonathan Allan

@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 바이트

2 바이트를 절약 해 준 Leo에게 감사합니다.

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

온라인으로 사용해보십시오!

거의 확실하지 않습니다. 제어 흐름은 상당히 정교하고 이전 버전보다 많은 바이트를 절약 한 것에 대해 매우 만족하지만 더 간단 하고 더 많은 것들을 복잡하게 만드는 느낌이 있습니다. 더 짧은 솔루션 .

설명

먼저 Alice의 RAS (Return Address Stack)에 대해 조금 자세히 설명해야합니다. 다른 많은 곰팡이와 마찬가지로 Alice는 코드에서 뛰어 넘을 명령이 있습니다. 그러나 여기에는 원래 위치로 돌아가는 명령도있어 서브 루틴을 매우 편리하게 구현할 수 있습니다. 물론 이것은 2D 언어이므로 서브 루틴은 실제로는 규칙에 의해서만 존재합니다. 리턴 명령 (또는 서브 루틴의 임의의 시점) 이외의 다른 방법을 통해 서브 루틴에 들어가거나 나가는 것을 막을 수있는 것은 없으며, RAS 사용 방법에 따라 클린 점프 / 리턴 계층 구조가 없을 수도 있습니다.

일반적으로 이것은 점프 명령이 점프 j하기 전에 현재 IP 주소를 RAS로 푸시하도록 함으로써 구현됩니다 . 리턴 명령 k은 RAS의 주소를 팝하고 점프합니다. RAS가 비어 있으면 k아무 것도 수행하지 않습니다.

RAS를 조작하는 다른 방법도 있습니다. 이 중 두 가지는이 프로그램과 관련이 있습니다.

  • w어디에서든 점프 하지 않고 현재 IP 주소를 RAS로 푸시합니다 . 이 명령을 반복하면 간단한 루프를 매우 편리하게 작성할 수 있습니다 &w...k. 이전 답변에서 이미 수행했습니다.
  • JRAS의 현재 IP 주소 와 j같지만 기억 나지 않습니다 .

또한 RAS는 IP 방향 에 대한 정보를 저장하지 않습니다 . 와 주소로 반환하는 것은 그래서 k항상 유지됩니다 현재 에 관계없이 우리가 통과하는 방법 (그러므로 또한 우리가 추기경 또는 서수 모드에있어 여부 등) IP 방향을 jw IP 주소를 처음에 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'라이브러리를 사용합니다. 이것은 피보나치 기능을 내장하고 있으며 많은 수의 기능을 제공합니다. 그것은 내 자신의 피보나치 함수를 만드는 것보다 여전히 작지만 seq와 적용에 몇 가지 문제를 일으켰습니다.

설명

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

펄 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

자바 스크립트 (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

자바 스크립트 (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

@ETHproductions로 변경 g(z)하면 해결할 수있는 오버플 로가 발생 g(z|0)하지만 동일한 바이트 수로 다시 돌아옵니다.
얽히고 설킨



당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.