Additionnez mes diviseurs Fibonaccified!

14

La célèbre séquence de Fibonacci est F(0) = 0; F(1) = 1; F(N+1) = F(N) + F(N-1)(pour ce défi nous commençons par 0).

Votre défi: Étant donné n , sortez la somme de tous les d ième nombres de Fibonacci pour tous les diviseurs d du n ième nombre de Fibonacci. Si vous préférez une notation plus formelle,

La somme

Entrée : un entier positif n

Sortie : la somme

Par exemple, réfléchissez n=4. F(4) = 3Les diviseurs de 3 sont 1 et 3, donc la sortie devrait être F(1) + F(3) = 1 + 2 = 3.

Pour n=6, F(6) = 8et les diviseurs de 8 sont 1, 2, 4, 8, de sorte que la sortie est F(1) + F(2) + F(4) + F(8) = 1 + 1 + 3 + 21 = 26.

Cas de test:

1 => 1
2 => 1
3 => 2
4 => 3
5 => 6
6 => 26

C'est le , la réponse la plus courte en octets. Des échappatoires standard s'appliquent.

Neil A.
la source

Réponses:

2

En fait , 5 octets

F÷♂FΣ

Essayez-le en ligne!

Comment ça fonctionne

       (implicit) Read n from STDIN.
F      Compute F(n).
 ÷     Get F(n)'s divisors.
  ♂F   Map F over the divisors.
    Σ  Take the sum.
Dennis
la source
Le nom de la langue la fait paraître passive agressive, est-ce voulu?
Rohan Jhunjhunwala
1
J'en doute. La première version de la langue a été appelée Sérieusement à cause de ce commentaire . Pour la deuxième version, l'auteur a choisi de continuer à utiliser des adjectifs.
Dennis
6

Gelée , 7 octets

ÆḞÆDÆḞS

Essayez-le en ligne!

Explication:

ÆḞÆDÆḞS Main link (Arguments: z)
ÆḞ      zth Fibonacci number's
  ÆD                           divisors'
    ÆḞ                                   Fibonacci numbers'
      S                                                     sum
Erik le Outgolfer
la source
Absolument scandaleux! Je ne connais aucune de ces langues exotiques, mais il me semble surnaturel comment vous pouvez écrire un algorithme entier avec quelques caractères.
Bogdan Alexandru
@BogdanAlexandru Vous pouvez voir que la plupart des modules internes utilisés ici consomment chacun 2 octets, car ils ne tiennent pas dans 1 octet. Voir la réponse Actuelle de Dennis pour encore moins de caractères. De plus, Jelly est un "langage de golf", un langage spécialement conçu pour le code-golf , et c'est l'un des plus efficaces ici (bien qu'il n'y ait pas de langue "la plus efficace").
Erik the Outgolfer
Êtes-vous en train de dire que ces langues ne sont pas utilisées dans la pratique et qu'elles ne sont destinées qu'aux défis?
Bogdan Alexandru
4

Mathematica, 29 octets

f=Fibonacci;f@#~DivisorSum~f&
Martin Ender
la source
4

Mathematica simplifié , 14 octets

Fi@#~Div9`~Fi&

Eh bien, cela a fini par être identique à la solution de @ MartinEnder ...

JungHwan Min
la source
Eh bien ... Utiliser une version plus courte de la même langue ... Je suppose que ça marche.
Neil A.
Il n'y a pas de nom de fonction à une seule lettre dans Mathematica, non? Ne pourriez-vous pas faire correspondre les deux chaînes de caractères formées à partir d'une lettre majuscule en tête et d'un seul octet? Si c'est le cas, vous auriez 26 * 256 = 6656 noms de fonction simplifiés à 2 octets, assez pour les 6356 11.1.1 noms avec 300 à épargner.
Jonathan Allan
@JonathanAllan Bonne idée. (mais il y a des fonctions de nom unique, comme N)
JungHwan Min
2

05AB1E , 11 octets

!ÅFDI<èÑ<èO

Essayez-le en ligne!

Explication

!            # factorial of input
 ÅF          # get the list of fibonacci numbers (starting at 1)
             # smaller than or equal to this
   D         # duplicate list of fibonacci number
    I<è      # get the element at index (input-1)
       Ñ     # get the list of its divisors
        <    # decrement each
         è   # get the fibonacci numbers at those indices
          O  # sum
