디지털 섬 피보나치


30

우리는 모두 피보나치 시퀀스에 익숙 합니다 .

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765

그러나 대신에, f(n) = f(n-1) + f(n-2)우리는 이전 2 개의 항목의 디지털 합계 를 취할 것 입니다.


0, 1차이가 급격히 나타난 후 시퀀스는 여전히로 시작해야합니다 . 이 목록은 색인이 0이며 1 색인을 사용할 수도 있습니다.

f(0)  = 0
f(1)  = 1
f(2)  = 1   # 0 + 1
f(3)  = 2   # 1 + 1
f(4)  = 3   # 1 + 2
f(5)  = 5   # 2 + 3
f(6)  = 8   # 3 + 5
f(7)  = 13  # 8 + 5
f(8)  = 12  # 8 + 1 + 3
f(9)  = 7   # 1 + 3 + 1 + 2
f(10) = 10  # 1 + 2 + 7
f(11) = 8   # 7 + 1 + 0
f(12) = 9   # 1 + 0 + 8
f(13) = 17  # 8 + 9
f(14) = 17  # 9 + 1 + 7
f(15) = 16  # 1 + 7 + 1 + 7
f(16) = 15  # 1 + 7 + 1 + 6
f(17) = 13  # 1 + 6 + 1 + 5
f(18) = 10  # 1 + 5 + 1 + 3
f(19) = 5   # 1 + 3 + 1 + 0
f(20) = 6   # 1 + 0 + 5
f(21) = 11  # 5 + 6
f(22) = 8   # 6 + 1 + 1
f(23) = 10  # 1 + 1 + 8
f(24) = 9   # 8 + 1 + 0
f(25) = 10  # 1 + 0 + 9
f(26) = 10  # 9 + 1 + 0
f(27) = 2   # 1 + 0 + 1 + 0
(After this point it repeats at the 3rd term, 0-indexed)

참고 : 챌린지 자체를 게시 할 때까지 반복을 알지 못했고 여기에서 또 다른 소설 피보나치 챌린지를 작성하는 것이 불가능하다고 생각했습니다.


당신의 작업에는 숫자가 주어 n지며이 시퀀스의 n 번째 숫자가 출력됩니다.

처음 3 자리 : [0,1,1],

24 자리 반복 패턴 : [2,3,5,8,13,12,7,10,8,9,17,17,16,15,13,10,5,6,11,8,10,9,10,10]

힌트 :이 반복을 유리하게 활용할 수 있습니다.


이것은 이며, 가장 낮은 바이트 수가 승자입니다.


보너스 : 귀하의 답변에 반복을 사용하는 경우, 시퀀스에서 100 점의 현상금을 사용하는 최저 바이트 수 답변을 수여합니다. 이것은 원래 답변 후에 원래 답변의 일부로 제출해야합니다. 내가 말하는 것에 대한 예제 로이 게시물을 참조하십시오 : https://codegolf.stackexchange.com/a/108972/59376

이 보너스를 받으려면 O(1)설명과 함께 일정한 시간 ( )으로 코드를 실행해야합니다 .

보너스 수상자 : Dennis https://codegolf.stackexchange.com/a/108967/59376 <Dennis won.

가장 고유 한 구현 : https://codegolf.stackexchange.com/a/108970/59376
(또한 정답을 선택한 후 최종 점수 100 점을받습니다)


2
1 기반 인덱싱을 사용할 수 있습니까, 아니면 0 기반이어야합니까?
비즈니스 고양이

1
@BusinessCat 그래, 망쳐
Magic Octopus Urn

1
반복을 이용하는 방법을 어떻게 정의 합니까? 하드 코드해야합니까, 아니면 그냥 %24"정상적인"솔루션에 추가합니까?
Dennis

1
@Dennis 나는 반복을 의미하는 것으로 정의 O(1)합니다. 코드가 실제로 반복을 악용하는 경우 코드는 일정한 시간 안에 실행되어야합니다.
Magic Octopus Urn

