Bu numara gizlice Fibonacci mi?


23

Arka fon

Fibonacci sayısının ne olduğunu biliyorsunuz . Bazılarınız, Zeckendorf Teoremine göre, tüm pozitif tamsayıların bir veya daha fazla farklı Fibonacci sayısının toplamı olarak temsil edilebileceğini biliyor olabilir . Bir tamsayının en iyi Zeckendorf Temsilindeki terim sayısı nkendisinin bir Fibonacci numarasıysa, n"gizlice" Fibonacci diyeceğiz .

Örneğin:

139 = 89 + 34 + 13 + 3
This is a total of 4 integers. Since 4 is not a Fibonacci number, 139 is not secretly Fibonacci

140 = 89 + 34 + 13 + 3 + 1
This is a total of 5 integers. Since 5 is a Fibonacci number, 140 is secretly Fibonacci

notlar

  • Optimal Zeckendorf Temsili, açgözlü bir algoritma kullanarak bulunabilir. Basitçe en büyük Fibonacci numarasını <= n alın ve 0'a ulaşana kadar n'den çıkarın
  • Tüm Fibonacci sayıları, 1 Fibonacci sayısının (kendisinin) toplamı olarak gösterilebilir. 1 bir Fibonacci sayısı olduğundan, tüm Fibonacci sayıları da gizlice Fibonacci'dir.

Meydan okuma

Buradaki zorluk, bir tamsayı alan ve bu tamsayının gizlice Fibonacci olup olmadığını döndüren bir program veya işlev yazmaktır.

Giriş

Herhangi bir makul formatta girdi alabilirsiniz. Girişin tek bir pozitif tamsayı olacağını varsayabilirsiniz.

Çıktı

Girdinin gizlice Fibonacci olup olmadığına ilişkin iki belirgin sonuçtan birini çıktılayın. Örnekler arasında True/ False, 1/ 0, vb.

puanlama

Bu , bayt cinsinden en kısa cevap! Standart boşluklar yasaktır.

Test Kılıfları

Truthy (secretly Fibonacci)
1
2
4
50
140
300099

Falsey (NOT secretly Fibonacci)
33
53
54
139
118808

6
Bu fi-meraklı oldukları anlamına mı geliyor?
kevin

2
Kimsenin yararına olması durumunda: En uygun miktar, arka arkaya iki Fibonacci numarası kullanmayan eşsiz bir çözümdür.
kasperd

2
@ kasperd Haklısın, eğer düşünürseniz mantıklı geliyor. Çözeltinin iki ardışık Fibonacci numarası varsa, bir sonrakini oluşturmak için birlikte eklenebilirler. Çözümünüz 5 ve 8 içeriyorsa, tek 13. olmasından daha az optimal olan olurdu
Cowabunghole

@Cowabunghole Bu sezgi. Tam bir kanıt bundan biraz daha karmaşıktır. Çözüm zaten 5, 8 ve 13 içeriyorsa, 5 + 8 değil 8 + 13 eklersiniz. Diğer yönün de kanıtlanması gerekiyor.
kasperd

Yanıtlar:



8

Python 2,77 bayt

def f(n):z=[bin(x).count('1')for x in range(n*n+1)if x&2*x<1];print z[z[n]]<2

Çevrimiçi deneyin!

Bu, OEIS A003714'ün iki tanımının eşdeğer olduğu teoremini kullanır :

n=F(ben1)+F(ben2)++F(benk)nnbir(n)=2ben1+2ben2++2benk1'S.

zn

Sonra z[n]bir Fibonacci numarası olup olmadığını kontrol etmek için kalır , yani z[z[n]] == 1.

n2+1


Arkadaki tırnakları sökerek iki baytı kesebilirsiniz bin(x). Ayrıca değiştirerek birini kaldırmak range(n*n+1)için range(n<<n). (0 'ın geçersiz olduğu varsayılıyor)
nedla2004

Etrafımdaki geri tepmelerle ne düşündüğümü bilmiyorum bin(x)haha. Ve, hm, 1<<nzaten yol, fazlasıyla yeterli, ama çalışma zamanını astronomik olarak tutmak
Lynn

Dürüst olmak gerekirse, kodu çalıştırabilmek önemli bir özellik olabilir. :)
nedla2004