Emigna
la source
2

Haskell, 54 octets

f=0:scanl(+)1f
g x=sum[f!!d|d<-[1..f!!x],mod(f!!x)d<1]

Exemple d'utilisation: g 6-> 26. Essayez-le en ligne!

nimi
la source
2

Alice , 38 36 octets

Merci à Leo d'avoir économisé 2 octets.

/ow;B1dt&w;31J
\i@/01dt,t&w.2,+k;d&+

Essayez-le en ligne!

Certainement pas optimal. Le flux de contrôle est assez élaboré et même si je suis assez satisfait du nombre d'octets enregistrés par rapport aux versions précédentes, j'ai le sentiment de trop compliquer les choses pour qu'il y ait une solution plus simple et plus courte.

Explication

Tout d'abord, je dois élaborer un peu sur la pile d'adresses de retour d'Alice (RAS). Comme beaucoup d'autres fungeoids, Alice a une commande pour sauter dans le code. Cependant, il a également des commandes pour retourner d'où vous venez, ce qui vous permet d'implémenter les sous-programmes très facilement. Bien sûr, étant un langage 2D, les sous-programmes n'existent vraiment que par convention. Rien ne vous empêche d'entrer ou de quitter un sous-programme par d'autres moyens qu'une commande de retour (ou à tout moment dans le sous-programme), et selon la façon dont vous utilisez le RAS, il pourrait ne pas y avoir de toute façon une hiérarchie de saut / retour propre.

En général, cela est implémenté en faisant en sorte que la commande jump jenvoie l'adresse IP actuelle au RAS avant de sauter. La commande de retour affiche kensuite une adresse du RAS et y saute. Si le RAS est vide, kne fait rien du tout.

Il existe également d'autres façons de manipuler le RAS. Deux d'entre elles sont pertinentes pour ce programme:

  • wpousse l'adresse IP actuelle vers le RAS sans sauter n'importe où. Si vous répétez cette commande, vous pouvez écrire des boucles simples assez facilement, comme &w...kje l'ai déjà fait dans les réponses précédentes.
  • Jest comme jmais ne se souvient pas de l'adresse IP actuelle sur le RAS.

Il est également important de noter que le RAS ne stocke aucune information sur la direction de l'IP. Donc, revenir à une adresse avec kpréservera toujours la direction IP actuelle (et donc aussi si nous sommes en mode Cardinal ou Ordinal) quelle que soit la façon dont nous avons traversé le jou wqui a poussé l'adresse IP en premier lieu.

Cela étant dit, commençons par examiner le sous-programme du programme ci-dessus:

01dt,t&w.2,+k