1
입력에서 @Dennis의 기술적으로 % 24는 27 반복에서 상한을 만들 것입니다. 흥미롭지는 않지만 확실히 중요합니다.
Magic Octopus Urn

답변:



28

자바 스크립트 (ES6), 45 바이트

f=(n,x=0,y=1)=>n?f(n-1,y,(x%9||x)+(y%9||y)):x
<input type=number min=0 oninput=o.textContent=f(this.value)><pre id=o>

x그리고 y둘 수 없습니다 9그 수는 이전 번호를 필요로하기 때문에 0, 디지털 합을 초과 할 수 있습니다 17. 이는보다 큰 수의 디지털 근 9이 나머지 모듈로와 동일 함을 의미합니다 9.


6
이것, 이것은 또한 반복 리더와 동등한 현상금을 얻을 것입니다 ... 이것은 놀라운 수학적 통찰력입니다.
Magic Octopus Urn

13

파이썬 2, 53 바이트

f=lambda n:n>1and sum(map(int,`f(n-1)`+`f(n-2)`))or n

재귀 기능. 의 기본 사례 n=0n=1yield n, 더 큰 숫자는 각각을 문자열로 호출 f(n-1)하고 f(n-2)변환하여 두 문자열을 연결하고를 사용하여 각 문자를 정수로 변환 하여 값을 계산합니다 map.int 함수를 한 다음 결과 목록을 합산하여 값을 계산합니다.


modulo-24 정보를 사용하여 현재 56 바이트 비 재귀 명명되지 않은 함수를 얻을 수 있습니다.

lambda n:int(('011'+'2358dc7a89hhgfda56b8a9aa'*n)[n],18)

1
예! 너무 많은 +1! 반복 답변 :). 명예 선생님에게 보너스 섹션을 추가했습니다. 이제 100 포인트 현상금 컨테스트의 리더가되었습니다!
Magic Octopus Urn

11

자바 스크립트 (ES6), 34 바이트

f=n=>n<2?n:~-f(--n)%9+~-f(--n)%9+2

27 이상의 입력에 대해서는 브라우저를 정지시킬 수 있지만 모든 입력 값에 대해 작동합니다. 간단한 캐시로 확인할 수 있습니다.

c=[];f=n=>n<2?n:c[n]=c[n]||~-f(--n)%9+~-f(--n)%9+2
<input type=number value=0 min=0 step=1 oninput="O.value=f(this.value)"> <input id=O value=0 disabled>

Neil의 훌륭한 답변 에서 지적했듯이 , 출력은 결코 17을 초과 할 수 없으므로 9를 초과하는 출력의 디지털 합은 n%9입니다. 이것은 9 이하의 출력에서도 작동합니다. 우리는 1을 빼서 9를 위해 작동시킬 수 있습니다.~- 모듈러스 앞에 다시 더함으로써 .


하드 코딩으로 할 수있는 최선의 방법은 50 바이트입니다.

n=>"0x"+"7880136ba5867ffedb834968"[n%24]-(n<3)*9+2

6

젤리 , 8 바이트

;DFS
ç¡1

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

작동 원리

ç¡1   Main link. No arguments. Implicit left argument: 0

  1   Set the right argument to 1.
ç¡    Repeatedly execute the helper link n times – where n is an integer read from
      STDIN – updating the left argument with the return value and the right
      argument with the previous value of the left argument. Yield the last result.


;DFS  Helper link. Arguments: a, b

;     Concatenate; yield [a, b].
 D    Decimal; convert both a and b to their base-10 digit arrays.
  F   Flatten the result.
   S  Compute the sum of the digits.

대체 솔루션, 19 바이트, 일정 시간

;DFS
9⁵ç23С⁸ịµṠ>?2

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

작동 원리

9⁵ç23С⁸ịµṠ>?2  Main link. Argument: n

9               Set the return value to 9
 ⁵              Yield 10.
  ç23С         Execute the helper link 23 times, with initial left argument 10
                and initial right argument 9, updating the arguments as before.
                Yield all intermediate results, returning
                [10,10,2,3,5,8,13,12,7,10,8,9,17,17,16,15,13,10,5,6,11,8,10,9].
   ⁸ị           Extract the element at index n. Indexing is 1-based and modular.
     µ          Combine all links to the left into a chain.
       >?2      If n > 2, execute the chain.
      Ṡ         Else, yield the sign if n.

