반복되는 피보나치 숫자는 무엇입니까?


30

아시다시피 피보나치 수는 시리즈의 이전 두 숫자의 합입니다.

Fibonacci Digit ™는 두 개의 이전 자릿수 의 합입니다 .

예를 들어, 시리즈의 시작을 위해 1,1,이 시리즈는 것 1,1,2,3,5,8,13,4,7,11,2...후 변경이 발생 13, 어디서, 대신에 추가로 8+13, 추가 1+3. 이 시리즈는 여기서 끝에서 루프 4+7=11, 그리고 1+1=2시리즈의 시작과 동일합니다.

다른 예를 들어, 시리즈 시작 2,2: 2,2,4,6,10,1,1,2,3,5,8,13,4,7,11,2,3.... 이것은 고유하게 시작되지만 숫자가에 합산되면으로 10끝나고 1+0=1, 0+1=1시리즈는 시리즈와 동일한 방식으로 계속 반복 1,1됩니다.


도전

정수 입력이 주어지면 0≤n≤99피보나치 숫자 시리즈에서 두 자리로 시작하는 루프를 계산하십시오. (당신은 확실히하는 허용 범위의 정수를 고려 있지만 필수 사항은 아닙니다.) 한 자리 입력을 제공하는 경우 코드는 시리즈의 시작을 나타 내기 위해 그것을 해석한다 0,n.

루프에서 두 자리 숫자 모두 두 자리 숫자로 출력 되어야합니다 . 예를 들어, for 루프 1,1에는 13not 이 포함 1,3됩니다.

출력은 루프의 첫 번째 숫자로 시작합니다. 그래서, 위의 제한 사항에 따라, 대한 루프 1,1로 시작 2하기 때문에, 1,1그리고 11별도로 계산됩니다.

각 출력 수는 일관된 한 원하는대로 분리 할 수 ​​있습니다. 모든 예제에서 쉼표를 사용하지만 항상 동일한 구분을 사용하는 한 공백, 줄 바꿈, 임의의 문자 등이 모두 허용됩니다. 그래서 2g3g5g8g13g4g7g11에 대한 법적 출력 1,하지만 2j3g5i8s13m4g7sk11하지 않습니다. 일관된 구분 기호로 구분 된 올바른 순서로 올바른 숫자가 있으면 문자열, 목록, 배열 등을 사용할 수 있습니다. 전체 출력 브라케팅도 허용됩니다 (예 : (5,9,14)또는 [5,9,14]등).

테스트 사례 :

1 -> 2,3,5,8,13,4,7,11
2 -> 2,3,5,8,13,4,7,11
3 -> 11,2,3,5,8,13,4,7
4 -> 3,5,8,13,4,7,11,2
5 -> 2,3,5,8,13,4,7,11
6 -> 3,5,8,13,4,7,11,2
7 -> 14,5,9
8 -> 13,4,7,11,2,3,5,8
9 -> 11,2,3,5,8,13,4,7
0 -> 0
14 -> 5,9,14
59 -> 5,9,14

이것은 이므로 가장 적은 바이트 수가 이깁니다.


1
0 n 99 대신 2 자리를 입력으로 사용할 수 있습니까 ?099 ?
Arnauld

1
에서처럼 하나의 입력이 아닌 두 개의 입력을 취합니까? 아니오
DonielF

난 아직도 이유를 이해하지 않습니다 1459같은 결과를 제공합니다. 59시작으로 해석되는 경우5,9 루프의 일부로 후 반드시 것을 허용하는 14그 루프의 시작해야 하는가?

1
@williamporter 시퀀스의 시작은입니다 0,1,1,2,3,5,8,13,4,7,11,2,3. 루프가 처음 반복되는 시간은 두 번째 2입니다.
DonielF

2
@Neil 해당 시퀀스의 시작은 1,4,5,9,14,55,9,14,5,9입니다. 둘 다 두 번째부터 시작합니다 5. 앞에서 말했듯이 입력 만 분리됩니다. 이후 숫자는 순서대로 숫자를 함께 유지합니다.
DonielF

답변:


