Fibonaktif bölücülerimi topla!


14

Ünlü Fibonacci dizisi F(0) = 0; F(1) = 1; F(N+1) = F(N) + F(N-1)(bu meydan okuma için 0 ile başlıyoruz).

Buradaki zorluk: Verilen n , çıkış tüm toplamı d tüm bölenler için Fibonacci sayıları inci d ait n Fibonacci sayısının inci. Daha resmi gösterimi tercih ederseniz,

Toplam

Girdi : pozitif bir tamsayı n

Çıktı : toplam

Örneğin, düşünün n=4. F(4) = 33'ün bölenleri 1 ve 3'tür, bu yüzden çıktı olmalıdır F(1) + F(3) = 1 + 2 = 3.

İçin n=6, F(6) = 8ve 8 bölenler çıkışı olan 1, 2, 4, 8, çok vardır F(1) + F(2) + F(4) + F(8) = 1 + 1 + 3 + 21 = 26.

Test Durumları:

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

Bu , bayt kazanır en kısa cevap. Standart boşluklar geçerlidir.

Yanıtlar:


2

Aslında 5 bayt

F÷♂FΣ

Çevrimiçi deneyin!

Nasıl çalışır

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

Dilin adı pasif agresif görünmesini sağlıyor, amaçlanan bu mu?
Rohan Jhunjhunwala

1
Şüpheliyim. Bu yorumdan dolayı dilin ilk sürümü Ciddi olarak çağrıldı . İkinci versiyon için yazar sıfatları kullanmaya devam etmeyi seçti.
Dennis

6

Jöle , 7 bayt

ÆḞÆDÆḞS

Çevrimiçi deneyin!

Açıklama:

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

Kesinlikle çirkin! Bu egzotik dillerin hiçbirini bilmiyorum, ancak bana birkaç karakterle bütün bir algoritmayı nasıl yazabileceğiniz çok doğal görünüyor.
Bogdan Alexandru

@BogdanAlexandru Burada kullanılan yerleşiklerin çoğunun 2 bayt tükettiğini görebilirsiniz, çünkü 1 bayta sığmazlar. Daha az karakter için Dennis'in Aslında cevabına bakınız. Ayrıca, Jelly bir "golf dili" dir, özellikle kod-golf için yapılmış bir dildir ve buradaki en verimli dillerden biridir (bir "en verimli" dil olmamasına rağmen).
Outgolfer Erik

Bu dillerin pratikte kullanılmadığını ve sadece zorluklara yönelik olduğunu mu söylüyorsunuz?
Bogdan Alexandru


4

Mathematica Basitleştirilmiş , 14 bayt

Fi@#~Div9`~Fi&

Ah, bu @ MartinEnder'in çözümü ile özdeş oldu ...


Şey ... Aynı dilin daha kısa bir versiyonunu kullanmak ... Sanırım bu işe yarıyor.
Neil A.

Mathematica'da tek harfli işlev adı yok, değil mi? Baştaki büyük harf artı tek bir bayttan oluşan iki karakter dizesinin tümünü eşleştiremez misiniz? Eğer öyleyse 26 * 256 = 6656 basitleştirilmiş 2 baytlık fonksiyon isimleriniz olurdu, 300 olan 6356 11.1.1 isimleri için yeterli.
Jonathan Allan

@JonathanAllan İyi fikir. (ancak tek isim işlevleri vardır N)
JungHwan Min


2

05AB1E , 11 bayt

!ÅFDI<èÑ<èO

Çevrimiçi deneyin!

açıklama

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

Leo'ya 2 bayt kaydettiği için teşekkürler.

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

Çevrimiçi deneyin!

Neredeyse kesinlikle optimal değil. Kontrol akışı oldukça ayrıntılıdır ve önceki sürümlere göre kaç bayt tasarruf ettiğinden oldukça memnun olduğum halde, işleri daha basit ve daha kısa bir çözüm olabileceğinden fazla karmaşıklaştırdığımı hissediyorum .

açıklama

İlk olarak, Alice'in dönüş adres yığını (RAS) üzerinde biraz durmam gerekiyor. Diğer birçok fungeoid gibi, Alice de kodda atlamak için bir komuta sahiptir. Ancak, alt rutinleri oldukça rahat bir şekilde uygulamanıza izin veren, nereden geldiğinize geri dönme komutları da vardır. Tabii ki, bu bir 2D dil, alt rutinler gerçekten sadece konvansiyonla var. Geri dönüş komutundan (veya alt programın herhangi bir noktasında) başka bir yolla alt programa girmenizi veya ayrılmanızı engelleyen hiçbir şey yoktur ve RAS'ı nasıl kullandığınıza bağlı olarak, yine de temiz bir atlama / dönüş hiyerarşisi olmayabilir.

Genel olarak bu, atlama komutunun atlamadan jönce geçerli IP adresini RAS'a iletmesi ile gerçekleştirilir. Dönüş komutu kdaha sonra RAS'ın adresini açar ve oraya atlar. RAS boşsa, khiçbir şey yapmaz.

