Hitung pembagi yang disetujui Fibon saya!


14

Urutan Fibonacci yang terkenal adalah F(0) = 0; F(1) = 1; F(N+1) = F(N) + F(N-1)(untuk tantangan ini kita mulai dengan 0).

Tantangan Anda: Diberikan n , hasilkan jumlah semua angka Fibonacci d untuk semua pembagi d dari angka Fibonacci n . Jika Anda lebih suka notasi formal,

Jumlah

Input : bilangan bulat positif n

Output : jumlahnya

Sebagai contoh, pertimbangkan n=4. F(4) = 3Pembagi 3 adalah 1 dan 3, jadi hasilnya seharusnya F(1) + F(3) = 1 + 2 = 3.

Untuk n=6,, F(6) = 8dan pembagi 8 adalah 1, 2, 4, 8, jadi outputnya adalah F(1) + F(2) + F(4) + F(8) = 1 + 1 + 3 + 21 = 26.

Kasus uji:

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

Ini adalah , jawaban terpendek dalam byte yang menang. Celah standar berlaku.

Jawaban:


2

Sebenarnya , 5 byte

F÷♂FΣ

Cobalah online!

Bagaimana itu bekerja

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

Nama bahasanya membuatnya tampak pasif agresif, apakah itu dimaksudkan?
Rohan Jhunjhunwala

1
Aku meragukan itu. Versi pertama bahasa itu disebut Serius karena komentar ini . Untuk versi kedua, penulis memilih untuk tetap menggunakan kata sifat.
Dennis

6

Jelly , 7 byte

ÆḞÆDÆḞS

Cobalah online!

Penjelasan:

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

Benar-benar keterlaluan! Saya tidak tahu bahasa-bahasa eksotis ini, tetapi tampaknya supernatural bagi saya bagaimana Anda dapat menulis keseluruhan algoritma dengan beberapa karakter.
Bogdan Alexandru

@BogdanAlexandru Anda dapat melihat bahwa sebagian besar builtin yang digunakan di sini masing-masing mengonsumsi 2 byte, karena tidak muat dalam 1 byte. Lihat jawaban Dennis's Actually untuk lebih sedikit karakter. Selain itu, Jelly adalah "bahasa golf", bahasa yang dibuat khusus untuk kode-golf , dan ini adalah salah satu yang paling efisien di sini (walaupun tidak ada satu bahasa "paling efisien").
Erik the Outgolfer

Apakah Anda mengatakan bahwa bahasa-bahasa ini tidak digunakan dalam praktik dan mereka hanya dimaksudkan untuk tantangan?
Bogdan Alexandru


4

Mathematica Disederhanakan , 14 byte

Fi@#~Div9`~Fi&

Oh well, ini akhirnya identik dengan solusi @ MartinEnder ...


Ya ... Menggunakan versi yang lebih pendek dari bahasa yang sama ... Saya kira itu berhasil.
Neil A.

Tidak ada nama fungsi huruf tunggal di Mathematica, kan? Tidak bisakah Anda mencocokkan kedua string karakter yang dibentuk dari huruf besar pertama ditambah satu byte? Jika demikian, Anda akan memiliki 26 * 256 = 6656 nama fungsi 2-byte yang disederhanakan, cukup untuk 6356 11.1.1 nama dengan 300 untuk cadangan.
Jonathan Allan

@ JonathanAllan Ide bagus. (Tapi ada fungsi nama tunggal, seperti N)
JungHwan Min


2

05AB1E , 11 byte

!ÅFDI<èÑ<èO

Cobalah online!

Penjelasan

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

Haskell, 54 byte

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

Contoh penggunaan: g 6-> 26. Cobalah online!


2

Alice , 38 36 byte

Terima kasih kepada Leo karena telah menghemat 2 byte.

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

Cobalah online!

Hampir dipastikan tidak optimal. Alur kontrolnya cukup rumit dan walaupun saya cukup senang dengan berapa byte yang disimpan di versi sebelumnya, saya merasa bahwa saya terlalu rumit, mungkin ada yang lebih sederhana dan lebih sederhana. lebih pendek.

Penjelasan

Pertama, saya perlu menguraikan sedikit tentang tumpukan alamat pengirim Alice (RAS). Seperti banyak fungeoids lainnya, Alice memiliki perintah untuk melompat-lompat dalam kode. Namun, ia juga memiliki perintah untuk kembali ke tempat asal Anda, yang memungkinkan Anda menerapkan subrutin dengan cukup mudah. Tentu saja, ini menjadi bahasa 2D, subrutin benar-benar hanya ada dengan konvensi. Tidak ada yang menghentikan Anda memasuki atau meninggalkan subrutin melalui cara lain selain perintah kembali (atau pada titik mana pun dalam subrutin), dan tergantung pada bagaimana Anda menggunakan RAS, bagaimanapun, mungkin tidak ada hierarki lompat / kembali yang bersih.

