Digital Sum Fibonacci


30

Hepimiz Fibonacci dizisine aşinayız :

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

Ancak, bunun yerine önceki 2 girişin dijital toplamınıf(n) = f(n-1) + f(n-2) alacağız .


Dizi hala başlamalı 0, 1, bundan sonra farklılıklar hızla ortaya çıkıyor. Bu liste 0 indeksli, 1 indisli de kullandığınız durumu kullanabilirsiniz.

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)

Not: Mücadelenin kendisini gönderinceye kadar tekrarı fark etmedim ve burada yeni bir Fibonacci mücadelesi yazmanın imkansız olacağını düşünüyordum.


Göreviniz, bir numara verildiğinde n, bu dizinin digit basamağını çıkarmanızdır.

İlk 3 basamak: [0,1,1],

24 basamaklı tekrarlanan model: [2,3,5,8,13,12,7,10,8,9,17,17,16,15,13,10,5,6,11,8,10,9,10,10]

İpucu: Bu tekrarı istifade etmek için kullanabilirsin.


Bu , en düşük bayt sayımı kazanır.


BONUS: Cevabınızdaki tekrarı kullanırsanız, sıradaki tekrarlamadan faydalanan ve 100 puanlık bir lütuf olan en düşük bayt sayısı cevabını vereceğim. Bu, orijinal cevabınızın ardından, orijinal cevabınızın bir parçası olarak gönderilmelidir. Bu yayını neden bahsettiğimin bir örneği olarak gör: https://codegolf.stackexchange.com/a/108972/59376

Bu bonusa hak kazanabilmek için kodunuzun O(1)bir açıklama ile ( ) sürekli olarak çalışması gerekir .

Bonus Kazanan: Dennis https://codegolf.stackexchange.com/a/108967/59376 <Dennis kazandı.

En Benzersiz Uygulama: https://codegolf.stackexchange.com/a/108970/59376
(Ayrıca, doğru cevap seçildikten sonra sonlandırılmış 100 puan alacaksınız)


2
1 tabanlı indeksleme kullanabilir miyiz yoksa 0 tabanlı mı olmalı?
Business Cat

1
@BusinessCat evet, elbette, boşver.
Magic Octopus Urn

1
Tekrarlamanın avantajlarından nasıl yararlanırsınız ? Kodlanmış olması gerekiyor mu yoksa sadece bir%24 "normal" bir çözüme mu?
Dennis,

1
@Dennis Demek istediğim tekrarlamanın avantajlarından yararlanmayı tanımlarım O(1). Eğer tekrarı gerçekten kullanıyorsa, kodunuz sürekli olarak çalışıyor olmalıdır.
Magic Octopus Urn

1
Girişteki teknik olarak% 24 @Dennis, 27 yinelemede üst sınırlandırır; iken, ilginç değil, kesinlikle sayar.
Magic Octopus Urn

Yanıtlar:


7

Vaha , 5 bayt

Kod:

ScS+T

Çevrimiçi deneyin!

Genişletilmiş sürüm:

ScS+10

Açıklama:

ScS+   = a(n)
     0 = a(0)
    1  = a(1)
S      # Sum of digits on a(n-1)
 c     # Compute a(n-2)
  S    # Sum of digits
   +   # Add together

Ah dostum ... Ben de Oasis öğrenmeye başlayacağım.
Magic Octopus Urn

28

JavaScript (ES6), 45 bayt

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>

xve yher ikisi de olamaz 9, çünkü bu önceki sayının olmasını gerektirir 0, bu nedenle dijital toplamları geçemez 17. Bu, daha büyük sayılar için dijital kökün 9, geri kalan modülo ile aynı olduğu anlamına gelir 9.


6
Bu, bu aynı zamanda tekrar liderine denk bir ödül alacak ... Bu harika bir matematiksel içgörü.
Magic Octopus Urn

13

Python 2, 53 bayt

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

Özyinelemeli işlevi. Taban vakaları n=0ve n=1verim n, daha çok sayıda çağırarak değerini hesaplamak f(n-1)ve f(n-2)bir kullanan bir tamsayıya her karakter dönüştürme, iki dizeleri bitiştirmek bir dizeye her dönüştürme mapile intfonksiyon ve daha sonra elde edilen listesi özetliyor.


