피보나치 제품


13

양의 피보나치 수의 고유 한 합계로 0보다 큰 수를 분해 할 수 있습니다. 이 질문에서 우리는 가능한 가장 큰 양의 피보나치 수 를 반복적으로 빼서이 작업을 수행합니다 . 예 :

1 = 1
2 = 2
3 = 3
4 = 3 + 1
12 = 8 + 3 + 1
13 = 13
100 = 89 + 8 + 3

이제 피보나치 제품 을 위와 같은 목록이라고하지만 곱셈으로 대체 한 것을 추가했습니다. 예를 들면 다음과 같습니다 f(100) = 89 * 8 * 3 = 2136.

양의 정수 n 이 주어진 프로그램이나 함수를 작성하면 해당 숫자의 피보나치 곱이 반환됩니다.


테스트 케이스 :

1: 1
2: 2
3: 3
4: 3
5: 5
6: 5
7: 10
8: 8
9: 8
42: 272
1000: 12831
12345: 138481852236

6
진술이 정확하지 않습니다. 예 2를 들어로 분해 할 수 있습니다 -1 + 3. Zeckendorf의 정리에 대한 올바른 진술은 양의 피보나치 수는 양의 지수를 가진 비 연속적인 피보나치 수의 합으로 고유하게 분해 될 수 있다는 것입니다.
피터 테일러

1
@PeterTaylor 나는이 질문에 대해 부정적인 피보나치 숫자 시리즈의 일부로 간주하지 않습니다. 연속적으로 또는 지수를 원할 때 중요 할뿐 아니라이 질문에 대한 지수는 신경 쓰지 않습니다.
orlp

1
나는 부정적인 피보나치 수를 지원하기 위해 질문을 변경해야한다고 말하는 것이 아닙니다. 나는 당신이 만들고있는 가정에 대해 명시 적으로 편집해야한다고 말하고 있습니다.
피터 테일러

1
@orlp는 두 개의 다른 형태가 두 개의 다른 제품을 제공하기 때문에 연속적이거나 중요하지 않습니다. 당신은 이미 피보나치 연속 용어를 암시 적으로 배제하는 방식으로 문제를 언급 했으므로 걱정할 필요가 없습니다.
hobbs

2
(구체적으로 : F (n)과 F (n + 1)은 알고리즘이 그것들을 고려하기 전에 나머지가 이미 F (n + 2) = F (n) +보다 작다는 것을 보장하기 때문에 출력에 모두 나타날 수 없습니다 F (n + 1))

답변:


5

젤리 , 16 15 바이트

Rf1+С¤ṪạµÐĿIAP

특히 빠르거나 메모리에 익숙하지는 않지만 모든 테스트 사례에 충분히 효율적입니다. 온라인으로 사용해보십시오!

작동 원리

Rf1+С¤ṪạµÐĿIAP  Main link. Argument: n (integer)

         µ       Combine the chain to the left into a link.
          ÐĿ     Apply that link until the results are no longer unique.
                 Return the list of unique results.
      ¤            Combine the two links to the left into a niladic chain.
  1                  Set the left (and right) argument to 1.
   +D¡               Apply + to the left and right argument, updating the left
                     argument with the sum, and the right argument with the
                     previous value of the left one. Return the list of results.
                     Repeat this process n times.
                   This yields n + 1 Fibonacci numbers, starting with 1, 2.
R                  Range; map k to [1, ..., k].
 f                 Filter; keep the items in the range that are Fibonacci numbers.
       Ṫ           Tail; yield the last one or 0 if the list is empty.
        ạ          Absolute difference with k.
                   This is the argument of the next iteration.
            I    Compute the increments of the arguments to the loop, yielding
                 the selected Fibonacci numbers (with changed sign).
             A   Apply absolute value to each.
              P  Compute their product.  

6
큰 것 같아, 데니스
orlp

9

파이썬, 54 바이트

f=lambda n,a=1,b=1:n<1or b>n and a*f(n-a)or f(n,b,a+b)

좋은 오래된 재귀.


5

펄, 69 63 + 4 ( -pl61플래그) = 67 바이트