6

Jöle , 15 bayt

‘ÆḞ€fRṪạµƬL’Ɗ⁺Ị

Olumsuz bir tamsayıyı kabul eden monadik bir bağlantı 1, "Gizlice Fibonacci" ve 0aksi takdirde elde edilir.

Çevrimiçi deneyin! (büyük test durumları için çok yetersiz)

Nasıl?

‘ÆḞ€fRṪạµƬL’Ɗ⁺Ị - Link: integer, I
        µƬ      - perform the monadic link to the left as a function of the current I,
                - collecting up all the inputs until the results are no longer unique:
‘               -   increment I -> I+1
 ÆḞ€            -   nth Fibonacci number for €ach n in [1,I+1]
     R          -   range from 1 to I
    f           -   filter discard (discard Fibonacci numbers not in the range, i.e. > I)
      Ṫ         -   tail (get the largest)
       ạ        -   absolute difference with I
                - This gives us a list from I decreasing by Fibonacci numbers to 0
                - e.g. for 88 we get [88,33,12,4,1,0]
                -      because (88-33)+(33-12)+(12-4)+(4-1)+(1-0)=55+21+8+3+1=88 
          L     - length (the number of Fibonacci numbers required plus one)
           ’    - decrement (the number of Fibonacci numbers required)
            Ɗ   - treat the last three links (which is everything to the left) as a monad:
             ⁺  - ...and repeat it
                - i.e. get the number of Fibonacci numbers required for the number of
                -      Fibonacci numbers required to represent I.
                -      This is 1 if I is Secretly Fibonacci, and greater if not)
              Ị - insignificant? (is the absolute value of that <= 1?)


5

C # (.NET Çekirdeği) , 124 115 98 bayt

a=>{int n=0,b,c;for(;a>0;a-=b,n++)for(b=c=1;c<=a;b=c-b)c+=b;for(b=c=1;c<n;c+=b)b=c-b;return c==n;}

Çevrimiçi deneyin!

-3 bayt: döngü için ( Olivier Grégoire sayesinde ) değiştirildi
-6 bayt: değişken, kullanıma hazır b ve c döngüler dışında ( Kevin Cruijssen sayesinde )
-17 bayt değiştirildi. döngü dışına alın ve geri dönüş ile birleştirin, son döngüde tekrar kullanılan b ve c değişkenleri ( raznagul sayesinde )

Ungolfed:

a => {
    int n = 0, b, c;                        // initialize variables

    for(; a > 0; a -= b, n++)               // increase n until a is 0
        for(b = c = 1; c <= a; b = c - b)   // set b and c to 1 for each a; set second largest Fibonacci number until largest Fibonacci number reaches a
            c += b;                         // set largest Fibonacci number of current sequence

    for(b = c = 1; c < n; c += b)           // while e is less than or equal to n, continue incrementing largest (e) Fibonacci number in the sequence
        b = c - b;                          // increment second-largest (d) Fibonacci number

    return c == n;                          // if c equals n, a is a secret Fibonacci number
}

1
for(;c<=a;b=c-b)c+=b;seni 3 bayt kurtaracak.
Olivier Grégoire

1
115 bayt . {}Döngülerinizin tüm dirseklerini çıkardım ve her şeyi-döngülere koydum for. Ayrıca, sizin için rbelirlediğimiz ve sonunda döndürdüğümüz bir değişkeni de ekledim , bu yüzden sadece bir taneye sahipsiniz . 1if(e==n)return
Kevin Cruijssen

İkisine de iyi çağrı. While döngüsünü for olarak değiştirmeye çalıştım ve bir şekilde bunu yapmanın kolay yolunu kaçırdım. Dönüş için ayrı bir değişkene sahip olmak da kesinlikle daha iyidir.
Meerkat

1
İkinci döngüdeki koşulu değiştirerek döngünün sonrasına e<nhareket edebilir ifve sonuçta returnfor 101 bayt ile birleştirebilirsiniz .
raznagul

1
Sen yeniden kullanarak başka 3 bayt kaydedebilir bve cson döngüde ve kaldırma dve e.
raznagul

4

Perl 6 , 58 bayt