10

젤리 , 15 바이트

DFṫ-SṭḊ
d⁵ÇÐḶZḢ

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

작동 원리

d⁵ÇÐḶZḢ  Main link. Argument: n (integer)

d⁵       Divmod 10; yield [n:10, n%10].
  ÇÐḶ    Call the helper link until a loop is reached. Return the loop.
     Z   Zip/transpose the resulting array of pairs.
      Ḣ  Head; extract the first row.


DFṫ-SṭḊ  Helper link. Argument: [a, b] (integer pair)

D        Decimal; replace a and b with the digits in base 10.
 F       Flatten the resulting array of digit arrays.
  ṫ-     Tail -1; take the last two digits.
    S    Compute their sum.
      Ḋ  Dequeue; yield [b].
     ṭ   Append the sum to [b].

6

펄 6 , 96 78 75 바이트

nwellnhof 덕분에 -3 바이트

{0,|.comb,((*~*)%100).comb.sum...{my$a=.tail(2);m/(\s$a.*)$a/}o{@_};$_&&$0}

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

0은 0을 반환하고 다른 숫자는 뒤에 공백이있는 공백으로 구분 된 숫자로 문자열 화하는 Match 객체를 반환합니다.

설명:

{                                                                         }   # Anonymous code block
 0,|.comb,                    ...   # Start a sequence with 0,input
                                    # Where each element is
                          .sum      # The sum of
          (     %100).comb          # The last two digits
           (*~*)                    # Of the previous two elements joined together
                                                                         # Until
                                 {                           }o{@_}   # Pass the list into another function
                                  my$a=.tail(2); # Save the last two elements
                                                m/(\s$a.*)$a/  # The list contains these elements twice?
                                                                     # And return
                                                                   ;$_     # Input if input is 0
                                                                      &&   # Else
                                                                        $0 # The looping part, as matched

5

자바 스크립트 (ES6)  111 104  103 바이트

f=(n,o=[p=n/10|0,n%10])=>n^o[i=o.lastIndexOf(n=(q=p+[p=n])/10%10+q%10|0)-1]?f(n,[...o,n]):o.slice(i,-1)

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

댓글

f = (                       // f = recursive function taking:
  n,                        //    n = last term, initialized to the input
  o = [                     //    o = sequence, initially containing:
    p = n / 10 | 0,         //      p = previous term, initialized to floor(n / 10)
    n % 10 ]                //      n mod 10
) =>                        //
  n ^                       // we compare n against
  o[                        // the element in o[] located at
    i = o.lastIndexOf(      //   the index i defined as the last position of
      n =                   //     the next term:
        (q = p + [p = n])   //       q = concatenation of p and n; update p to n
        / 10 % 10           //       compute the sum of the last two digits
        + q % 10            //       of the resulting string
        | 0                 //       and coerce it back to an integer
      ) - 1                 //   minus 1
  ] ?                       // if o[i] is not equal to n:
    f(n, [...o, n])         //   append n to o[] and do a recursive call
  :                         // else:
    o.slice(i, -1)          //   we've found the cycle: return it

5

파이썬 (3) , 187 (176) 158 139 138 129 121 120 112 96 95 120 116 바이트

