Somma i miei divisori fibonaccificati!


14

La famosa sequenza di Fibonacci è F(0) = 0; F(1) = 1; F(N+1) = F(N) + F(N-1)(per questa sfida iniziamo con 0).

La tua sfida: dato n , genera la somma di tutti i numeri d Fibonacci per tutti i divisori d del numero n Fibonacci. Se preferisci una notazione più formale,

La somma

Input : un numero intero positivo n

Uscita : la somma

Ad esempio, considera n=4. F(4) = 3I divisori di 3 sono 1 e 3, quindi l'output dovrebbe essere F(1) + F(3) = 1 + 2 = 3.

Per n=6, F(6) = 8e i divisori di 8 sono 1, 2, 4, 8, quindi l'output è F(1) + F(2) + F(4) + F(8) = 1 + 1 + 3 + 21 = 26.

Casi test:

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

Questo è , la risposta più breve in byte vince. Si applicano scappatoie standard .

Risposte:


2

In realtà , 5 byte

F÷♂FΣ

Provalo online!

Come funziona

       (implicit) Read n from STDIN.
F      Compute F(n).
 ÷     Get F(n)'s divisors.
  ♂F   Map F over the divisors.
    Σ  Take the sum.

Il nome della lingua lo fa sembrare passivo aggressivo, è quello che intendi?
Rohan Jhunjhunwala,

1
Ne dubito. La prima versione della lingua è stata chiamata Seriamente a causa di questo commento . Per la seconda versione, l'autore ha scelto di continuare ad usare aggettivi.
Dennis,

6

Gelatina , 7 byte

ÆḞÆDÆḞS

Provalo online!

Spiegazione:

ÆḞÆDÆḞS Main link (Arguments: z)
ÆḞ      zth Fibonacci number's
  ÆD                           divisors'
    ÆḞ                                   Fibonacci numbers'
      S                                                     sum

Assolutamente scandaloso! Non conosco nessuna di queste lingue esotiche, ma mi sembra soprannaturale come si possa scrivere un intero algoritmo con pochi caratteri.
Bogdan Alexandru,

@BogdanAlexandru Puoi vedere che la maggior parte dei builtin usati qui consumano 2 byte, dato che non si adattano a 1 byte. Vedi la risposta reale di Dennis per ancora meno caratteri. Inoltre, Jelly è un "linguaggio del golf", un linguaggio creato appositamente per il code-golf , ed è uno dei più efficienti qui (anche se non esiste un linguaggio "più efficiente").
Erik the Outgolfer,

Stai dicendo che queste lingue non sono utilizzate nella pratica e sono pensate solo per le sfide?
Bogdan Alexandru,


4

Mathematica semplificata , 14 byte

Fi@#~Div9`~Fi&

Oh bene, questo è finito per essere identico alla soluzione di @ MartinEnder ...


Bene ... Utilizzando una versione più breve della stessa lingua ... Immagino che funzioni.
Neil A.

Non ci sono nomi di funzioni a lettera singola in Mathematica, giusto? Non potresti abbinare tutte e due le stringhe di caratteri formate da una lettera maiuscola iniziale più un singolo byte? In tal caso, avresti 26 * 256 = 6656 nomi di funzioni a 2 byte semplificati, sufficienti per i 6356 11.1.1 nomi con 300 da risparmiare.
Jonathan Allan,

@JonathanAllan Buona idea. (ma ci sono funzioni con un solo nome, come N)
JungHwan Min


2

05AB1E , 11 byte

!ÅFDI<èÑ<èO

Provalo online!

Spiegazione

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


2

Alice , 38 36 byte

Grazie a Leo per aver salvato 2 byte.

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

Provalo online!

Quasi certamente non ottimale. Il flusso di controllo è abbastanza elaborato e mentre sono abbastanza contento di quanti byte sono stati salvati rispetto alle versioni precedenti, ho la sensazione di complicare troppo le cose che potrebbero esserci soluzione più e più breve.

Spiegazione

Innanzitutto, devo elaborare un po 'lo stack degli indirizzi di ritorno (RAS) di Alice. Come molti altri fungeoid, Alice ha il comando di saltare nel codice. Tuttavia, ha anche i comandi per tornare da dove vieni, il che ti consente di implementare le subroutine abbastanza comodamente. Naturalmente, trattandosi di un linguaggio 2D, le subroutine esistono davvero solo per convenzione. Non c'è nulla che ti impedisca di entrare o uscire da una subroutine con mezzi diversi da un comando di ritorno (o in qualsiasi punto della subroutine) e, a seconda di come usi il RAS, potrebbe non esserci comunque una gerarchia pulita di salto / ritorno.

