Digital Sum Fibonacci

30

Nous connaissons tous la séquence de Fibonacci :

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

Cependant, au lieu de, f(n) = f(n-1) + f(n-2)nous prendrons la somme numérique des 2 entrées précédentes.


La séquence doit toujours commencer 0, 1, après quoi les différences sont rapidement apparentes. Cette liste est indexée 0, vous pouvez également utiliser l'index 1, indiquez celle que vous avez utilisée.

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)

Remarque: je n'ai pas remarqué la répétition jusqu'à ce que j'aie posté le défi lui-même, et ici je pensais qu'il serait impossible d'écrire un autre défi Fibonacci.


Votre tâche consiste, en fonction d'un nombre n, à sortir le nième chiffre de cette séquence.

Les 3 premiers chiffres: [0,1,1],

Motif répété à 24 chiffres: [2,3,5,8,13,12,7,10,8,9,17,17,16,15,13,10,5,6,11,8,10,9,10,10]

Astuce: Vous pourrez peut-être exploiter cette répétition à votre avantage.


C'est le , le nombre d'octets le plus bas est le gagnant.


BONUS: Si vous utilisez la répétition dans votre réponse, je vais attribuer à la réponse de décompte d'octets la plus basse qui profite de la répétition dans la séquence une prime de 100 points. Cela devrait être soumis dans le cadre de votre réponse d'origine, après votre réponse d'origine. Voir cet article comme un exemple de ce dont je parle: https://codegolf.stackexchange.com/a/108972/59376

Pour bénéficier de ce bonus, votre code doit être exécuté en temps constant ( O(1)) avec une explication.

Gagnant du bonus: Dennis https://codegolf.stackexchange.com/a/108967/59376 <Dennis a gagné.

Implémentation la plus unique: https://codegolf.stackexchange.com/a/108970/59376
(recevra également 100 points, finalisés après avoir choisi la bonne réponse)

Urne de poulpe magique
la source
2
Peut-on utiliser une indexation basée sur 1 ou doit-elle être basée sur 0?
Business Cat
1
@BusinessCat oui, bien sûr, vissez-le.
Magic Octopus Urn
1
Comment définissez-vous tire parti de la répétition ? Doit-il être codé en dur ou j'ajoute juste un %24à une solution "normale"?
Dennis
1
@Dennis Je veux dire profiter de la répétition O(1). Votre code doit être exécuté en temps constant, s'il exploite vraiment la répétition.
Magic Octopus Urn
1
@Dennis techniquement% 24 sur l'entrée rendrait la limite supérieure à 27 itérations; alors que ce n'est pas intéressant, ça compte vraiment.
Magic Octopus Urn

Réponses:

7

Oasis , 5 octets

Code:

ScS+T

Essayez-le en ligne!

Version étendue:

ScS+10

Explication:

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
Adnan
la source
Oh mec ... je vais aussi commencer à apprendre Oasis.
Urne de poulpe magique le
28

JavaScript (ES6), 45 octets

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>

xet yne peuvent pas être les deux 9, car cela nécessiterait que le nombre précédent soit 0, donc leur somme numérique ne peut pas dépasser 17. Cela signifie que la racine numérique pour les nombres supérieurs à 9est la même que le reste modulo 9.

Neil
la source
6
Ceci, cela obtiendra également une prime équivalente au leader de répétition ... Ceci est un aperçu mathématique impressionnant.
Magic Octopus Urn
13

Python 2, 53 octets

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

Fonction récursive. Les cas de base n=0et n=1produisent ndes nombres plus grands calculent la valeur en appelant f(n-1)et en f(n-2)convertissant chacun en une chaîne, en concaténant les deux chaînes, en convertissant chaque caractère en un entier à l'aide de a mapavec la intfonction, puis en additionnant la liste résultante.


En utilisant les informations modulo-24, je peux actuellement obtenir une fonction non récursive non nommée de 56 octets:

lambda n:int(('011'+'2358dc7a89hhgfda56b8a9aa'*n)[n],18)
Jonathan Allan
la source
1
Oui! Tellement +1! Une réponse répétée :). J'ai ajouté une section bonus en votre honneur monsieur, vous êtes maintenant le leader d'un concours de primes de 100 points!
Magic Octopus Urn
11

JavaScript (ES6), 34 octets

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