RAS'ı manipüle etmenin başka yolları da vardır. Bunlardan ikisi bu programla ilgilidir:

  • wRAS geçerli IP adresini iter olmadan herhangi bir yere atlama. Bu komutu tekrarlarsanız &w...k, geçmiş döngülerde zaten yaptığım gibi basit döngüler oldukça rahat yazabilirsiniz .
  • Jbenzer jancak RAS'taki geçerli IP adresini hatırlamıyor.

RAS'ın IP'nin yönü hakkında hiçbir bilgi depolayamayacağına dikkat etmek de önemlidir . Bu nedenle, bir adrese geri dönmek , IP adresini nasıl geçirdiğimizden veya ilk etapta ittiğimizden bağımsız olarak kher zaman geçerli IP yönünü (ve dolayısıyla Kardinal veya Sıradan modda olup olmadığımızı) koruyacaktır .jw

Bu şekilde, yukarıdaki programdaki alt rutine bakarak başlayalım:

01dt,t&w.2,+k

Bu alt-rutinde yığının alt elemanı çekmekte, n , üst ve daha sonra Fibonacci sayıları hesaplar F, (n) ve (n-1 +) F (yığının üstüne bırakmak). Asla F'ye (n + 1) ihtiyacımız yoktur , ancak &w...kdöngülerin RAS ile etkileşimi nedeniyle alt rutinin dışında atılır (bu tür döngülerin bir alt rutinin sonunda olmasını gerektirir ). Üst kısım yerine alttan eleman almamızın nedeni, bu yığını yığına daha çok bir kuyruk gibi işlememize izin vermesidir, bu da tüm Fibonacci numaralarını başka bir yerde saklamak zorunda kalmadan tek seferde hesaplayabileceğimiz anlamına gelir.

Bu altyordam şöyle çalışır:

                                                          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.

Döngünün sonu biraz zor. Yığında 'w' adresinin bir kopyası olduğu sürece, bu bir sonraki yinelemeyi başlatır. Bunlar tükendikten sonra, sonuç altyordamın nasıl çağrıldığına bağlıdır. Altyordam 'j' ile çağrılmışsa, son 'k' oraya geri döner, bu nedenle döngü sonu altyordamın geri dönüşü olarak iki katına çıkar. Altyordam 'J' ile çağrılmışsa ve yığın üzerinde daha önce hala bir adres varsa, oraya atlarız. Bu, alt rutinin bir dış ilmeğin kendisinde çağrılması durumunda, bu 'k' o dış ilmeğin başına geri döner . Altyordam 'J' ile çağrılmışsa ancak RAS şimdi boşsa, bu 'k' hiçbir şey yapmaz ve IP döngüden sonra hareket etmeye devam eder. Bu vakaların üçünü de programda kullanacağız.

Son olarak, programın kendisine.

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

Bunlar, ondalık tam sayıları okumak ve yazdırmak için Ordinal moda yalnızca iki hızlı gezidir.

Sonra, ikinci nedeniyle alt rutine geçmeden önce mevcut pozisyonu hatırlayan ibir var . Altprogramın Bu ilk başlatılmasını hesaplar ve girişi . Daha sonra buraya atlıyoruz, ama şimdi doğuya hareket ediyoruz, bu yüzden Kardinal modunda program operatörlerinin geri kalanı. Ana program şöyle görünür:w/F(n)F(n+1)n

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

Burada, 31Jaltyordam için bir başka çağrı ve bu nedenle bir Fibonacci numarası hesaplar.

                                              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

Aksiyom, 68 bayt

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

bazı testler

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

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)

'Gmp' kütüphanesini kullanır. Bu yerleşik bir Fibonacci fonksiyonuna sahiptir ve çok sayıda yapma yeteneği sağlar. Seqs ve uygulamayla ilgili birkaç soruna neden oldu, ancak yine de kendi Fibonacci işlevimi oluşturmaktan daha küçük.

açıklama

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

Ölçek

> 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

Gmp kullanmadan

81 bayt , büyük (9+) sayılar seçildiğinde umutsuzca yavaşlayan yinelemeli işlev

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

88 bayt , Binet'in daha büyük sayılarla oldukça iyi çalışacak, ancak yine de tamsayı sınırına oldukça hızlı bir şekilde ulaşacak formülü

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 bayt

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

Çevrimiçi deneyin!

Eminim daha iyi yapılabilir. Açıklama:

Fikir, Fibonacci sayıları dizisine sahip olmak ve bu sayı girişin bir böleniyse veya değilse, 1s ve 0s içeren bir dizi ile nokta ürün yapmaktır.

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 bayt

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)

Test senaryoları


0

JavaScript (ES6), 105 104 103 101 97 bayt

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

Dene

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>


Ben düşünüyorum değiştirebileceğiniz (z=g(i)/y)>~~ziçin (z=g(i)/y)%1sadece o atmaktaysanız, zbir tam sayıdır.
ETHproductions 23:17

@ETHproductions, bu değiştirerek çözülebilir bir taşma oluşturur g(z)etmek g(z|0)ama bize aynı bayt sayımına yedeklemek getiriyor.
Shaggy



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.