1
D : "그냥 일정 시간의 전체 반복 섹션 계산하자"의 chuzpe +1
펠릭스 Dombek

4

자바 스크립트 (ES6), 52 46 45 바이트

_=$=>$<2?$:eval([..._(--$)+[_(--$)]].join`+`)

용법

_=$=>$<2?$:eval([..._(--$)+[_(--$)]].join`+`)
_(7)

산출

13

설명

이 함수는 입력이 2보다 작은 지 확인하고, 입력이 있으면 입력을 반환합니다. 그렇지 않으면 서로 문자열로 추가되는 두 값의 배열을 만듭니다. 이 두 값은 input - 1및로 함수를 호출 한 결과입니다 input - 2.

...연산자 이제는 함께 다시 문자열로 변환되는 문자의 배열로 분할 문자열 +값의 에스. 이 문자열은 코드로 해석되므로 합계가 계산되어 반환됩니다.

이것은 이중 재귀 알고리즘이므로 상당히 비효율적입니다. n-2입력을 위해 2 개의 함수 호출 이 필요 합니다 n. 따라서 더 길지만 빠른 솔루션이 있습니다. ETHproductions에 감사드립니다.

f=($,p=1,c=0)=>$?f($-1,c,eval([...p+[c]].join`+`)):c

27과 같은 큰 값에는 작동하지 않으며 브라우저를 정지시킵니다 (적어도 나를 위해 작동합니다)
Kritixi Lithos

시간이 좀 걸리지 만 결국에는 ... 살펴 보 겠지만,이 도전에있어 성능은 중요하지 않습니다 ...
Luke

글쎄요, 예수님, 그것은 계산적으로 강렬하지는 않습니다. 당신의 프로그램은 27 이상의 값에서 작동해야합니다. 그러나 1-28에서 작동한다면 기술적으로는 그것이 더 잘 작동한다는 것을 증명합니다.
Magic Octopus Urn

1
@KritixiLithos 문제인 재귀입니다. 시퀀스에서 n 번째 숫자를 계산 하려면 대략 2 ^ (n-2) 개의 함수 호출이 필요합니다.
ETHproductions

다음과 같이 바이트를 저장할 수 있습니다 [..._(--$)+[_(--$)]]:-)
ETHproductions

4

05AB1E , 8 바이트

XÎF‚¤sSO

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

설명

XÎ        # push 1,0,input
  F       # input_no times do:
   ‚      # pair the top 2 elements of the stack
    ¤     # push a copy of the 2nd element to the stack
     s    # swap the pair to the top of the stack
      S   # convert to list of digits
       O  # sum

3

CJam, 22 20 바이트

Martin Ender 덕분에 2 바이트 절약