Peut geler votre navigateur pour les entrées supérieures à 27 environ, mais cela fonctionne pour toutes les valeurs d'entrée. Cela peut être vérifié avec un simple cache:

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>

Comme indiqué dans la brillante réponse de Neil , la sortie ne peut jamais dépasser 17, de sorte que la somme numérique de toute sortie supérieure à 9 est égale à n%9. Cela fonctionne également avec des sorties inférieures à 9; nous pouvons aussi le faire fonctionner pour 9 en soustrayant 1 avec ~-avant le module, puis en rajoutant en 1 après.


Le mieux que je puisse faire avec le codage en dur est de 50 octets:

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

Gelée , 8 octets

;DFS
ç¡1

Essayez-le en ligne!

Comment ça marche

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

Solution alternative, 19 octets, temps constant

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

Essayez-le en ligne!

Comment ça marche

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.
Dennis
la source
1
+1 pour le chuzpe de «calculons simplement toute la section répétée en temps constant»: D
Felix Dombek
4

JavaScript (ES6), 52 46 45 octets

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

Usage

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

Sortie

13

Explication

Cette fonction vérifie si l'entrée est inférieure à 2, et si c'est le cas, elle renvoie l'entrée. Sinon, il crée un tableau de deux valeurs qui sont ajoutées l'une à l'autre sous forme de chaînes. Ces deux valeurs sont le résultat de l'appel de la fonction avecinput - 1 et input - 2.

le ... opérateur divise cette chaîne en un tableau de caractères, qui est ensuite converti à nouveau en chaîne, mais maintenant avec +es entre les valeurs. Cette chaîne est ensuite interprétée comme du code, de sorte que la somme est calculée, qui est ensuite renvoyée.

Il s'agit d'un algorithme à double récursivité, ce qui le rend assez inefficace. Il a besoin de 2 n-2appels de fonction pour l'entrée n. En tant que tel, voici une solution plus longue mais plus rapide. Merci à ETHproductions de l'avoir proposé.

f=($,p=1,c=0)=>$?f($-1,c,eval([...p+[c]].join`+`)):c
Luc
la source
Cela ne fonctionne pas pour les grandes valeurs comme 27, cela fige le navigateur (du moins c'est le cas pour moi)
Kritixi Lithos
Cela prend du temps, mais ça y arrivera ... finalement. Je vais y jeter un œil, mais les performances ne sont pas importantes pour ce défi ...
Luke
Eh bien, Jésus, ce n'est pas si intense en termes de calcul, votre programme devrait fonctionner pour des valeurs au-delà de 27 ... Mais si cela fonctionne pour 1-28, cela prouve techniquement qu'il fonctionne pour plus.
Magic Octopus Urn
1
@KritixiLithos C'est la récursivité qui est le problème. Le calcul du n ème nombre dans la séquence nécessite environ 2 ^ (n-2) appels de fonction, qui s'accumulent assez rapidement.
ETHproductions
Vous pouvez enregistrer un octet avec [..._(--$)+[_(--$)]]:-)
ETHproductions
4

05AB1E , 8 octets

XÎF‚¤sSO

Essayez-le en ligne!

Explication

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
Emigna
la source
3

CJam, 22 20 octets

Enregistré 2 octets grâce à Martin Ender

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

Algorithme récursif simple, rien d'extraordinaire. 0 indexé.

Essayez-le en ligne! ou tester pour 0-50 (fonctionne en fait assez rapidement).

Explication

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 octets

Solution utilisant la répétition. Algorithme similaire à la solution de Jonathan Allan.

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

Essayez-le en ligne!

Chat d'affaires
la source
3

Perl 6 ,  41  37 octets

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

Essayez-le

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

Essayez-le

{ # 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
}
Brad Gilbert b2gills
la source
1
Vous pouvez écrire le lambda intérieur comme *.comb.sum+*.comb.sum.
smls
2

MATL , 15 octets

lOi:"yyhFYAss]&

Essayez-le en ligne!

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
Luis Mendo
la source
2

C, 96 octets

ou 61 octets comptant les codes d'échappement comme 1 octet chacun

0 indexé. Semblable à certaines des autres réponses, j'indexe une table de recherche de valeurs mais je l'ai compressée en blocs de 4 octets. Je n'ai pas pris la peine d'étudier la version mod 24 parce que je ne pensais pas que c'était aussi intéressant puisque les autres l'ont déjà fait mais avouons-le, C ne va pas gagner de toute façon.

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

