Fibonacci ürünleri


13

Pozitif Fibonacci sayılarının benzersiz bir toplamı olarak 0'dan büyük bir sayı çağırabilirsiniz. Bu soruda bunu mümkün olan en büyük pozitif Fibonacci sayısını art arda çıkararak yapıyoruz . Örneğin:

1 = 1
2 = 2
3 = 3
4 = 3 + 1
12 = 8 + 3 + 1
13 = 13
100 = 89 + 8 + 3

Şimdi, bir Fibonacci ürününü yukarıdakiyle aynı listeler olarak adlandırıyorum, ancak ekleme çarpma ile değiştirildi. Örneğin f(100) = 89 * 8 * 3 = 2136,.

Pozitif tamsayı n veren bir program veya fonksiyon yazın , bu sayının Fibonacci ürününü döndürür.


testcases:

1: 1
2: 2
3: 3
4: 3
5: 5
6: 5
7: 10
8: 8
9: 8
42: 272
1000: 12831
12345: 138481852236

6
İfade oldukça doğru değil. Örn . 2Olarak ayrıştırılabilir -1 + 3. Zeckendorf teoreminin doğru ifadesi, pozitif bir Fibonacci sayısının, pozitif indekse sahip ardışık olmayan Fibonacci sayılarının toplamı olarak benzersiz şekilde ayrıştırılabileceğidir.
Peter Taylor

1
@PeterTaylor Negatif Fibonacci sayılarını bu soru için serinin bir parçası olarak görmüyorum. Ardışık veya sadece endeksleri istediğinizde önemli değildir, bu soru için endeksleri umursamıyoruz.
orlp

1
Negatif Fibonacci sayılarını desteklemek için soruyu değiştirmeniz gerektiğini söylemiyorum: Yaptığınız varsayımlar hakkında açık olmak için onu düzenlemeniz gerektiğini söylüyorum.
Peter Taylor

1
@orlp birbirini takip ediyor ya da pek önemli değil, çünkü iki farklı form iki farklı ürün verecek. Sorunu zaten ardışık Fibonacci terimlerini örtük olarak dışlayacak şekilde belirtmiştiniz, bu yüzden orada endişelenecek bir şey yok.
ocaklar

2
(özellikle: F (n) ve F (n + 1) her ikisi de çıktıda görünemez çünkü algoritma, bunları dikkate almadan önce, kalanın F (n + 2) = F (n) + F (n + 1))
ocaklar

Yanıtlar:


5

Jöle , 16 15 bayt

Rf1+С¤ṪạµÐĿIAP

Özellikle hızlı veya bellek dostu değil, tüm test senaryoları için yeterince verimli. Çevrimiçi deneyin!

Nasıl çalışır

Rf1+С¤ṪạµÐĿIAP  Main link. Argument: n (integer)

         µ       Combine the chain to the left into a link.
          ÐĿ     Apply that link until the results are no longer unique.
                 Return the list of unique results.
      ¤            Combine the two links to the left into a niladic chain.
  1                  Set the left (and right) argument to 1.
   +D¡               Apply + to the left and right argument, updating the left
                     argument with the sum, and the right argument with the
                     previous value of the left one. Return the list of results.
                     Repeat this process n times.
                   This yields n + 1 Fibonacci numbers, starting with 1, 2.
R                  Range; map k to [1, ..., k].
 f                 Filter; keep the items in the range that are Fibonacci numbers.
       Ṫ           Tail; yield the last one or 0 if the list is empty.
        ạ          Absolute difference with k.
                   This is the argument of the next iteration.
            I    Compute the increments of the arguments to the loop, yielding
                 the selected Fibonacci numbers (with changed sign).
             A   Apply absolute value to each.
              P  Compute their product.  

6
Bu çok büyük görünüyor, Dennis.
orlp

9

Python, 54 bayt

f=lambda n,a=1,b=1:n<1or b>n and a*f(n-a)or f(n,b,a+b)

Sadece eski güzel bir özyineleme.


5

Perl, 69 63 + 4 ( -pl61bayrak) = 67 bayt