Ce sous-programme tire l'élément inférieur de la pile, n , vers le haut, puis calcule les nombres de Fibonacci F (n) et F (n + 1) (en les laissant en haut de la pile). Nous n'avons jamais besoin de F (n + 1) , mais il sera rejeté en dehors du sous-programme, en raison de la façon dont les &w...kboucles interagissent avec le RAS (ce qui oblige ces boucles à se trouver à la fin d'un sous-programme). La raison pour laquelle nous prenons des éléments du bas au lieu du haut est que cela nous permet de traiter la pile plus comme une file d'attente, ce qui signifie que nous pouvons calculer tous les numéros de Fibonacci en une seule fois sans avoir à les stocker ailleurs.

Voici comment fonctionne ce sous-programme:

                                                          Stack
01    Push 0 and 1, to initialise Fibonacci sequence.     [n ... 0 1]
dt,   Pull bottom element n to top.                       [... 0 1 n]
t&w   Run this loop n times...                            [... F(i-2) F(i-1)]

  .     Duplicate F(i-1).                                 [... F(i-2) F(i-1) F(i-1)]
  2,    Pull up F(i-2).                                   [... F(i-1) F(i-1) F(i-2)]
  +     Add them together to get F(i).                    [... F(i-1) F(i)]

k     End of loop.

La fin de la boucle est un peu délicate. Tant qu'il y a une copie de l'adresse «w» sur la pile, cela démarre l'itération suivante. Une fois ceux-ci épuisés, le résultat dépend de la façon dont le sous-programme a été invoqué. Si le sous-programme a été appelé avec 'j', le dernier 'k' y revient, donc la fin de la boucle se double du retour du sous-programme. Si le sous-programme a été appelé avec 'J', et qu'il y a toujours une adresse antérieure à la pile, nous sautons là. Cela signifie que si le sous-programme a été appelé dans une boucle externe elle-même, ce «k» revient au début de cette boucle externe . Si le sous-programme a été appelé avec «J» mais que le RAS est vide maintenant, alors ce «k» ne fait rien et l'IP continue simplement de se déplacer après la boucle. Nous utiliserons ces trois cas dans le programme.

Enfin, passons au programme lui-même.

/o....
\i@...

Ce ne sont que deux excursions rapides en mode Ordinal pour lire et imprimer des entiers décimaux.

Après le i, il y en a un wqui se souvient de la position actuelle avant de passer dans le sous-programme, en raison du second /. Cette première invocation du sous-programme calcule F(n)et F(n+1)sur l'entrée n. Ensuite, nous sautons ici, mais nous nous déplaçons vers l'est maintenant, donc le reste des opérateurs de programme en mode Cardinal. Le programme principal ressemble à ceci:

;B1dt&w;31J;d&+
        ^^^

Ici, 31Jc'est un autre appel à la sous-routine et calcule donc un nombre de Fibonacci.

                                              Stack
                                              [F(n) F(n+1)]
;     Discard F(n+1).                         [F(n)]
B     Push all divisors of F(n).              [d_1 d_2 ... d_p]
1     Push 1. This value is arbitrary.        [d_1 d_2 ... d_p 1]
      The reason we need it is due to
      the fact that we don't want to run
      any code after our nested loops, so
      the upcoming outer loop over all
      divisors will *start* with ';' to
      discard F(d+1). But on the first
      iteration we haven't called the
      subroutine yet, so we need some 
      dummy value we can discard.
dt&w  Run this loop once for each element     [d_1 d_2 ... d_p 1]
      in the stack. Note that this is once    OR
      more than we have divisors. But since   [d_i d_(i+1) ... F(d_(i-1)) F(d_(i-1)+1)] 
      we're treating the stack as a queue,
      the last iteration will process the 
      first divisor for a second time. 
      Luckily, the first divisor is always 
      1 and F(1) = 1, so it doesn't matter 
      how often we process this one.

  ;     Discard the dummy value on the        [d_1 d_2 ... d_p]
        first iteration and F(d+1) of         OR
        the previous divisor on subsequent    [d_i d_(i+1) ... F(d_(i-1))]
        iterations.
  31J   Call the subroutine without pushing   [d_(i+1) ... F(d_i) F(d_i+1)]
        the current address on the RAS.
        Thereby, this doubles as our outer
        loop end. As long as there's an
        address left from the 'w', the end
        of the subroutine will jump there
        and start another iteration for the
        next divisor. Once that's done, the
        'k' at the end of the subroutine will
        simply do nothing and we'll continue
        after it.

;     Discard the final F(d_i+1).
d&+   Get the stack depth D and add the top   [final result]
      D+2 values. Of course that's two more
      than we have divisors, but the stack is
      implicitly padded with zeros, so that
      doesn't matter.
Martin Ender
la source
1

Axiome, 68 octets

g==>fibonacci;f(x:NNI):NNI==(x<3=>1;reduce(+,map(g,divisors(g(x)))))

un test

(46) -> [[i,f(i)] for i in [0,1,2,3,4,5,6,10,15] ]
   (46)
   [[0,1], [1,1], [2,1], [3,2], [4,3], [5,6], [6,26], [10,139583862540],
     [15,
      135823697912782666169062844948067355657769395021071830756126284114988028_
       12823029319917411196081011510136735503204397274473084444
     ]
   ]
                                       Type: List List NonNegativeInteger
RosLuP
la source
1

R, 77 octets

F=gmp::fibnum;N=F(scan());i=n=N-N;while(i<N)if(N%%(i=i+1)<1)n=n+F(i);print(n)

Utilise la bibliothèque 'gmp'. Cela a une fonction Fibonacci intégrée et offre la possibilité de faire de grands nombres. Cela a causé quelques problèmes avec les séquences et les applications, bien qu'il soit encore plus petit que la création de ma propre fonction Fibonacci.

Explication

F=gmp::fibnum;               # Set F as fibnum function
N=F(scan());                 # get input and set N to the fibonacci number of that index
i=n=N-N;                     # set i and n to 0 with data type bigz
while(i<N)                   # loop while i < N
   if(N%%(i=i+1)<1)          # if incremented i is divisor of N 
       n=n+F(i);             # add F(i) to rolling sum
print(n)                     # output final result

Tester

> F=gmp::fibnum;N=F(scan());i=n=N-N;while(i<N)if(N%%(i=i+1)<1)n=n+F(i);print(n)
1: 6
2: 
Read 1 item
Big Integer ('bigz') :
[1] 26
> F=gmp::fibnum;N=F(scan());i=n=N-N;while(i<N)if(N%%(i=i+1)<1)n=n+F(i);print(n)
1: 10
2: 
Read 1 item
Big Integer ('bigz') :
[1] 139583862540
> F=gmp::fibnum;N=F(scan());i=n=N-N;while(i<N)if(N%%(i=i+1)<1)n=n+F(i);print(n)
1: 15
2: 
Read 1 item
Big Integer ('bigz') :
[1] 13582369791278266616906284494806735565776939502107183075612628411498802812823029319917411196081011510136735503204397274473084444

Sans utiliser gmp

81 octets , fonction récursive désespérément lente lorsque de grands nombres (9+) sont sélectionnés

F=function(n)`if`(n<2,n,F(n-1)+F(n-2));sum(sapply(which((N=F(scan()))%%1:N<1),F))

88 octets , la formule de Binet qui fonctionnera raisonnablement bien avec de plus grands nombres, mais atteint toujours la limite entière assez rapidement

F=function(n)round(((5+5^.5)/10)*((1+5^.5)/2)^(n-1));sum(F(which(F(N<-scan())%%1:N<1)))
MickyT
la source
0

Perl 6 , 49 octets

{my \f=0,1,*+*...*;sum f[grep f[$_]%%*,1..f[$_]]}
Sean
la source
0

CJam , 26 octets

qi_[XY@{_2$+}*]_@\f%:!.*:+

Essayez-le en ligne!

Je suis sûr que cela peut être mieux fait. Explication:

L'idée est d'avoir un tableau de nombres de Fibonacci et de le produire par points avec un tableau avec 1s et 0s si ce nombre est ou n'est pas un diviseur de l'entrée.

qi                                 Read the input (n)
   [XY        ]                    Array starting with [1,2,...]
  _   @{_2$+}*                     Append n times the sum of the previous two
               _                   Duplicate the array
                @\f%               Modulo each item with n (0 if divisor, a number otherwise)
                    :!             Logical NOT everything (1 if divisor, 0 otherwise) 
                      .*:+         Dot product those two arrays
FrodCube
la source
0

JavaScript (ES6), 76 65 octets

f=(n,i=k=(F=n=>n>1?F(n-1)+F(n-2):n)(n))=>i&&(k%i?0:F(i))+f(n,i-1)

Cas de test

Arnauld
la source
0

JavaScript (ES6), 105 104 103 101 97 bytes

i=>[...Array((g=(n,x=0,y=1)=>n--?g(n,y,x+y):x)(i)+1)].map((_,y)=>s+=g((z=g(i)/y)%1?0:z|0),s=0)&&s

Essayez-le

f=
i=>[...Array((g=(n,x=0,y=1)=>n--?g(n,y,x+y):x)(i)+1)].map((_,y)=>s+=g((z=g(i)/y)%1?0:z|0),s=0)&&s
o.innerText=f(j.value=4)
oninput=_=>o.innerText=f(+j.value)
<input id=j type=number><pre id=o>

Hirsute
la source
Je pense que vous pouvez passer (z=g(i)/y)>~~zà (z=g(i)/y)%1, si vous vérifiez simplement qu'il zs'agit d'un entier.
ETHproductions
@ETHproductions, qui crée un débordement qui peut être résolu en changeant g(z)en g(z|0)mais nous ramène au même nombre d'octets.
Shaggy
0

Q, 75 octets

{f:{$[x<2;x;.z.s[x-1]+.z.s[x-2]]};sum f each m where(~)b mod m:1+til b:f x}
Daniel Plainview
la source
0

C (gcc) , 93 90 80 octets

F(n){n=n<2?n:F(n-1)+F(n-2);}i,s;f(n){for(s=0,i=F(n);i;i--)s+=F(n)%i?0:F(i);n=s;}

Essayez-le en ligne!

cleblanc
la source