이 번호는 비밀리에 피보나치인가요?


23

배경

대부분의 피보나치 수 는 무엇인지 알고 있습니다. Zeckendorf의 정리 에 따르면 모든 양의 정수가 하나 이상의 고유 피보나치 수의 합으로 표현 될 수 있음을 알고있을 것입니다 . 정수의 최적의 Zeckendorf Representation에서 용어의 수가 n피보나치 수인 경우, n"비밀로"피보나치라고합니다.

예를 들면 다음과 같습니다.

139 = 89 + 34 + 13 + 3
This is a total of 4 integers. Since 4 is not a Fibonacci number, 139 is not secretly Fibonacci

140 = 89 + 34 + 13 + 3 + 1
This is a total of 5 integers. Since 5 is a Fibonacci number, 140 is secretly Fibonacci

노트

  • 최적의 Zeckendorf Representation은 욕심 많은 알고리즘을 사용하여 찾을 수 있습니다. 가장 큰 피보나치 수 <= n을 취하여 0에 도달 할 때까지 n에서 빼십시오.
  • 모든 피보나치 수는 1 피보나치 수 (자체)의 합으로 표시 될 수 있습니다. 1은 피보나치 수이므로 모든 피보나치 수는 비밀리에 피보나치입니다.

도전

당신의 도전은 정수를 취하고 그 정수가 비밀리에 피보나치인지 여부를 반환하는 프로그램이나 함수를 작성하는 것입니다.

입력

합리적인 형식으로 입력 할 수 있습니다. 입력이 단일 양의 정수라고 가정 할 수 있습니다.

산출

입력 값이 비밀리에 피보나치인지에 대한 두 가지 뚜렷한 결과 중 하나를 출력합니다. 예를 들어 True/ False, 1/ 0등이 있습니다.

채점

이것은 이므로 바이트 단위의 최단 답변이 승리합니다! 표준 허점은 금지되어 있습니다.

테스트 사례

Truthy (secretly Fibonacci)
1
2
4
50
140
300099

Falsey (NOT secretly Fibonacci)
33
53
54
139
118808

6
이것이 그들이 호기심을 의미합니까?
kevin

2
누구에게나 사용하는 경우 : 최적의 합계는 두 개의 연속 피보나치 수를 사용하지 않는 고유 한 솔루션입니다.
kasperd

2
@kasperd 당신이 맞습니다. 생각하면 말이됩니다. 솔루션에 두 개의 연속 피보나치 수가 있으면 함께 추가하여 다음 수를 형성 할 수 있습니다. 솔루션에 5와 8이 포함 된 경우 단일 13을 사용하는 것보다 덜 적합합니다.
Cowabunghole

@Cowabunghole 직감입니다. 완전한 증거는 그보다 조금 더 복잡합니다. 솔루션에 이미 5, 8 및 13이 포함 된 경우 5 + 8이 아닌 8 + 13을 추가합니다. 그리고 다른 방향도 입증해야합니다.
kasperd

답변:



8

파이썬 2 , 77 바이트

def f(n):z=[bin(x).count('1')for x in range(n*n+1)if x&2*x<1];print z[z[n]]<2

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

이것은 OEIS A003714에 대한 두 가지 설명 이 동일 하다는 정리를 사용합니다 .

피비 나이 숫자 : 가 의 Zeckendorf 표현 인 (즉, 피보나치 수 시스템에서 을 쓴 ) 입니다. 또한 이진 표현에 두 개의 인접한 포함되지 않은 숫자입니다 .n=F(i1)+F(i2)++F(ik)nna(n)=2i1+2i2++2ik 11

우리는 그러한 숫자를 충분히 생성 한 다음, 1을 2 진수로 세어 z음수가 아닌 정수에서 " 의 Zeckendorf 표현에 몇 개의 항이 있습니까?" 로의 매핑으로 사용 합니다.n

그런 다음 z[n]피보나치 수 인지 확인해야 z[z[n]] == 1합니다.

* 적어도 충분히 느껴지고 실험적으로는 충분 해 보입니다. 나는 이것을 나중에 증명할 것이다.n2+1


주위의 백틱을 제거하여 2 바이트를 줄일 수 있습니다 bin(x). 로 변경 range(n*n+1)하여 하나를 제거 할 수도 있습니다 range(n<<n). (0이 유효하지 않다고 가정)
nedla2004