Modulo-24 bilgisini kullanarak şu anda 56 bayt özyinelemeli adsız işlevi elde edebilirsiniz:

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

1
Evet! Çok fazla +1! Bir tekrarlama cevabı :). Şerefinize bir bonus bölümü ekledim efendim, şimdi 100 puanlık ödül yarışmasında lider sizsiniz!
Magic Octopus Urn

11

JavaScript (ES6), 34 bayt

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

Tarayıcınızı 27'nin üzerindeki girişler için donabilir, ancak tüm giriş değerleri için çalışır. Bu basit bir önbellekle doğrulanabilir:

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'in mükemmel cevabında işaret edildiği gibi , çıktı asla 17'yi geçemez, bu nedenle 9'un üzerindeki herhangi bir çıktının dijital toplamı eşittir n%9. Bu aynı zamanda 9'un altındaki çıktılarla da çalışır; 9 ile çalışmasını sağlayabiliriz.~- , modülden önce 1'i çıkardıktan sonra 1'e geri ekleriz.


Sabit kodlama ile yapabileceğim en iyi 50 byte:

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

6

Jöle , 8 bayt

;DFS
ç¡1

Çevrimiçi deneyin!

Nasıl çalışır

ç¡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.

Alternatif çözüm, 19 bayt, sabit zaman

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

Çevrimiçi deneyin!

Nasıl çalışır

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.


4

JavaScript (ES6), 52 46 45 bayt

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

kullanım

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

Çıktı

13

açıklama

Bu işlev, girişin 2'den küçük olup olmadığını kontrol eder ve öyleyse girişi döndürür. Aksi takdirde, birbirlerine dize olarak eklenen iki değerden oluşan bir dizi oluşturur. Bu iki değer, işlevi çağırmanın sonucudur.input - 1 veinput - 2 .

...Operatör ama şimdi, sonra tekrar bir dizeye dönüştürülür karakterler bir diziye bu dizeyi böler +değerler arasındaki es. Bu dize daha sonra kod olarak yorumlanır, böylece toplam hesaplanır, sonra döndürülür.

Bu çift özyinelemeli bir algoritmadır, bu onu oldukça verimsiz kılar. n-2Giriş için 2 fonksiyon çağrısı gerekir n. Gibi, burada daha uzun ama daha hızlı bir çözüm. ETHproductions'a geldiğiniz için teşekkürler.

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

Bu, 27 gibi büyük değerler için işe yaramaz, tarayıcıyı dondurur (en azından benim için yapar)
Kritixi Lithos 19

Biraz zaman alıyor, ama oraya varacak ... sonunda. Bunu inceleyeceğim, ancak performans bu zorluk için önemli değil ...
Luke

Tanrım, bu hesaplama açısından çok yoğun değil, programınız 27'den daha büyük değerler için çalışmalı ... Fakat 1-28 için çalışıyorsa, teknik olarak daha yüksek için çalıştığını kanıtlar.
Magic Octopus Urn

1
@KritixiLithos Sorun bu özyinelemektir. Sekanstaki n. Sayının hesaplanması , oldukça hızlı bir şekilde oluşan yaklaşık 2 ^ (n-2) fonksiyon çağrısını gerektirir.
ETHProductions

[..._(--$)+[_(--$)]]:-) ile bir bayt kaydedebilirsiniz
ETHproductions

4

05AB1E , 8 bayt

XÎF‚¤sSO

Çevrimiçi deneyin!

açıklama

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 bayt

Martin Ender sayesinde 2 bayt kaydedildi

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

Basit özyinelemeli algoritması, hiçbir şey fantezi. 0 endeksli.

Çevrimiçi deneyin! veya 0-50 test edin (aslında oldukça hızlı çalışıyor).

açıklama

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 bayt

Tekrarı kullanarak çözüm. Jonathan Allan'ın çözümüne benzer bir algoritma.

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

Çevrimiçi deneyin!


3

Perl 6 ,  41  37 bayt

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

Dene

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

Dene