In generale, questo viene implementato facendo in modo che il comando jump jspinga l'attuale indirizzo IP sul RAS prima di saltare. Il comando return kquindi visualizza un indirizzo del RAS e salta lì. Se il RAS è vuoto, knon fa nulla.

Esistono anche altri modi per manipolare il RAS. Due di questi sono rilevanti per questo programma:

  • winvia l'attuale indirizzo IP al RAS senza saltare da nessuna parte. Se ripeti questo comando puoi scrivere semplici loop abbastanza comodamente come &w...k, cosa che ho già fatto nelle risposte precedenti.
  • Jè come jma non ricorda l'attuale indirizzo IP sul RAS.

È anche importante notare che il RAS non memorizza informazioni sulla direzione dell'IP. Quindi il ritorno a un indirizzo con kmanterrà sempre la direzione IP corrente (e quindi anche se siamo in modalità Cardinale o Ordinale) indipendentemente da come abbiamo attraversato jo wche ha spinto l'indirizzo IP in primo luogo.

Detto questo, iniziamo esaminando la subroutine nel programma sopra:

01dt,t&w.2,+k

Questa subroutine tira in alto l'elemento inferiore della pila, n , quindi calcola i numeri di Fibonacci F (n) e F (n + 1) (lasciandoli in cima alla pila). Non abbiamo mai bisogno di F (n + 1) , ma verrà scartato al di fuori della subroutine, a causa del modo in cui i &w...kloop interagiscono con il RAS (che tipo di richiede che questi loop siano alla fine di una subroutine). Il motivo per cui stiamo prendendo gli elementi dal basso invece che dall'alto è che questo ci consente di trattare lo stack più come una coda, il che significa che possiamo calcolare tutti i numeri di Fibonacci in una volta sola senza doverli memorizzare altrove.

Ecco come funziona questa subroutine:

                                                          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 fine del ciclo è un po 'complicata. Finché c'è una copia dell'indirizzo "w" nello stack, questo avvia la successiva iterazione. Una volta esauriti, il risultato dipende da come è stata invocata la subroutine. Se la subroutine è stata chiamata con 'j', l'ultima 'k' vi ritorna, quindi la fine del ciclo raddoppia come ritorno della subroutine. Se la subroutine è stata chiamata con 'J', e c'è ancora un indirizzo precedente nello stack, saltiamo lì. Ciò significa che se la subroutine è stata chiamata in un loop esterno stesso, questa 'k' ritorna all'inizio di quel loop esterno . Se la subroutine è stata chiamata con 'J' ma ora il RAS è vuoto, allora 'k' non fa nulla e l'IP semplicemente continua a muoversi dopo il loop. Useremo tutti e tre questi casi nel programma.

Infine, al programma stesso.

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

Queste sono solo due brevi escursioni in modalità Ordinale per leggere e stampare numeri decimali.

Dopo il i, c'è un wche ricorda la posizione corrente prima di passare alla subroutine, a causa del secondo /. Questa prima invocazione della subroutine viene calcolata F(n)e F(n+1)sull'input n. Successivamente torniamo indietro qui, ma ora ci stiamo spostando verso est, quindi il resto degli operatori del programma in modalità Cardinale. Il programma principale è simile al seguente:

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

Ecco 31Jun'altra chiamata alla subroutine e quindi calcola un numero di 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.

1

Assioma, 68 byte

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

qualche 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



1

R, 77 byte

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)

Fa uso della libreria 'gmp'. Questo ha una funzione integrata di Fibonacci e offre la possibilità di fare grandi numeri. Ha causato alcuni problemi con seqs e applicazioni, anche se è ancora più piccolo della creazione della mia funzione Fibonacci.

Spiegazione

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

Test

> 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

Senza usare gmp

81 byte , Funzione ricorsiva che è irrimediabilmente lenta quando vengono scelti numeri grandi (9+)

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

88 byte , la formula di Binet che funzionerà ragionevolmente bene con numeri più grandi, ma raggiunge comunque il limite intero abbastanza rapidamente

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

0

Perl 6 , 49 byte

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

0

CJam , 26 byte

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

Provalo online!

Sono sicuro che si può fare di meglio. Spiegazione:

L'idea è di avere una matrice di numeri di Fibonacci e di puntarla sul prodotto con una matrice con 1 e 0 se quel numero è o non è un divisore dell'input.

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

0

JavaScript (ES6), 76 65 byte

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)

Casi test


0

JavaScript (ES6), 105 104 103 101 97 byte

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

Provalo

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>


Io credo che si può cambiare (z=g(i)/y)>~~za (z=g(i)/y)%1, se si sta solo controllando che zè un intero.
ETHproductions

@ETHproductions, che crea un overflow che può essere risolto cambiando g(z)in g(z|0)ma ci riporta allo stesso numero di byte.
Shaggy,

0

Q, 75 byte

{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}


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.