나는 내가 주위의 틱으로 생각했던 것을 몰랐다 bin(x). 그리고 흠, 1<<n그것은 이미 충분히 길지만, 나는 런타임을 천문학적이지 않게 유지하고 싶습니다
Lynn

요컨대, 코드를 실행할 수있는 것이 중요한 특성 일 수 있습니다. :)
nedla2004 년

6

젤리 , 15 바이트

‘ÆḞ€fRṪạµƬL’Ɗ⁺Ị

1"비밀 피보나치"또는 0기타 방식으로 생성되는 음이 아닌 정수를 허용하는 모나드 링크 .

온라인으로 사용해보십시오! (더 큰 테스트 사례에는 너무 비효율적 임)

방법?

‘ÆḞ€fRṪạµƬL’Ɗ⁺Ị - Link: integer, I
        µƬ      - perform the monadic link to the left as a function of the current I,
                - collecting up all the inputs until the results are no longer unique:
‘               -   increment I -> I+1
 ÆḞ€            -   nth Fibonacci number for €ach n in [1,I+1]
     R          -   range from 1 to I
    f           -   filter discard (discard Fibonacci numbers not in the range, i.e. > I)
      Ṫ         -   tail (get the largest)
       ạ        -   absolute difference with I
                - This gives us a list from I decreasing by Fibonacci numbers to 0
                - e.g. for 88 we get [88,33,12,4,1,0]
                -      because (88-33)+(33-12)+(12-4)+(4-1)+(1-0)=55+21+8+3+1=88 
          L     - length (the number of Fibonacci numbers required plus one)
           ’    - decrement (the number of Fibonacci numbers required)
            Ɗ   - treat the last three links (which is everything to the left) as a monad:
             ⁺  - ...and repeat it
                - i.e. get the number of Fibonacci numbers required for the number of
                -      Fibonacci numbers required to represent I.
                -      This is 1 if I is Secretly Fibonacci, and greater if not)
              Ị - insignificant? (is the absolute value of that <= 1?)


5

C # (.NET 코어) , 124 (115) 98 바이트

a=>{int n=0,b,c;for(;a>0;a-=b,n++)for(b=c=1;c<=a;b=c-b)c+=b;for(b=c=1;c<n;c+=b)b=c-b;return c==n;}

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

-3 바이트 : for 루프로 변경 된 동안 ( Olivier Grégoire 덕분에 )
-6 바이트 : 스위치는 루프 외부에서 변수로 초기화 된 b 및 c를 사용하여 반환합니다 ( Kevin Cruijssen 덕분에 )
-17 바이트 : 두 번째 루프에서 변경된 조건이 루프에서 벗어나 마지막 루프에서 재사용 된 b 및 c 변수와 결합 ( raznagul 덕분에 )

언 골프 드 :

a => {
    int n = 0, b, c;                        // initialize variables

    for(; a > 0; a -= b, n++)               // increase n until a is 0
        for(b = c = 1; c <= a; b = c - b)   // set b and c to 1 for each a; set second largest Fibonacci number until largest Fibonacci number reaches a
            c += b;                         // set largest Fibonacci number of current sequence

    for(b = c = 1; c < n; c += b)           // while e is less than or equal to n, continue incrementing largest (e) Fibonacci number in the sequence
        b = c - b;                          // increment second-largest (d) Fibonacci number

    return c == n;                          // if c equals n, a is a secret Fibonacci number
}

1
for(;c<=a;b=c-b)c+=b;3 바이트를 절약 할 수 있습니다.
Olivier Grégoire

1
115 바이트 . 나는 {}루프의 모든 브래킷을 제거하고 모든 것을 루프에 for넣었습니다. 또한, 나는 변수 추가 r우리가 설정 한 1사용자에 if(e==n)하나만 그래서, 말과 수익을 return.
Kevin Cruijssen

둘 다 잘 부탁드립니다. while 루프를 for로 변경하려고했지만 어떻게 든 쉬운 방법을 놓쳤습니다. 반환을 위해 별도의 변수를 갖는 것이 더 좋습니다.
Meerkat