{(1,&[+]...*>$_)∋($_,{$^n-(1,&[+]...^*>$n).tail}...0)-1}

Çevrimiçi deneyin!

1, &[+] ... * > $_ sadece Fibonacci dizisidir, sınırsız ve uygun olmayan bir yerde durur (giriş numarası).

$_, { $^n - (1, &[+] ...^ * > $n).tail } ... 0giriş numarası ile başlayan ve en büyük Fibonacci sayısının bir önceki elemana göre önceki elemana eşit veya ondan daha az çıkarılmasıyla elde edilen her bir ardışık elemeden oluşan bir sayı dizisidir. Dizi 0ulaşıldığında sona erer . Örneğin, $_bir 140zaman bu dizisidir 140, 51, 17, 4, 1, 0.

Bir diziyi bu diziden çıkarmak bir sayı, uzunluğu olarak ele alır ve aradaki fark, birlikte eklenen giriş numarasını veren Fibonacci sayılarının sayısıdır. Ardından bu numara ilk Fibonacci dizisine üyelik için kontrol edilir.


Bu numarayı daha &[+]önce görmedim ! İki ilk terim tanımlamak zorunda kalmamaktan
Jo King,

1
Fibonacci dizisini bir işleve ve diğer birkaç değişikliğe atayarak 51 bayt
Jo King

L4m2 Limanı'nın JavaScript yanıtı, 50 bayt
nwellnhof

@nwellnhof Ha, küçük bir fark
Jo King,

3

Perl 6 , 48 bayt

{4>($_,{$_,{$_-(1,&[+]...*>$_)[*-2]}...^0}...1)}

Çevrimiçi deneyin!

Girişi, tek bir sayıya ulaşana kadar art arda Zeckendorf Representation listesine dönüştürür ve ardından dizinin uzunluğunun 4'ten az olup olmadığını kontrol eder.

Ortadaki Zenckendorf işlevi çoğunlukla Sean'ın cevabından birkaç iyileştirme ile geliyor.

Açıklama:

{4>($_,{$_,{$_-(1,&[+]...*>$_)[*-2]}...^0}...1)}
{                                              } # Anonymous code block
                                          ...     # Define a sequence:
    $_  # That starts at the input
      ,{                                 }  # Each element is defined by:
                                   ... # Another sequence that:
        $_,   # Starts at the previous element
            $_-   # The previous element minus
                1,&[+]...*     # The Fibonacci sequence
                          >$_  # Ending when it is larger than the previous element
               (             )[*-2]  # The second from last element
          {                        }...^0  # Run until 0, discarding the last element
         # This returns the length of the Zeckendorf Representation
                                         ...1  # Run this until it is length 1
 4>(                                         )  # Return true if the length of the sequence is smaller than 4

Örneğin, için sekans 2IS 2 1çünkü 2zaten Fibonacci sayıdır. Sırası 140olan 140 5 1ve 5 beri bu döner doğru Fibonacci sayıdır. Sırası 33olan 33 4 2 1ve yana 4dizi uzunluğu 4 olan bir Fibonacci sayı değil.


3

05AB1E , 14 bayt

ΔDÅFθ-¼}¾ÅF¾<å

Çevrimiçi deneyin . Tüm test durumları için test paketi yoktur, çünkü counter_variable0 olarak sıfırlanamaz.

Açıklama:

Δ      }          # Loop until the top of the stack no longer changes
 D                #  Duplicate the top of the stack
                  #  (implicitly the input in the first iteration)
  ÅF              #  Get a list of all Fibonacci numbers lower than this number
    θ             #  Get the last item (largest one)
     -            #  Subtract it from the number
      ¼           #  Increase the counter_variable by 1 every iteration
        ¾         # After the loop, push the counter_variable
         ÅF       # Get all Fibonacci numbers below this counter_variable
           ¾<     # Push the counter_variable again, and subtract 1
             å    # Check if this value is in the list of Fibonacci numbers
                  # (and output implicitly)

NOT: Giriş ve giriş için counter_variableolacaktır , çünkü -loop'un yığını kontrol etmesi için aynı kalması elbette ek bir yineleme yapar.51396140Δ



2

Retina 0.8.2 , 61 bayt