#!perl -pl61
while($_){$n=$m=1;($n,$m)=($m,$n+$m)until$m>$_;$_-=$n;$\*=$n}}{

Kullanımı:

> echo 42 | perl -pl61e 'while($_){$n=$m=1;($n,$m)=($m,$n+$m)until$m>$_;$_-=$n;$\*=$n}}{'

Ungolfed:

while (<>) {
# code above added by -p
    # $_ has input value
    # $\ = 1 by -l61
    while ($_ != 0) {
        my $n = 1;
        my $m = 1;
        while ($m <= $_) {
            ($n, $m) = ($m, $n + $m);
        }
        $_ -= $n;
        $\ *= $n;
    }
} {
# code below added by -p
    print;  # prints $_ (undef here) and $\
}

Ideone .


Açıklama, sekizlik 061karakterin ASCII kodlaması olduğunu belirtmelidir '1'. $\Yakın kesmek için yazdırmak için kullanmak güzel kesmek .
Peter Cordes

2

JavaScript (ES6), 78 42 bayt

f=(n,a=1,b=1)=>n?b>n?a*f(n-a):f(n,b,a+b):1

@ Sp3000'in cevabı portu. Orijinal 78 baytlık sürüm:

f=(n,a=[2,1])=>n>a[0]?f(n,[a[0]+a[1],...a]):a.map(e=>e>n?0:(r*=e,n-=e),r=1)&&r

2

> <> , 57 bayt

111\ ;n{/
:@+>:{:})?\$:@@
~{*}:0=?\}>:0${:})?$~:{$-$:1@?$

Program başlangıcında yığınta giriş numarasının bulunmasını bekler.

Girişten ( f0, f1, f2, ..., fn) daha büyük bir sayıya ulaşılana kadar destedeki Fibonacci dizisini ( ) oluşturur i. Ardından, bir ürün ( p) ile 1...

while (i != 0)
   if (fn <= i)
      i = i - fn
      p = p * fn
   else
      i = i - 0
      p = p * 1
   discard fn
output p

Çevrimiçi deneyin!




1

Pyth, 24 bayt

W=-QeaYh.WgQeH,eZsZ1;*FY

Çevrimiçi deneyin: Gösteri veya Test Paketi

Açıklama:

Q giriş numarası ile atanır.

Parça h.WgQeH,eZsZ1, daha küçük veya eşit olan en büyük Fibonacci sayısını hesaplarQ

h.WgQeH,eZsZ1
            1   start with H=Z=1
 .WgQeH         while Q >= end(H):
       ,eZsZ       H=Z=(end(Z), sum(Z))
h               first

Yani Q = 10, sayıları / çiftleri üretirse:

1 -> (1,1) -> (1,2) -> (2,3) -> (3,5) -> (5,8) -> (8,13) -> 8

Kodun geri kalanı bölümü hesaplar ve sayıları birlikte çarpar:

W=-QeaY...;*FY    implicit: Y = empty list
     aY...        add the calculated Fibonacci number to the empty list
    e             take the last element of Y (yes the number we just added)
 =-Q              and update Q with the difference of Q and ^
W         ;       continue until Q == 0
           *FY    multiply all number in Y and print

Açıkçası çok daha kısa çözümler var (gerçekten kötü çalışma sürelerine rağmen), gibi *FhfqQsTyeM.u,eNsNQ1.


1

Haskell, 44 bayt

Karşılıklı özyineleme için Yay:

(a&b)c|c<1=1|b>c=a*f(c-a)|d<-a+b=b&d$c
f=0&1
  • a önceki Fibonacci sayısıdır
  • b Mevcut Fibonacci sayısı
  • c girdi
  • f istenen işlevdir

Daha az golf:

(a & b) c | c == 0    = 1
          | c <  b    = a * f (c-a)
          | otherwise = b & (a + b) $ c
f x = (0 & 1) x

1

Aslında 22 bayt

W;╗uR♂F;`╜≥`M░M;╜-WXkπ

Çevrimiçi deneyin!

Açıklama:

W;╗uR♂F;`╜≥`M░M;╜-WXkπ
                        (implicit input)
W                 W     while top of stack is truthy:
 ;╗                       push a copy of n to reg0
   uR♂F;                  push 2 copies of [Fib(a) for a in range(1, n+2)]
        `╜≥`M░            filter: take values where n <= Fib(a)
              M;          two copies of maximum (call it m)
                ╜-        subtract from n (this leaves n-m on top of the stack to be the new n next iteration, with a copy of m below it)
                   X    discard the 0 left over after the loop ends
                    kπ  product of all stack values

Aslında kendi kodlaması var mı? 22 karakterde 35 bayt sayıyorum. mothereff.in/…
kedi

1
@cat Tıpkı Ciddi gibi CP437 kullanır.
Mego

1

JavaScript (ES6) 134 106 92 bayt

@Cat için bir yer tespit ettiğiniz için teşekkür ederiz.

n=>{for(c=[a=b=s=1,1];a+b<=n;)a+=b,c.unshift(b+=a,a);c.map(i=>i<=n&&(n-=i)&(s*=i));alert(s)}

Sadece benim telefonumda yapılan optimize edilmemiş bir versiyon, ben bir kez eve, ben golf. Fikirler açıktır.


Bir tane süper boşluk var. : P
kedi

1

DÖNÜŞ , 44 bayt

[a:[a;][1$[¤¤+$a;->~][]#%$␌a;\-a:]#␁[¤][×]#]

Try it here.

Stack2 sonuç bırakan şaşırtıcı derecede verimsiz anonim lambda. Kullanımı:

12345[a:[a;][1$[¤¤+$a;->~][]#%$␌a;\-a:]#␁[¤][×]#]!

NOT: ␌ ve ␁, basılamaz karakterleri için yer tutuculardır: Form Beslemesi ve Başlığın Başlangıcı .

açıklama

[                                           ]  lambda
 a:                                            store input to a
   [  ][                         ]#            while loop
    a;                                           check if a is truthy
        1$[¤¤+$a;->~][]#%                        if so, generate all fibonacci numbers less than a 
                         $␌                      push copy of TOS to stack2
                           a;\-a:                a-=TOS
                                   ␁[¤][×]#   get product of stack2

42 karakterde 46 bayt sayıyorum. RETURN biraz özel kodlama kullanıyorsa, 42 karakterde 42 bayt olmalıdır, ancak unicode gibi görünüyor, bu yüzden 46.
kedi

Aslında farkettim ki bazı yazdırılamaz şeyler koymayı unuttum.
Mama Fun Roll

Ne olduklarını söylemek için mikroskoba ihtiyacım vardı, bu yüzden senin için onlara bağlandım. : D (SOH veya BOM olup olmadığını söyleyemedim)
kedi

0

PHP, 119 bayt

Kod (okunabilirlik için iki satıra sarılmış):

for($o=$c=1;$c<=$n=$argv[1];$f[++$k]=$c,$a=$b,$b=$c,$c+=$a);
for($i=$k;$i;$i--)for(;$n>=$d=$f[$i];$n-=$d,$o*=$d);echo$o;

İlk satır $fFibonacci sayılarından küçüktür $n(komut satırında sağlanan argüman). İkinci satır (çıkarma ile) Fibonacci faktörlerini hesaplar ve bunları ürünü hesaplamak için çarpar $o.

Kodu <?php(teknik olarak programın bir parçası değil) ile başa getirin, bir dosyaya ( fibonacci-factors.php) koyun ve şu şekilde çalıştırın:

$ php -d error_reporting=0 fibonacci-factors.php 100
# The output:
2136

Veya kullanarak çalıştırın php -d error_reporting=0 -r '... code here ...' 100.

Ungolfed kodu ve test paketi bulunabilir Github .


0

Q, 47 Bayt

m:{*/1_-':|(0<){y-x x bin y}[*+60(|+\)\1 0]\x}

Ölçek

+(i;m'i:1 2 3 4 5 6 7 8 9 42 1000 12345)

çiftler (i, harita (m, i)) olarak okuyun, burada m hesaplama işlevidir ve i farklı argümanlar

yazıyor

1     1
2     2
3     3
4     3
5     5
6     5
7     10
8     8
9     8
42    272
1000  12831
12345 138481852236

açıklama

n funtion\arg function (function (function (... function (args))) n kez uygular (dahili olarak tal özyinelemeyi kullanır) ve sonuç sırasını döndürür. Fibonnaci serisinin ilk 60 öğesini şu şekilde hesaplarız: *+60(|+\)\1 0Bu durumda işlev ( | +): + \ bir dizi üzerine uygulanan kısmi toplamları hesaplar (ex + \ 1 2 3 1 3 6) ve | sekansı tersine çevirir. Böylece her 'yineleme' önceki iki fibonacci sayısının kısmi toplamlarını hesaplar ve kısmi döndürür ters çevrilmiş toplamlar 60(|+\)\1 01 0, 1 1, 2 1, 3 2, 5 3, 8 5, 13 8, 21 13, ... *+bu sonuç üzerine uygulanan dizileri oluşturur (ilk amaç) ve birinci alır. 1 2 3 5 8 13 21 34 55 ..

(cond)function\args cond true durumunda işlev (function (.. function (args)) uygular ve kısmi sonuçların sırasını döndürür

function[arg] birden fazla argümanın bir işlevi üzerine uygulanan bir projeksiyon oluşturur (kısmi uygulama)

Bağımsız değişkenlere ad verebiliriz, ancak örtük adlar x, y, z

{y-x x bin y}[*+60(|+\)\1 0]x, y kısmi izdüşümlü bir lambda bildirir (arg x, fibonacci serisidir, * + 60 (| +) \ 1 0 olarak hesaplar). x, fibonacci değerlerini ve y, işlenecek sayıyı temsil eder. İkili arama (bin), daha büyük fibonacci sayısının <= y ( x bin y) indeksini bulmak ve karşılık gelen x değerini özetlemek için kullanılır.

Kısmi sonuçlardan ürünü hesaplamak için bunları tersine çevirir ve her bir çiftin ( -':|) farkını hesaplar , ilkini düşürür ( 1_çünkü 0'dır) ve (( */) ile çarparız .

Birikmiş toplamla ilgileniyorsak, kod aynıdır, +/bunun yerine ile */. + Veya * yerine başka bir diadik operatör de kullanabiliriz

Yürütme verimliliği hakkında

Bu yarışmada verimliliğin bir sorun olmadığını biliyorum. Ama bu problemde çizgisel maliyetten üstel maliyete kadar değişebiliriz, bu yüzden merak ediyorum.

İkinci bir versiyon geliştirdim (yorum hariç uzunluk 48 bayt) ve her iki versiyonda da 1000 kez pilleri tekrarladım.

f:*+60(|+\)\1 0;m:{*/1_-':|(0<){x-f f bin x}\x}    /new version

yürütme süresi: orijinal sürüm 0'212 seg, yeni sürüm 0'037 seg

Orijinal sürüm, fonksiyon uygulaması başına bir kez fibbonaci serisini hesaplar; yeni sürüm sadece bir fibonacci hesaplar.

Her iki durumda da fibonacci serisinin hesaplanması kuyruk özyineleme kullanır

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.