Secara umum, ini diimplementasikan dengan memiliki perintah lompat jmendorong alamat IP saat ini ke RAS sebelum melompat. Perintah kembali kkemudian muncul alamat RAS dan melompat ke sana. Jika RAS kosong, ktidak melakukan apa-apa.

Ada juga cara lain untuk memanipulasi RAS. Dua di antaranya relevan untuk program ini:

  • wmendorong alamat IP saat ini ke RAS tanpa melompat ke mana pun. Jika Anda mengulangi perintah ini, Anda dapat menulis loop sederhana dengan nyaman&w...k , yang sudah saya lakukan di jawaban sebelumnya.
  • Jseperti jtetapi tidak ingat alamat IP saat ini di RAS.

Penting juga untuk dicatat bahwa RAS tidak menyimpan informasi tentang arah IP. Jadi kembali ke alamat dengan kakan selalu menjaga arah IP saat ini (dan karena itu juga apakah kita dalam mode Kardinal atau Ordinal) terlepas dari bagaimana kita melewati jatauw yang mendorong alamat IP di tempat pertama.

Dengan itu, mari kita mulai dengan melihat subrutin dalam program di atas:

01dt,t&w.2,+k

Subrutin ini menarik elemen bawah tumpukan, n , ke atas dan kemudian menghitung angka Fibonacci F (n) dan F (n +1) (meninggalkannya di atas tumpukan). Kita tidak pernah membutuhkan F (n +1) , tetapi akan dibuang di luar subrutin, karena bagaimana &w...kloop berinteraksi dengan RAS (yang memerlukan loop ini pada akhir subrutin). Alasan kami mengambil elemen dari bawah alih-alih dari atas adalah bahwa ini memungkinkan kami memperlakukan tumpukan lebih seperti antrian, yang berarti kami dapat menghitung semua angka Fibonacci dalam sekali jalan tanpa harus menyimpannya di tempat lain.

Inilah cara kerja subrutin ini:

                                                          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.

Akhir dari loop agak rumit. Selama ada salinan alamat 'w' di stack, ini akan memulai iterasi berikutnya. Setelah habis, hasilnya tergantung pada bagaimana subrutin itu dipanggil. Jika subrutin dipanggil dengan 'j', 'k' terakhir kembali ke sana, sehingga ujung loop berlipat ganda sebagai kembalinya subrutin. Jika subrutin dipanggil dengan 'J', dan masih ada alamat dari sebelumnya di stack, kita lompat ke sana. Ini berarti jika subrutin dipanggil dalam loop luar itu sendiri, 'k' ini kembali ke awal loop luar itu . Jika subrutin dipanggil dengan 'J' tetapi RAS kosong sekarang, maka 'k' ini tidak melakukan apa-apa dan IP hanya terus bergerak setelah loop. Kami akan menggunakan ketiga kasus ini dalam program.

Akhirnya, ke program itu sendiri.

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

Ini hanya dua kunjungan singkat ke mode Ordinal untuk membaca dan mencetak bilangan bulat desimal.

Setelah itu i, ada wyang mengingat posisi saat ini sebelum melewati subrutin, karena yang kedua /. Doa pertama dari subrutin ini menghitung F(n)dan memberi F(n+1)masukan n. Setelah itu kami melompat kembali ke sini, tapi kami bergerak ke timur sekarang, jadi sisa dari operator program dalam mode Kardinal. Program utama terlihat seperti ini:

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

Di sini, 31Jada panggilan lain ke subrutin dan karenanya menghitung angka 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

Aksioma, 68 byte

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

beberapa tes

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

Manfaatkan perpustakaan 'gmp'. Ini memiliki fungsi Fibonacci bawaan dan menyediakan kemampuan untuk melakukan sejumlah besar. Ini menyebabkan beberapa masalah dengan seqs dan berlaku, meskipun masih lebih kecil daripada membuat fungsi Fibonacci saya sendiri.

Penjelasan

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

Uji

> 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

Tanpa menggunakan gmp

81 byte , Fungsi rekursif yang lambat sekali ketika angka (9+) besar dipilih

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 , formula Binet yang akan bekerja cukup baik dengan angka yang lebih besar, tetapi masih mencapai batas integer dengan cukup cepat

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


0

CJam , 26 byte

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

Cobalah online!

Saya yakin itu bisa dilakukan dengan lebih baik. Penjelasan:

Idenya adalah untuk memiliki array angka Fibonacci dan dot produkkan dengan array dengan 1s dan 0s jika angka itu adalah atau bukan merupakan pembagi 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)

Uji kasus


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

Cobalah

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>


Saya pikir Anda dapat mengubah (z=g(i)/y)>~~zke (z=g(i)/y)%1, jika Anda hanya memeriksa bahwa zadalah bilangan bulat.
Produk ETH

@ETHproductions, yang menciptakan sebuah meluap yang dapat diselesaikan dengan mengubah g(z)ke g(z|0)tapi membawa kita kembali ke hitungan byte yang sama.
Shaggy



Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.