{ # 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
İç lambda olarak yazabilirsiniz *.comb.sum+*.comb.sum.
sml

2

MATL , 15 bayt

lOi:"yyhFYAss]&

Çevrimiçi deneyin!

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 bayt

veya kaçış kodlarını her biri 1 bayt olarak sayan 61 bayt

0 dizin oluşturuldu. Diğer cevapların bazılarına benzer bir değerler tablosunu indeksliyorum ancak 4 baytlık parçaya sıkıştırdım. Mod 24 versiyonunu incelemekten zahmete girmedim, çünkü diğerleri çoktan bunu yaptığını düşündüğümden ilginç olmadığını düşünmüştüm, ama hadi yüzleşelim, C yine de kazanmayacak.

#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)

açıklama:

#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

Çevrimiçi deneyin!


Çıkış kodlarını her biri 1 bayt olarak sayıyorum! Harika iş
Albert Renshaw 11

2

Japt , 27 25 bayt

U<2?U:~-ß´U %9+~-ß´U %9+2

Çevrimiçi deneyin!

ETHproductions sayesinde 2 bayt kurtardı.


Hey, Japt'u kullandığın için teşekkürler :-) ´Yerinde --iki bayttan tasarruf etmek için kullanabilirsin .
ETHproductions


2

Mathematica, 49 bayt

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

Basit özyinelemeli tanımı. Bir süre sonra oldukça yavaşlar.

Mathematica, 79 71 bayt

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

Periyodik desenin kodlanması. Çok hızlı ve tatmin edici bir şekilde Mathematica'ya şimşek çakıyor :) 8 byte tasarruf için JungHwan Min'e teşekkürler!


İkinci kodunuz için LetterNumber@"JJBCEHMLGJHIQQPOMJEFKHJ"ise 8 byte daha kısa 43626804920391712116157158790~IntegerDigits~18.
JungHwan Min,

haklısın! Bu günlerden birini hatırlayacağım LetterNumber....
Greg Martin

1

Python 2 , 56 bayt

Basit yinelemeli çözüm.

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

Çevrimiçi deneyin!

(a%9or a)+(b%9or b)Aslında kullanmak daha kısa olduğu ortaya çıktı sum(map(int(`a`+`b`)))!


Bence demek istediğin sum(map(int,a+b))(yorumlarda nasıl kullanılacağını

1

Güç kalkanı , 79 bayt

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

Çevrimiçi deneyin!

Her fordöngü doğrudan rakam toplamı hesaplamaları yapan uzun sıkıcı yinelemeli çözüm . Döngünün sonunda, istediğimiz sayı içeridedir, bu $byüzden boru hattında bırakılır ve çıktı gizlidir. Girdi ise 0, koşulun yanlış olduğu için döngü girmeyeceğini unutmayın, öyle $bkalır 0.


1

Toplu, 85 bayt

@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 cevabını partiye nasıl taşıyacağımı merak ediyordum, ancak ipucu @ Dennis'in Python çözümündeydi.


1

Pyth, 20 bayt

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

Sıfır dizinli bir tamsayı girişi alan ve sonucu basan bir program.

Test odası (Biçimlendirme için ilk bölüm)

Nasıl çalışır

[Açıklama daha sonra gelecek]


1

Ruby, 58 bayt

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

Basit kodlanmış çözüm.



1

Octave, 148 bayt

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'ye Hoşgeldiniz! Güzel ilk mesaj!
Rɪᴋᴇʀ

1

Haskell, 151 bayt

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Örneğin , işlevi çağırın .

Kod çok büyük endekslerle de çalışır. Uygulanan modulo 24 işlevselliği nedeniyle çok hızlı.

Sıkıştırılmamış kod:

-- 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 bayt

Çok uzun bir çözüm, ama ilk başta sahip olduğum 108'den daha iyi. Bunu yapmanın daha iyi bir yolu olduğundan şüpheleniyorum, ancak şu anda göremiyorum.

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

Bu, vektördeki sayıları sayılara ayırmak için kullanılan gsubve adlandırılmayan bir işlevdir scan(t=. Bunların toplamı, ilk madde düşürülürken vektöre eklenir. repeatdizi nzamanlarında ilerlemek için kullanılır ve sonuç vektörün ilk öğesidir.



0

Mathematica, 67 bayt

r=IntegerDigits;f@0=0;f@1=1;f[x_]:=f@x=Tr@r@f[x-1]+Tr@r@f[x-2];f@#&
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.