1
두 번째 루프의 조건을로 변경하면 루프 뒤에서 e<n로 이동하여 if결과적으로 returnfor 101 바이트 와 결합 할 수 있습니다.
raznagul

1
당신은 재사용하여 다른 3 바이트를 저장할 수 bc마지막 루프 및 제거 d하고 e.
raznagul

4

펄 6 , 58 바이트

{(1,&[+]...*>$_)∋($_,{$^n-(1,&[+]...^*>$n).tail}...0)-1}

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

1, &[+] ... * > $_ 피보나치 (Fibonacci) 서열 일 뿐이며, 편리한 비 무한 위치 (입력 번호)에서 정지합니다.

$_, { $^n - (1, &[+] ...^ * > $n).tail } ... 0입력 숫자로 시작하는 일련의 숫자이며, 이전 요소에서 가장 큰 피보나치 수를 이전 요소보다 작거나 같은 수로 얻은 각 연속 요소 0도달 하면 순서가 종료됩니다 . 예를 들어 $_is 140인 경우이 시퀀스는 140, 51, 17, 4, 1, 0입니다.

이 순서에서 하나를 빼면 숫자, 길이로 취급되며, 그 차이는 피보나치 수와 함께 더해 입력 숫자를 제공합니다. 그런 다음이 번호는 첫 번째 피보나치 시퀀스의 멤버 자격을 확인합니다.


나는 &[+]이전 과 같은 트릭을 보지 못했습니다 ! 두 개의 초기 용어를 정의 할 필요가 없습니다.
Jo King

1
피보나치 수열을 함수와 다른 몇 가지 변경 사항에 할당하여 51 바이트
Jo King

l4m2의 JavaScript 응답 포트, 50 바이트
nwellnhof

@nwellnhof Ha, 나는 작은 차이를
Jo King

3

펄 6 , 48 바이트

{4>($_,{$_,{$_-(1,&[+]...*>$_)[*-2]}...^0}...1)}

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

단일 숫자에 도달 할 때까지 입력을 Zeckendorf Representation 목록으로 반복 변환 한 다음 시퀀스 길이가 4 미만인지 확인합니다.

가운데의 Zenckendorf 기능은 대부분 몇 가지 개선 된 Sean의 답변 에서 비롯된 입니다.

설명:

{4>($_,{$_,{$_-(1,&[+]...*>$_)[*-2]}...^0}...1)}
{                                              } # Anonymous code block
                                          ...     # Define a sequence:
    $_  # That starts at the input
      ,{                                 }  # Each element is defined by:
                                   ... # Another sequence that:
        $_,   # Starts at the previous element
            $_-   # The previous element minus
                1,&[+]...*     # The Fibonacci sequence
                          >$_  # Ending when it is larger than the previous element
               (             )[*-2]  # The second from last element
          {                        }...^0  # Run until 0, discarding the last element
         # This returns the length of the Zeckendorf Representation
                                         ...1  # Run this until it is length 1
 4>(                                         )  # Return true if the length of the sequence is smaller than 4

예를 들어,에 대한 서열 2되고 2 1이후 2이미 피보나치 수있다. 의 시퀀스는 140입니다 140 5 1. 5는 피보나치 수이므로 true를 반환합니다. 의 시퀀스는 33입니다 . 피보나치 수가 아니기 33 4 2 1때문에 4시퀀스의 길이는 4입니다.


3

05AB1E , 14 바이트

ΔDÅFθ-¼}¾ÅF¾<å

온라인으로 사용해보십시오 . counter_variable를 0으로 재설정 할 수 없기 때문에 모든 테스트 사례에 대해 테스트 스위트 가 없습니다. 모든 것을 직접 확인했지만 정확합니다.

설명:

Δ      }          # Loop until the top of the stack no longer changes
 D                #  Duplicate the top of the stack
                  #  (implicitly the input in the first iteration)
  ÅF              #  Get a list of all Fibonacci numbers lower than this number
    θ             #  Get the last item (largest one)
     -            #  Subtract it from the number
      ¼           #  Increase the counter_variable by 1 every iteration
        ¾         # After the loop, push the counter_variable
         ÅF       # Get all Fibonacci numbers below this counter_variable
           ¾<     # Push the counter_variable again, and subtract 1
             å    # Check if this value is in the list of Fibonacci numbers
                  # (and output implicitly)