explication:

#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

Essayez-le en ligne!

Ahemone
la source
Je compte les codes d'échappement comme 1 octet chacun! Excellent travail
Albert Renshaw
2

Japt , 27 25 octets

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

Essayez-le en ligne!

Sauvegardé 2 octets grâce à ETHproductions.

À M
la source
Hé, merci d'utiliser Japt :-) Vous pouvez utiliser ´à la place de --sauver deux octets.
ETHproductions
2

Mathematica, 49 octets

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

Définition récursive simple. Obtient assez lent après un certain temps.

Mathematica, 79 71 octets

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

Codage en dur du modèle périodique. Rapide comme l'éclair et abusivement satisfaisant pour Mathematica :) Merci à JungHwan Min pour avoir économisé 8 octets!

Greg Martin
la source
Pour votre deuxième code LetterNumber@"JJBCEHMLGJHIQQPOMJEFKHJ"est 8 octets plus court que 43626804920391712116157158790~IntegerDigits~18.
JungHwan Min
tu as raison! Un de ces jours, je m'en souviendrai LetterNumber...
Greg Martin
1

Python 2 , 56 octets

Solution itérative simple.

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

Essayez-le en ligne!

L'utilisation (a%9or a)+(b%9or b)s'est avérée être plus courte que sum(map(int(`a`+`b`)))!

FlipTack
la source
Je pense que vous voulez dire sum(map(int,a+b))(ne peut pas comprendre comment utiliser `dans les commentaires)
1

PowerShell , 79 octets

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

Essayez-le en ligne!

Longue solution itérative ennuyeuse qui effectue des calculs de somme de chiffres directs à chaque forboucle. À la fin de la boucle, le nombre que nous voulons est $b, donc il reste sur le pipeline et la sortie est implicite. Notez que si l'entrée est 0, alors la boucle n'entrera pas car le conditionnel est faux, donc ça $breste 0.

AdmBorkBork
la source
1

Lot, 85 octets

@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%

Je me demandais comment j'allais porter ma réponse JavaScript en batch mais l'indice était dans la solution Python de @ Dennis.

Neil
la source
1

Pyth, 20 octets

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

Un programme qui prend en entrée un entier indexé zéro et imprime le résultat.

Suite de tests (première partie pour le formatage)

Comment ça marche

[Explication à venir plus tard]

TheBikingViking
la source
1

Rubis, 58 octets

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

La solution simple en dur.

GB
la source
1

empilé , 40 octets

{!2:>[:$digitsflatmap sum\last\,]n*last}

Cette lambda est équivalente à la lambda suivante:

{n : 2:>[:$digitsflatmap sum\last\,]n*last}

Essayez-le en ligne!

Conor O'Brien
la source
1

Octave, 148 octets

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
Pitagora
la source
Bienvenue à ppcg! Bon premier post!
Rɪᴋᴇʀ
1

Haskell, 151 octets

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)

Appelez la fonction avec f 123456789012345678901234567890123456789012345678 , par exemple.

Le code fonctionne également avec de très gros indices. En raison de la fonctionnalité modulo 24 implémentée, elle est très rapide.

Le code non compressé:

-- 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
Gerhard
la source
0

R, 90 octets

Une solution horriblement longue, mais elle est meilleure que la 108 que j'avais à l'origine. Je soupçonne qu'il existe une bien meilleure façon de procéder, mais je ne peux pas le voir pour le moment.

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

Il s'agit d'une fonction sans nom qui utilise gsubet scan(t=pour diviser les chiffres du vecteur en chiffres. La somme de ceux-ci est ajoutée au vecteur pendant que le premier élément est supprimé. repeatest utilisé pour parcourir les ntemps de séquence et le résultat est le premier élément du vecteur.

MickyT
la source
0

PHP, 80 octets

for($r=[0,1];$i<$argn;)$r[]=array_sum(str_split($r[$i].$r[++$i]));echo$r[$argn];

Version en ligne

Jörg Hülsermann
la source
0

Mathematica, 67 octets

r=IntegerDigits;f@0=0;f@1=1;f[x_]:=f@x=Tr@r@f[x-1]+Tr@r@f[x-2];f@#&
J42161217
la source