.+
$*
M`((?>\2?)(\1|\G.))*..|.
.+
$*
^(((?>\3?)(\2|^.))*.)?.$

Çevrimiçi deneyin! Link, test durumlarını içerir. Açıklama:

.+
$*

Birliğe dönüştür.

M`((?>\2?)(\1|\G.))*..|.

Gerekli Fibonacci sayıları sayısını.

İlk alternatif en az 2 olan Fibonacci sayılarıyla ilgilidir. İlk pasoda \2henüz mevcut değil, ama neyse ki isteğe bağlı, bu yüzden eşleşmek zorunda değiliz. \1ya da yok, ama neyse ki \G., maçın başlangıcında tek bir karakterle eşleşen alternatifine sahibiz . Her ikisi de \2ve \1bu nedenle 1 değerini alır.

Sonraki pasolarda \2var, bu yüzden eşleştirmeye çalışıyoruz. O zaman başarısız olursa bu kez \1de başarısız (o daha büyük olduğu için \2), ancak başarılı olursa, (?>)eğer öyleyse önler, geri izleme \2eşleştiği halde \1biz sadece kalkma gelmez \1. ( \G1yamanın başlangıcını geçtikten sonra her zaman başarısız olur.) Sonunda \2, önceki iki değeri \1alırken \1, iki değerin toplamını alır.

Bu nedenle mümkün olduğunca çok Fibonacci sayıları ile eşleşiyoruz, istediğimizi ekliyoruz. Dizinin kısmi toplamları 1, 2, 3, 5..., 0, 1, 3, 6, 11...yani Fibonacci sayılarından 2 daha az olduğundan, sonunda 2'yi eşleştirerek bitiriyoruz.

Bu açıkça 1 ile eşleşmiyor, bu yüzden bir değişiklik bu durumu ele alıyor.

.+
$*

Birliğe dönüştür.

^(((?>\3?)(\2|^.))*.)?.$

Bunun bir Fibonacci numarası olup olmadığını test edin. Bu, ilk test ile aynı fikri kullanır, ancak onun ^yerine kullanır \Gve tam olarak eşleşmemiz gerekir, bu yüzden bir golf yerine bir seçenek yerine isteğe bağlı bir yakalama kullanır (ancak yakalama numaralarını 1'e kadar artırır).

Retina , 35 bayt

.+
*
2}C`((?>\2?)(\1|\G.))*..|.
^1$

Çevrimiçi deneyin! Link, test durumlarını içerir. Açıklama:

.+
*

Birliğe dönüştür.

C`((?>\2?)(\1|\G.))*..|.

Gerekli Fibonacci sayıları sayısını. (Hem dönüşüm hem de sayıyı döngülemek, sayımı ilk sırada unary'e almaktan öteye bir bütün bayt kazandırır.)

2}

Önceki adımları toplamda iki kez gerçekleştirin. Bu, Fibonacci sayılarının sayısını toplamak için gereken Fibonacci sayılarının sayısını alır.

^1$

Sayı gizlice Fibonacci olsaydı, sonuç 1'dir.


1

Python 2 , 146 137 bayt

lambda a:len(g(len(g(a))))<2
f=lambda n:n<3or f(n-2)+f(n-1)
def g(a,n=1):j=f(n-1);return[j]if a-j<1else[j]+g(a-j)if a-f(n)<0else g(a,n+1)

Çevrimiçi deneyin!

f (), F Fibonacci sayısının değerini döndüren özyinelemeli bir işlevdir. Alındığı bu cevap .

g (), verilen sayının Zeckendorf Temsilini bir tamsayı listesi olarak döndüren özyinelemeli bir işlevdir.

Tüm Fibonacci sayıları g () 'den bir öğenin dönüş uzunluğuna sahip olacağından h (), g (n) g ()' nin == 1 uzunluğunu kontrol eder.

EDIT: nedla2004 sayesinde 9 bayt kurtardı . Lambdaların her zaman en iyi çözüm olmadığını unutmaya devam ediyorum ...


1
138 bayt . Bir değişkene gtanımlayabilmem f(n-1)için çoğunlukla sadece bir işlev yaptım . Dan Çift diğer değişiklikler ==için <aynı olduğu.
nedla2004
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.