참고 :이 counter_variable될 것 5입력 139하고 6입력 140위해서는 있기 때문에, Δ스택을 확인 -loop 동일하게 유지는 물론 추가로 반복 않습니다.



2

레티 나 0.8.2 , 61 바이트

.+
$*
M`((?>\2?)(\1|\G.))*..|.
.+
$*
^(((?>\3?)(\2|^.))*.)?.$

온라인으로 사용해보십시오! 링크에는 테스트 사례가 포함됩니다. 설명:

.+
$*

단항으로 변환합니다.

M`((?>\2?)(\1|\G.))*..|.

필요한 피보나치 수를 세십시오.

첫 번째 대안은 2 이상의 피보나치 수를 처리합니다. 첫 번째 패스 \2에는 아직 존재하지 않지만 다행히 선택 사항이므로 일치하지 않아도됩니다. \1존재하지 않지만, 운 좋게도 \G.경기 시작시 단일 문자와 일치하는 대안이 있습니다. 모두 \2하고 \1, 따라서 값 1에 걸릴.

이후의 패스에서는 \2존재하므로 일치시킵니다. 이번에 \1는 실패하면 실패 \2하지만 ( 보다 큼 ) 실패 하지만 성공 (?>)하면 역 추적을 방지하므로 \2일치하지만 \1시도하지 않으면 그냥 시도하지 않습니다 \1. ( \G1패치의 시작을 지나서 진행 한 이후로 항상 실패합니다.) 마지막으로 \2이전 값을받는 \1동안 \1두 값의 합 을 받습니다.

따라서 우리는 가능한 한 많은 피보나치 수와 일치합니다. 시퀀스의 부분합이 때문에 1, 2, 3, 5...있는 0, 1, 3, 6, 11...적은 우리 끝에 정합 (2)에 의해 마무리 피보나치 수열보다 예에서 2.

이것은 분명히 1 자체와 일치하지 않으므로 대체가 해당 경우를 처리합니다.

.+
$*

단항으로 변환합니다.

^(((?>\3?)(\2|^.))*.)?.$

피보나치 수인지 테스트하십시오. 이것은 첫 번째 테스트와 동일한 아이디어를 사용하지만 ^대신 사용 \G하고 정확하게 일치해야하므로 골퍼와 달리 교대 대신 선택적 캡처를 사용하지만 캡처 횟수는 1 씩 증가합니다.

망막 , 35 바이트

.+
*
2}C`((?>\2?)(\1|\G.))*..|.
^1$

온라인으로 사용해보십시오! 링크에는 테스트 사례가 포함됩니다. 설명:

.+
*

단항으로 변환합니다.

C`((?>\2?)(\1|\G.))*..|.

필요한 피보나치 수를 세십시오. (변환과 카운트를 모두 반복하면 처음부터 단항으로 카운트를 얻는 것보다 전체 바이트가 절약됩니다.)

2}

이전 단계를 총 두 번 수행하십시오. 피보나치 수와 합산하는 데 필요한 피보나치 수를 계산합니다.

^1$

숫자가 비밀리에 피보나치 인 경우 결과는 1입니다.


1

파이썬 (2) , 146 (137) 바이트

lambda a:len(g(len(g(a))))<2
f=lambda n:n<3or f(n-2)+f(n-1)
def g(a,n=1):j=f(n-1);return[j]if a-j<1else[j]+g(a-j)if a-f(n)<0else g(a,n+1)

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

f ()는 n 번째 피보나치 수의 값을 반환하는 재귀 함수입니다. 이 답변 에서 가져 왔습니다 .

g ()는 주어진 숫자의 Zeckendorf Representation을 정수 목록으로 반환하는 재귀 함수입니다.

모든 피보나치 수는 g ()에서 한 항목의 반환 길이를 가지므로, h ()는 g (n)의 길이가 g (n) == 1인지 확인합니다.

편집 : nedla2004 덕분에 9 바이트가 절약되었습니다 . 람다는 항상 최상의 솔루션은 아닙니다.


1
138 바이트 . 나는 대부분 변수를 g정의 f(n-1)할 수 있도록 함수를 만들었습니다 . 에서 커플 다른 변화 ==<는 같은 곳.
nedla2004
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.