#!perl -pl61
while($_){$n=$m=1;($n,$m)=($m,$n+$m)until$m>$_;$_-=$n;$\*=$n}}{

사용 :

> echo 42 | perl -pl61e 'while($_){$n=$m=1;($n,$m)=($m,$n+$m)until$m>$_;$_-=$n;$\*=$n}}{'

언 골프 드 :

while (<>) {
# code above added by -p
    # $_ has input value
    # $\ = 1 by -l61
    while ($_ != 0) {
        my $n = 1;
        my $m = 1;
        while ($m <= $_) {
            ($n, $m) = ($m, $n + $m);
        }
        $_ -= $n;
        $\ *= $n;
    }
} {
# code below added by -p
    print;  # prints $_ (undef here) and $\
}

Ideone .


설명은 8 진수 061가 문자의 ASCII 인코딩 임을 언급해야 합니다 '1'. $\거의 무료로 인쇄하기 위해 사용 하는 멋진 해킹 .
Peter Cordes

2

자바 스크립트 (ES6), 78 42 바이트

f=(n,a=1,b=1)=>n?b>n?a*f(n-a):f(n,b,a+b):1

@ Sp3000의 답변 포트입니다. 원래 78 바이트 버전 :

f=(n,a=[2,1])=>n>a[0]?f(n,[a[0]+a[1],...a]):a.map(e=>e>n?0:(r*=e,n-=e),r=1)&&r

2

> <> , 57 바이트

111\ ;n{/
:@+>:{:})?\$:@@
~{*}:0=?\}>:0${:})?$~:{$-$:1@?$

프로그램 시작시 입력 번호가 스택에있을 것으로 예상합니다.

f0, f1, f2, ..., fn입력 ( i) 보다 큰 수에 도달 할 때까지 스택 에서 피보나치 시퀀스 ( )를 구성합니다 . 그런 다음 제품 ( p)을 초기화하면 1...

while (i != 0)
   if (fn <= i)
      i = i - fn
      p = p * fn
   else
      i = i - 0
      p = p * 1
   discard fn
output p

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




1

Pyth, 24 바이트

W=-QeaYh.WgQeH,eZsZ1;*FY

온라인으로 사용해보십시오 : 데모 또는 테스트 스위트

설명:

Q 입력 번호가 할당됩니다.

이 부분 h.WgQeH,eZsZ1은 가장 큰 피보나치 수를 계산합니다.Q

h.WgQeH,eZsZ1
            1   start with H=Z=1
 .WgQeH         while Q >= end(H):
       ,eZsZ       H=Z=(end(Z), sum(Z))
h               first

따라서 인 경우 Q = 10숫자 / 쌍을 생성합니다.

1 -> (1,1) -> (1,2) -> (2,3) -> (3,5) -> (5,8) -> (8,13) -> 8

나머지 코드는 파티션을 계산하고 숫자를 곱합니다.

W=-QeaY...;*FY    implicit: Y = empty list
     aY...        add the calculated Fibonacci number to the empty list
    e             take the last element of Y (yes the number we just added)
 =-Q              and update Q with the difference of Q and ^
W         ;       continue until Q == 0
           *FY    multiply all number in Y and print

같은 짧은 솔루션이 많이 있습니다 (실제로 런타임이 좋지 않습니다) *FhfqQsTyeM.u,eNsNQ1.


1

하스켈, 44 바이트

상호 재귀에 대한 예 :

(a&b)c|c<1=1|b>c=a*f(c-a)|d<-a+b=b&d$c
f=0&1
  • a 이전 피보나치 수
  • b 현재 피보나치 수
  • c 입력입니다
  • f 원하는 기능입니다

덜 골프 :

(a & b) c | c == 0    = 1
          | c <  b    = a * f (c-a)
          | otherwise = b & (a + b) $ c
f x = (0 & 1) x

1

실제로 22 바이트

W;╗uR♂F;`╜≥`M░M;╜-WXkπ

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

설명:

W;╗uR♂F;`╜≥`M░M;╜-WXkπ
                        (implicit input)
W                 W     while top of stack is truthy:
 ;╗                       push a copy of n to reg0
   uR♂F;                  push 2 copies of [Fib(a) for a in range(1, n+2)]
        `╜≥`M░            filter: take values where n <= Fib(a)
              M;          two copies of maximum (call it m)
                ╜-        subtract from n (this leaves n-m on top of the stack to be the new n next iteration, with a copy of m below it)
                   X    discard the 0 left over after the loop ends
                    kπ  product of all stack values

실제로 자체 인코딩이 있습니까? 22 문자에서 35 바이트를 계산합니다. mothereff.in/…
고양이

1
@cat 심각하게 CP437을 사용합니다.
Mego

1

자바 (ES6) 134 (106) 92 바이트

공간을 발견 한 @cat에 감사드립니다.

n=>{for(c=[a=b=s=1,1];a+b<=n;)a+=b,c.unshift(b+=a,a);c.map(i=>i<=n&&(n-=i)&(s*=i));alert(s)}

휴대 전화에서 최적화되지 않은 버전으로 집에 도착하면 골프를 멈 춥니 다. 아이디어를 환영합니다.


과잉 공백 이 하나 있습니다 . : P
고양이

1

RETURN , 44 바이트

[a:[a;][1$[¤¤+$a;->~][]#%$␌a;\-a:]#␁[¤][×]#]

Try it here.

놀랍게도 비효율적 인 익명 람다는 Stack2에 결과를 남깁니다. 용법:

12345[a:[a;][1$[¤¤+$a;->~][]#%$␌a;\-a:]#␁[¤][×]#]!

참고 : ␌ 및 ␁는 인쇄 할 수없는 각 문자 ( 양식 공급머리글 시작)의 자리 표시 자입니다 .

설명

[                                           ]  lambda
 a:                                            store input to a
   [  ][                         ]#            while loop
    a;                                           check if a is truthy
        1$[¤¤+$a;->~][]#%                        if so, generate all fibonacci numbers less than a 
                         $␌                      push copy of TOS to stack2
                           a;\-a:                a-=TOS
                                   ␁[¤][×]#   get product of stack2

42 문자에서 46 바이트를 셉니다. RETURN이 일종의 특수 인코딩을 사용하는 경우 42 자에서 42 바이트 여야하지만 유니 코드 인 것처럼 보이므로 46입니다.
cat

실제로, 나는 단지 인쇄 할 수없는 것을 넣는 것을 잊었다는 것을 깨달았습니다.
Mama Fun Roll

나는 그들이 무엇인지 알기 위해 현미경이 필요했기 때문에 당신을 위해 그것들을 연결했습니다. : D (SOH인지 BOM인지 알 수 없음)
cat

0

PHP, 119 바이트

코드 (가독성을 위해 두 줄로 줄 바꿈) :

for($o=$c=1;$c<=$n=$argv[1];$f[++$k]=$c,$a=$b,$b=$c,$c+=$a);
for($i=$k;$i;$i--)for(;$n>=$d=$f[$i];$n-=$d,$o*=$d);echo$o;

첫 번째 줄은 $f피보나치 수 $n(명령 줄에 제공된 인수) 보다 작은 숫자를 계산합니다 . 두 번째 줄은 피보나치 인자를 빼기로 계산하고 곱하여의 곱을 계산합니다 $o.

<?php(기술적으로 프로그램의 일부가 아닌) 코드 앞에 파일을 넣고 ( fibonacci-factors.php) 다음과 같이 실행하십시오.

$ php -d error_reporting=0 fibonacci-factors.php 100
# The output:
2136

또는를 사용하여 실행하십시오 php -d error_reporting=0 -r '... code here ...' 100.

ungolfed 코드와 테스트 스위트는 Github 에서 찾을 수 있습니다 .


0

Q, 47 바이트

m:{*/1_-':|(0<){y-x x bin y}[*+60(|+\)\1 0]\x}

테스트

+(i;m'i:1 2 3 4 5 6 7 8 9 42 1000 12345)

쌍으로 읽습니다 (i, map (m, i)). 여기서 m은 계산 함수이고 i는 다른 인수입니다.

글을

1     1
2     2
3     3
4     3
5     5
6     5
7     10
8     8
9     8
42    272
1000  12831
12345 138481852236

설명

n funtion\arg function (function (function (... function (args))) n 번 (내부적으로 tal recursion을 사용함)을 적용하고 결과 시퀀스를 반환합니다 *+60(|+\)\1 0. | +) : 시퀀스에 적용된 + \는 부분합을 계산하고 (예 : + \ 1 2 3은 1 3 6), | sums reversed. 60(|+\)\1 0시퀀스 1 0, 1 1, 2 1, 3 2, 5 3, 8 5, 13 8, 21 13을 생성합니다. ... *+이 결과 플립에 적용되고 첫 번째 결과를 얻습니다. 1 2 3 5 8 13 21 34 55 ..

(cond)function\args cond true 인 동안 function (function (.. function (args)))을 적용하고 부분 결과 시퀀스를 반환합니다.

function[arg] 둘 이상의 인수 함수에 적용하면 투영이 생성됩니다 (부분 적용)

인수에 이름을 지정할 수 있지만 내재적 이름은 x, y, z입니다.

{y-x x bin y}[*+60(|+\)\1 0]부분 프로젝션을 사용하여 args x, y가있는 람다를 선언합니다 (arg x는 피보나치 계열이며 * + 60 (| +) \ 1 0으로 계산). x는 피보나치 값을 나타내고, y는 처리 할 숫자입니다. 이진 검색 (bin)은 더 큰 피보나치 수 <= y ( x bin y) 의 인덱스를 찾아 해당 x 값을 뺍니다.

부분 resuls에서 제품을 계산하기 위해 우리는 그것들을 뒤집고 각 쌍의 차이를 계산하고 ( -':|) 첫 번째를 버리고 ( 1_0이기 때문에) 곱합니다 ( */).

누적 합계에 관심이 있다면 코드는 동일하지만 +/대신에 동일 */합니다. + 또는 * 대신 다른 분음 연산자를 사용할 수도 있습니다

실행 효율에 대해

이 콘테스트에서 효율성은 문제가되지 않습니다. 그러나이 문제에서 우리는 직계 비용에서 지수 비용에 이르기까지 다양 할 수 있으므로 궁금합니다.

두 번째 버전 (주석을 제외한 길이 48 바이트)을 개발하고 두 버전에서 테스트 케이스 배터리를 1000 번 반복했습니다.

f:*+60(|+\)\1 0;m:{*/1_-':|(0<){x-f f bin x}\x}    /new version

실행 시간은 원래 버전 0'212 seg, 새 버전 0'037 seg

원래 버전은 기능 적용마다 한 번씩 피보 나시 세리를 계산합니다. 새 버전은 피보나치를 하나만 계산합니다.

두 경우 모두 피보나치 시리즈 계산에는 꼬리 재귀가 사용됩니다.

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