ri2,{(_(jAb\jAb+:+}j

간단한 재귀 알고리즘으로 멋진 것은 아닙니다. 인덱스가 0입니다.

온라인으로 사용해보십시오! 또는 0-50 테스트 (실제로 꽤 빠르게 실행).

설명

ri                    Read an integer from input
  2,                  Push the array [0 1]
    {             }j  Recursive block, let's call it j(n), using the input as n and [0 1] as base cases
     (                 Decrement (n-1)
      _(               Duplicate and decrement again (n-2)
        jAb            Get the list digits of j(n-2)
           \           Swap the top two elements
            jAb        Get the list of digits of j(n-1)
               +       Concatenate the lists of digits
                :+     Sum the digits

CJam, 42 바이트

반복을 사용하는 솔루션. Jonathan Allan의 솔루션과 유사한 알고리즘.

ri_2,1+"[2358DC7A89HHGFDA56B8A9AA]"S*~@*+=

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


3

펄 6 ,  41  37 바이트

{(0,1,{[+] |$^a.comb,|$^b.comb}...*)[$_]}

시도 해봐

{(0,1,*.comb.sum+*.comb.sum...*)[$_]}

시도 해봐

{ # bare block lambda with implicit parameter 「$_」
  (

    0, 1,           # first two values

    # WhateverCode lambda with two parameters ( the two 「*」 )
    *.comb.sum      # digital sum of first parameter
    +
    *.comb.sum      # digital sum of second parameter

    ...            # keep using that code object to generate new values until:

    *              # never stop

  )[ $_ ]          # index into the sequence
}

1
내부 람다를로 쓸 수 있습니다 *.comb.sum+*.comb.sum.
smls

2

MATL , 15 바이트

lOi:"yyhFYAss]&

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

lO       % Push 1, then 0. So the next generated terms will be 1, 1, 2,... 
i        % Input n
:"       % Repeat that many times
  yy     %   Duplicate top two elements in the stack
  h      %   Concatenate into length-2 horizontal vector
  FYA    %   Convert to decimal digits. Gives a 2-row matrix
  ss     %   Sum of all matrix entries
]        % End
&        % Specify that next function (display) will take only 1 input
         % Implicit display


2

C, 96 바이트

또는 1 바이트로 이스케이프 코드를 계산하는 61 바이트

인덱스가 0입니다. 다른 답변 중 일부와 유사하게 값 조회 테이블을 인덱싱하고 있지만 4 바이트 청크로 압축했습니다. 나는 다른 사람들이 이미 그렇게했기 때문에 그것이 흥미 로웠다고 생각하지 않았기 때문에 mod 24 버전을 조사하는 것을 귀찮게하지 않았지만 그것을 직면하자 .C는 어쨌든 승리하지 않을 것이다.

#define a(n) n<3?!!n:2+(15&"\x1\x36\xba\x58\x67\xff\xed\xb8\x34\x96\x87\x88"[(n-3)/2%12]>>n%2*4)

설명:

#define a(n)                                                                                     // using a preprocessor macro is shorter than defining a function
             n<3?!!n:                                                                            // when n is less than 3 !!n will give the series 0,1,1,1..., otherwise..
                                                                             (n-3)/2%12          // condition the input to correctly index the string...
                           "\x1\x36\xba\x58\x67\xff\xed\xb8\x34\x96\x87\x88"                     // which has the repeating part of the series encoded into 4 bits each number
                                                                                                 // these are encoded 2 less than what we want as all numbers in the series after the third are 2 <= a(n>2) <= 17 which conforms to 0 <= a(n>2) - 2 <= 15
                                                                                        >>n%2*4  // ensure the data is in the lower 4 bits by shifting it down, n%2 will give either 0 or 1, which is then multiplied by 4
                        15&                                                                      // mask those bits off
                     2+                                                                          // finally, add 2 to correct the numbers pulled from the string

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


이스케이프 코드를 각각 1 바이트로 계산합니다! 훌륭한 직업
Albert Renshaw



2

Mathematica, 49 바이트

If[#<2,#,Tr[Join@@IntegerDigits[#0/@{#-1,#-2}]]]&

간단한 재귀 정의. 잠시 후 꽤 느려집니다.

Mathematica, 79 71 바이트

If[#<3,Sign@#,(9@@LetterNumber@"JJBCEHMLGJHIQQPOMJEFKHJ")[[#~Mod~24]]]&

주기적인 패턴을 하드 코딩합니다. Mathematica에 번개가 빠르고 만족스럽게 남용 :) 8 바이트를 절약 한 JungHwan Min에게 감사합니다!


두 번째 코드 LetterNumber@"JJBCEHMLGJHIQQPOMJEFKHJ"는보다 8 바이트 짧습니다 43626804920391712116157158790~IntegerDigits~18.
JungHwan Min

네가 옳아! 요즘 내가 기억할 것은 LetterNumber....
Greg Martin

1

파이썬 2 , 56 바이트

간단한 반복 솔루션.

a,b=0,1
exec'a,b=b,(a%9or a)+(b%9or b);'*input()
print a

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

(a%9or a)+(b%9or b)실제로 사용 하는 것보다 짧았습니다 sum(map(int(`a`+`b`)))!


나는 당신이 생각하는 것 sum(map(int,a+b))(댓글에서`를 사용하는 방법을 알 수 없음)

1

PowerShell , 79 바이트

$b,$c=0,1;for($a=$args[0];$a;$a--){$z=[char[]]"$b$c"-join'+'|iex;$b=$c;$c=$z}$b

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

for루프 마다 디지트-섬 계산을 직접 수행하는 긴 보링 반복 솔루션 . 루프가 끝나면 원하는 숫자가 $b에 있으므로 파이프 라인에 남아 있고 출력은 암시 적입니다. 입력이 0이면 조건이 false이므로 루프가 입력되지 않으므로 $b계속 유지 0됩니다.


1

배치, 85 바이트

@set/ax=0,y=1
@for /l %%i in (1,1,%1)do @set/az=x-x/10*9+y-y/10*9,x=y,y=z
@echo %x%

JavaScript 답변을 배치로 어떻게 이식 할 것인지 궁금하지만 실마리는 @Dennis의 Python 솔루션에 있습니다.


1

Pyth, 20 바이트

J,01VQ=+JssjRT>2J)@J

인덱스가없는 정수를 입력하여 결과를 인쇄하는 프로그램입니다.

테스트 스위트 (서식의 첫 부분)

작동 원리

[나중에 설명]


1

루비, 58 바이트

->n{n<3?n<=>0:"9aa2358dc7a89hhgfda56b8a"[n%24].to_i(18)}

간단한 하드 코딩 된 솔루션.



1

옥타브, 148 바이트

function f = fib(n)
  if (n <= 1)
    f = n;
  else
    f = sum(int2str((fib(n - 1)))-48) + sum(int2str((fib(n - 2)))-48);
  endif
endfunction

ppcg에 오신 것을 환영합니다! 좋은 첫 포스트!
Rɪᴋᴇʀ

1

하스켈, 151 바이트

import Numeric
import Data.Char
s i=foldr(\c i->i+digitToInt c)0$showInt i""
d a b=a:d b(s a+s b)
f 0=0
f 1=1
f 2=1
f i=d 2 3!!fromIntegral(mod(i-3)24)

로 함수를 호출하십시오. f 123456789012345678901234567890123456789012345678예를 들어로 .

이 코드는 매우 큰 지수에서도 작동합니다. 구현 된 모듈로 24 기능 때문에 매우 빠릅니다.

압축되지 않은 코드 :

-- FibonacciDigital
-- Gerhard
-- 13 February 2017

module FibonacciDigital () where

import Numeric
import Data.Char

-- sum of digits
digitSum :: Int -> Int 
digitSum i = foldr (\c i -> i + digitToInt c) 0 $ showInt i ""

-- fibonacci digital sequence function with arbitrary starting values
fibonacciDigitals :: Int -> Int -> [Int]
fibonacciDigitals a b = a : fibonacciDigitals b (digitSum a + digitSum b)

-- index -> fibonacci digital value
f :: Integer -> Int 
f 0 = 0 
f 1 = 1 
f 2 = 1 
f i = fibonacciDigitals 2 3 !! fromIntegral (mod (i-3) 24) 

-- End

0

R, 90 바이트

엄청나게 긴 해결책이지만 원래 가지고 있던 108보다 낫습니다. 이 작업을 수행하는 더 좋은 방법이 있다고 생각하지만 지금은 볼 수 없습니다.

function(n,x=0:1){repeat`if`(n,{x=c(x,sum(scan(t=gsub('',' ',x))))[-1];n=n-1},break);x[1]}

이 용도가 익명 함수 gsubscan(t=숫자로 벡터의 수를 분할한다. 이들의 합계는 벡터에 추가되고 첫 번째 항목은 삭제됩니다. repeat는 시퀀스 n시간 을 단계별로 실행하는 데 사용되며 결과는 벡터의 첫 번째 항목입니다.



0

수학, 67 바이트

r=IntegerDigits;f@0=0;f@1=1;f[x_]:=f@x=Tr@r@f[x-1]+Tr@r@f[x-2];f@#&
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.