f=lambda n,m=0,z=[]:(n,m)in zip(z,z[1:])and z[z.index(m)::-1]or f((z and n//10or m%10)+n%10,z and n or n//10,(m,*z))

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

편집 : @ Jules가 지적한대로 에서 더 짧은 솔루션은 Python 3.6 이상에 적용됩니다. 더 이상 Python 3 / 3.6 + 용 솔루션이 없습니다.

편집 : 색인 생성 z 이 너무 장황했습니다. 그것 없이는을 사용하면 아무런 이득이 없습니다 eval.

편집 : 마지막 두 요소가 이미 시퀀스에 나타나는지 간단하게 발견했습니다.

편집 : 튜플 목록에서 변경 출력 형식은 대체 + lambdadef

편집 :로 돌아가 lambda지만에 포함 t되었습니다 f.

편집 : 입력 n은 실제로 z재귀 접근 방식의 꼬리를 나타내는 컬렉션 증가의 헤드로 해석 될 수 있습니다 . 또한 @ Arbo 의 솔루션을 다시 능가 합니다.

편집 : 실제로 16 바이트를 자르는 head에서 두 개의 항목을 풀 수 있습니다.

편집 : 실제로 17 바이트.

편집 : @ Arbo 솔루션에서 지적했듯이 초기 테스트 사례에서 1459같이 나중에 잘못된 것으로 입증 된 답변 과 사례를 제공했습니다. 지금은 짧지 않지만 적어도 올바르게 작동합니다.


f-strings과 의 남용 eval. 어떻게 든 쉽게 할 수 있다고 생각하지만 원래 ungolfed 코드는 다음과 같습니다.

def is_subsequence(l1, l2):
    N, n = len(l1), len(l2)
    for i in range(N-n):
        if l1[i:i+n]==l2:
            return True
    return False

def generate_sequence(r):
    if is_subsequence(r,r[-2:]):
        return r
    last_two_digits = "".join(map(str,r))[-2:]
    new_item = sum(int(digit) for digit in last_two_digits)
    return generate_sequence(r + [new_item])

def f(n):
    seq = generate_sequence([n,n])[::-1]
    second_to_last = seq[1]
    first_occurence = seq.index(second_to_last)
    second_occurence = seq.index(second_to_last, first_occurence + 1)
    return seq[first_occurence + 1 : second_occurence + 1][::-1]

1
작은 수정 : 이것은 Python 3.6 이상입니다. 3.5 이상에서는 작동하지 않습니다.
0xdd

1
테스트 코드가 작동하지 않는 것 같습니다. 의 입력 59수율(14, 5, 9)
ARBÖ

도전을 시작한 후 테스트 사례가 변경되어 결과가 잘못되었습니다. 작동하도록 솔루션을 변경했지만 지금은 그리 짧지 않습니다. 그럼에도 불구하고 지적 해 주셔서 감사합니다.
니시오 카

4

C (GCC) , 114 (112) 109 바이트

f(n,s){int i[19]={};for(s=n/10,n%=10;i[s]-n;n+=n>9?-9:s%10,s=i[s])i[s]=n;for(;printf("%d ",s),i[s=i[s]]-n;);}

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

ceilingcat 에서 -3

후행 공간을 포함합니다.

f(n,s){
    int i[19]={};                               //re-initialize edges for each call
    for(s=n/10,n%=10;                           //initialize from input
        i[s]-n;                                 //detect loop when an edge s->n repeats
        n+=n>9?-9:s%10,s=i[s])i[s]=n;           //step
    for(;printf("%d ",s),i[s=i[s]]-n;);         //output loop
}

1
허, do...while단일 문장 인 경우 중괄호가 필요하지 않습니다. O_o
ASCII 전용


2

자바 (JDK) 194 바이트

n->"acdfinehlcdfinehfjofj".chars().map(x->x-97).skip((n="abbicbcsfibbbgqifiibbgbbbcsfbiiqcigcibiccisbcqbgcfbffifbicdqcibcbicfsisiibicfsiffbbicfsifiibicfsifii".charAt(n)%97)).limit(n<1?1:n<9?8:3)

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

파이썬이 이미 187의 답을 가지고 있다는 것을 감안할 때 하드 코드 된 것이 가장 짧았습니다 ...


2

하스켈, 100 바이트

d!p@(s,t)|(_,i:h)<-span(/=p)d=fst<$>i:h|q<-d++[p]=q!(t,last$mod s 10+t:[t-9|t>9])
h x=[]!divMod x 10

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

d!p@(s,t)                -- function '!' recursively calculates the sequence
                         -- input parameter:
                         -- 'p': pair (s,t) of the last two numbers of the sequence
                         -- 'd': a list of all such pairs 'p' seen before
  |       <-span(/=p)d   -- split list 'd' into two lists, just before the first
                         -- element that is equal to 'p'
   (_,i:h)               -- if the 2nd part is not empty, i.e. 'p' has been seen
                         -- before
          =fst<$>i:h     -- return all first elements of that 2nd part. This is
                         -- the result.
  |q<-d++[p]             -- else (p has not been seen) bind 'q' to 'd' followed by 'p'
   =q!                   -- and make a recursive call to '!' with 'q' and
     (t,    )            -- make the last element 't' the second to last element
                         -- the new last element is
          [t-9|t>9]      -- 't'-9 (digit sum of 't'), if 't'>9
       mod s 10+t        -- last digit of 's' plus 't', otherwise

h x=                     -- main function
     []!divMod x 10      -- call '!' with and empty list for 'd' and
                         -- (x/10,x%10) as the pair of last numbers

2

파이썬 2 , 123 114 113 바이트

n=input()
p=b=l=n/10,n%10
while~-(b in p):p+=b,;l+=(b[1]/10or b[0]%10)+b[1]%10,;b=l[-2:]
print l[p.index(b)-2:-2]

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

이 프로그램은 p시퀀스에서 발생한 모든 2 값 쌍 의 튜플 을 작성하며 일부 바이트를 절약하기 위해 정크로 초기화됩니다. 시퀀스 자체는 튜플에 내장되며,이 튜플 l의 마지막 두 요소는 b쉽고 짧은 참조 를 위해 저장됩니다 . 즉시 반복이 발견, 우리는의 인덱스 찾아 볼 수 있습니다 b에서 p루프가 시작 위치를 알하기를.

편집 : 이것을 조금 정리하고 한 바이트 더 줄였습니다 ... 내 방법은 바이트 수 제한에 가까워 보입니다.이 작업을 중단해야합니다.


1

, 46 바이트

≔E◧S²ΣιθW¬υ≔ΦE⊖L⊞OθΣ…⮌⪫θω²✂θλLθ¹⁼κ✂θ⊗⁻λLθλ¹υIυ

온라인으로 사용해보십시오! 링크는 자세한 버전의 코드입니다. 설명:

≔E◧S²Σιθ

숫자를 입력하고 2 자로 채운 다음 각 문자의 디지털 합계를 가져와 결과 목록을 저장하십시오.

W¬υ

루프 목록이 비어있는 동안 반복하십시오.

⊞OθΣ…⮌⪫θω²

이전 두 자리의 합계를 계산하여 피보나치 목록에 추가하십시오.

E⊖L...✂θλLθ¹

목록의 사소한 접미사를 모두 사용하십시오.

≔Φ...⁼κ✂θ⊗⁻λLθλ¹υ

반복되지 않는 것을 필터링하고 루프 목록에 결과를 저장하십시오.

Iυ

루프 목록을 문자열로 캐스트하고 인쇄하십시오.



1

파이썬 2 , 149139 바이트

s=input()
s=[s/10,s%10]
while zip(s,s[1:]).count((s[-2],s[-1]))<2:s+=[(s[-1]/10or s[-2]%10)+s[-1]%10]
print s[-s[::-1].index(s[-2],2)-1:-2]

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

음수가 아닌 정수를 입력으로 예상합니다. 더 작은 바이트 수이지만 99보다 큰 정수에는 더 이상 작동하지 않을 수 있습니다.

설명:

# get the input from STDIN
s=input()
# convert the input into two integers via a divmod operation
s=[s/10,s%10]
# count number of times the last two numbers appear in sequence in list.
# turn list into list of adjacent value pairs Ex: [1,1,2]->[(1,1),(1,2)]
      zip(s,s[1:])
                  # count number of times the last two items in list appear in entire list
                  .count((s[-2],s[-1]))
# if >1 matches, we have found a repeat.
while .................................<2:
        # the first digit of the last number, if it is >9
        # else the last digit of the second to last number
        (s[-1]/10or s[-2]%10)
                             # the last digit of the last number
                             +s[-1]%10
    # add the new item to the list
    s+=[..............................]
         # reverse the list, then find the second occurrence of the second to last item
         s[::-1].index(s[-2],2)
# get the section of the list from the second occurrence from the end, discard the final two items of the list
print s[-......................-1:-2]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.