Bir sayıyı Zeckendorf Gösterimi'nden Ondalık'a dönüştürme


18

Zeckendorf Temsilcilikleri / Baz Fibonacci Sayıları Hakkında

Bu temel olarak Fibonacci sayılarını kullanan bir sayı sistemidir. Sayılar 0 ve 1'lerden oluşur ve her 1, sayının karşılık gelen Fibonacci numarasını içerdiği ve 0'ın içermediği anlamına gelir.

Örneğin, tüm doğal sayıları <= 10 temel Fibonacci'ye dönüştürelim.

  • 1 1 olur, çünkü bu bir Fibonacci sayısı olan 1'in toplamıdır,

  • 2, 10 olacak, çünkü bu bir Fibonacci sayısı olan 2'nin toplamıdır ve 1'e ihtiyaç duymaz, çünkü zaten istenen toplamı elde ettik.

  • 3 100 olur, çünkü bu bir Fibonacci sayısı olan 3'ün toplamıdır ve istenen toplamı zaten elde ettiğimiz için 2 veya 1'e ihtiyaç duymaz.

  • 4 101 olur, çünkü her ikisi de Fibonacci sayıları olan [3,1] 'in toplamıdır.
  • 5, 1000 olacak, çünkü bu bir Fibonacci sayısı olan 5'in toplamıdır ve diğer sayılardan hiçbirine ihtiyacımız yoktur.
  • 6 1001 olacak, çünkü bu Fibonacci 5 ve 1 sayılarının toplamıdır.
  • 7, 1010 olacak, çünkü Fibonacci 5 ve 2 sayılarının toplamıdır.
  • 8 10000 olur, çünkü bu bir Fibonacci numarasıdır.
  • 9 10001 olacaktır, çünkü bu Fibonacci 8 ve 1 sayılarının toplamıdır.
  • 10 10010 olacaktır, çünkü bu Fibonacci 8 ve 2 sayılarının toplamıdır.

Rastgele bir Baz Fibonacci sayısını, 10101001010'u ondalığa dönüştürelim: İlk önce ilgili Fibonacci sayılarını yazıyoruz. Sonra 1'lerin altındaki sayıların toplamını hesaplıyoruz.

 1   0   1   0   1   0   0   1   0   1   0
 144 89  55  34  21  13  8   5   3   2   1  -> 144+55+21+5+2 = 227.

Temel Fibonacci sayıları hakkında daha fazla bilgi edinin: bağlantı , aynı zamanda düzenli tam sayıları temel Fibonacci'ye dönüştüren bir araca sahiptir. Bunu deneyebilirsiniz.

Şimdi soru:

Göreviniz Zeckendorf Temsilcisinde bir sayı almak ve ondalık değerini çıkarmaktır.

Giriş yalnızca 0 ve 1 içeren bir dizedir (girişi istediğiniz şekilde alabilmenize rağmen).

Ondalık olarak bir sayı çıktılayın.

Test senaryoları: (girdi-> çıktı biçiminde)

 1001 -> 6
 100101000 -> 73
 1000000000 -> 89
 1001000000100100010 -> 8432
 1010000010001000100001010000 -> 723452

Bu kod golf, bu yüzden bayttaki en kısa cevap kazanır.

Not: Giriş, önde gelen 0'lar veya ardışık 1'ler içermez.


Girdiyi bitler listesi olarak alabilir miyiz?
Rock Garf Hunter Post

Gibi, ascii kodlanmış giriş almak sonra ikili veya böyle bir şeye dönüştürmek?
Yel Değirmeni Kurabiyeleri

4
LSB birinci sırada girdi alabilir miyiz ?
Mego


1
@Mego Evet, yapabilirsiniz
Yel Değirmeni Kurabiyeleri

Yanıtlar:


19

Taksi , 1987 1927 bayt

Çizgi satırlarının isteğe bağlı olduğunun anlaşılması nedeniyle -60 bayt.

Go to Post Office:w 1 l 1 r 1 l.Pickup a passenger going to Chop Suey.Go to Chop Suey:n 1 r 1 l 4 r 1 l.[B]Switch to plan C if no one is waiting.Pickup a passenger going to Cyclone.Go to Cyclone:n 1 l 3 l.Pickup a passenger going to Narrow Path Park.Pickup a passenger going to Sunny Skies Park.Go to Zoom Zoom:n.Go to Sunny Skies Park:w 2 l.Go to Narrow Path Park:n 1 r 1 r 1 l 1 r.Go to Chop Suey:e 1 r 1 l 1 r.Switch to plan B.[C]1 is waiting at Starchild Numerology.1 is waiting at Starchild Numerology.Go to Starchild Numerology:n 1 l 3 l 3 l 2 r.Pickup a passenger going to Addition Alley.Pickup a passenger going to Cyclone.Go to Cyclone:w 1 r 4 l.[D]Pickup a passenger going to Addition Alley.Pickup a passenger going to Cyclone.Go to Addition Alley:n 2 r 1 r.Go to Cyclone:n 1 l 1 l.Pickup a passenger going to Multiplication Station.Go to Zoom Zoom:n.Go to Narrow Path Park:w 1 l 1 l 1 r.Switch to plan E if no one is waiting.Pickup a passenger going to The Babelfishery.Go to The Babelfishery:e 1 r.Pickup a passenger going to Multiplication Station.Go to Multiplication Station:n 1 r 2 l.Pickup a passenger going to Joyless Park.Go to Joyless Park:n 2 l 1 r 1 r.Go to Addition Alley:w 1 r 2 l 1 l.Pickup a passenger going to Cyclone.Go to Cyclone:n 1 l 1 l.Pickup a passenger going to Addition Alley.Switch to plan D.[E]Go to Addition Alley:w 1 l 1 r 1 l.Pickup a passenger going to Riverview Bridge.Go to Riverview Bridge:n 1 r.Go to Joyless Park:e 1 r 2 l.Pickup a passenger going to Addition Alley.[F]Switch to plan G if no one is waiting.Pickup a passenger going to Addition Alley.Go to Fueler Up:w 1 l.Go to Addition Alley:n 3 l 1 l.Pickup a passenger going to Addition Alley.Go to Joyless Park:n 1 r 1 r 2 l.Switch to plan F.[G]Go to Addition Alley:w 1 r 2 l 1 l.Pickup a passenger going to The Babelfishery.Go to The Babelfishery:n 1 r 1 r.Pickup a passenger going to Post Office.Go to Post Office:n 1 l 1 r.

Çevrimiçi deneyin!

Sonunda Taksi Garajına dönmediğim için patronum beni kovuyor, bu yüzden bir hata ile çıkıyor.


Joyless Parkziyaret etmek için güzel bir yer gibi görünüyor
aloisdg diyor Reinstate Monica

Şey, daha az karakterdir Sunny Skies Park.
JosiahRyanW

11

Perl 6 , 28 23 bayt

{[+] (1,2,*+*...*)Z*$_}

Çevrimiçi deneyin!

LSB sıralamasında 1s ve 0s listesini alan ve bir sayı döndüren anonim kod bloğu .

Açıklama:

{                     }   # Anonymous codeblock
 [+]                      # The sum of
     (1,2,*+*...*)        # The infinite Fibonacci sequence starting from 1,2
                  Z*      # Zip multiplied by
                    $_    # The input list in LSB form



4

Haskell , 38 bayt

f=1:scanl(+)2f
sum.zipWith(*)f.reverse

Çevrimiçi deneyin!

Girişi 1s ve 0s listesi olarak alır.

açıklama


f=1:scanl(+)2f

Değişken olarak Fibonacci sayılarının birincisini sans yapar f.

sum.zipWith(*)f.reverse

Girdi listesini reversealır ve her girdiyi karşılık gelen girdi ile çarpar f, sonra sumda sonuçları alır.

Haskell , 30 bayt

f=1:scanl(+)2f
sum.zipWith(*)f

Çevrimiçi deneyin!

Öncelikle en az önemli bit ile girdi reversealırsak, 8 bayt tasarruf edebilmemiz için ihtiyacımız yoktur .


4

Python 2 , 43 bayt

a=b=0
for x in input():b+=a+x;a=b-a
print b

Çevrimiçi deneyin!

Girişi liste olarak alır. Güncelleme, görmezden gelirseniz a,b=b+x,a+b+xFibonacci güncellemesine benzeyen daha kısa bir sürümüdür .a,b=b,a+bx


Python 2 , 45 bayt

f=lambda n,a=1,b=1:n and n%10*b+f(n/10,b,a+b)

Çevrimiçi deneyin!

Girdiyi ondalık sayı olarak alır.


3

Pyth, 13 bayt

Bunların çoğu (8 bayt) sadece Fibonacci sayılarını üretmektedir.

s*V_m=+Z|~YZ1

Bu test paketi ile deneyin!

Açıklama:

s*V_m=+Z|~YZ1QQ     Autofill variables
    m=+Z|~YZ1Q      Generate the first length(input) Fibonacci numbers as follows:
       Z             Start with Z=0
         ~YZ         And Y=[] (update it to Y=Z, return old Y)
        |   1        if Y is [], then replace with 1
      +              Sum Z and Y
     =               Replace Z with sum
    m                Repeat process
             Q       once for each element of the input
   _                Reverse the order of the Fibonacci numbers
 *V                 Vectorize multiplication
s                   Sum


3

J , 24 14 bayt

#.~2+&%&1~#-#\

Çevrimiçi deneyin!

Fibonacci için karışık tabanı kullanan 24 baytlık versiyonda golf.

Nasıl çalışır

#.~2+&%&1~#-#\  Example input: y=1 0 0 1 0
          #-#\  Length minus 1-based indices; 4 3 2 1 0
   2     ~      Starting from 2, run the following (4,3,2,1,0) times:
    +&%&1         Given y, compute 1 + 1 / y
                The result is 13/8 8/5 5/3 3/2 2
#.~             Mixed base conversion of y into base above; 2+8=10

J , 21 bayt

1#.|.*[:+/@(!~#-])\#\

Çevrimiçi deneyin!

Galen Ivanov'un 25 baytlık çözümünün rafine versiyonu .

Binom katsayılarının toplamına eşdeğer olan Pascal üçgeninin çapraz toplamını kullanır:

Fn=i=0nniCi

Nasıl çalışır

1#.|.*[:+/@(!~#-])\#\
                       Example input: 1 0 0 1 0
                   #\  Generate 1-based index; 1 2 3 4 5
      [:          \    For each prefix of above... (ex. 1 2 3)
              #-]        Subtract each element from the length (ex. 2 1 0)
           (!~   )       Compute binomial coefficient (ex. 3C0 + 2C1 + 1C2)
        +/@              Sum
                       The result is Fibonacci numbers; 1 2 3 5 8
   |.*                 Multiply with mirrored self; 0 2 0 0 8
1#.                    Sum; 10

J , 24 bayt

3 :'y#.~|.(1+%)^:(<#y)2'

Çevrimiçi deneyin!

Monadik açık fiil. Fibonacci bazını temsil eden karışık bazı oluşturur ve daha sonra baz dönüşümüne beslenir #..

Nasıl çalışır

y#.~|.(1+%)^:(<#y)2  Explicit verb, input: y = Fibonacci digit array, n = length of y
      (1+%)          x -> 1 + 1/x
           ^:(<#y)2  Apply the above 0..n-1 times to 2
                     The result looks like 2/1, 3/2, 5/3, 8/5, 13/8, ...
    |.               Reverse
                     Now, if it is fed into #. on the left, the digit values become
                     ...(8/5 * 5/3 * 3/2 * 2/1), (5/3 * 3/2 * 2/1), (3/2 * 2/1), 2/1, 1
                     which is ... 8 5 3 2 1 (Yes, it's Fibonacci.)
y#.~                 Convert y to a number using Fibonacci base

Alternatifler

J , 27 bayt

}.@(+#{.3#{.)^:(<:@#)@(,&0)

Çevrimiçi deneyin!

Fikir:

 1  0  0  1  0  1
-1 +1 +1
------------------
    1  1  1  0  1
   -1 +1 +1
------------------
       2  2  0  1
      -2 +2 +2
------------------
          4  2  1
         -4 +4 +4
------------------
             6  5
            -6 +6 +6 <- Add an imaginary digit that has value 1
---------------------
               11  6
              -11+11
---------------------
                  17 <- the answer

J , 30 bayt

0.5<.@+(%:5)%~(-:>:%:5)#.,&0 0

Çevrimiçi deneyin!

Bu, inşa etmek için en çok çaba sarf etti. Yuvarlanmış hile ile kapalı form ifadesini kullanır. İfadede, 0. ve 1. değerler sırasıyla 0 ve 1'dir, bu nedenle gerçek basamak gücü 2 ile başlamalıdır.

0.5<.@+(%:5)%~(-:>:%:5)#.,&0 0  Tacit verb.
                         ,&0 0  Add two zeroes at the end
              (-:>:%:5)#.       Convert to a number using base phi (golden ratio)
       (%:5)%~                  Divide by sqrt(5)
0.5<.@+                         Round to nearest integer

Hata ( ((1-sqrt(5))/2)^nterimler) oluşabilse de, asla 0,5'i aşmaz, bu nedenle yuvarlama hilesi sonsuza kadar çalışır. Matematiksel olarak:

max(|error|)=151(152)2n=150(152)n=5125<12


Güzel çözüm! Tacit çözümünü yenen açık bir fiil gördüğüme sevindim.
Galen Ivanov

Daha kısa bir zımni çözüm bulmaya çalışıyorum ama başarılı olamadım. Şimdilik 25 bayt . Pascal'ın üçgenini kullanıyorum.
Galen Ivanov

@GalenIvanov Bir yıl sonra meydan okumaya yeniden baktığımda yeni, süper kısa bir zımni çözüm buldum :)
Bubbler

Bu harika! Yakında daha ayrıntılı olarak bakacağım.
Galen Ivanov

2

MathGolf , 8 6 bayt

{î)f*+

Çevrimiçi deneyin!

açıklama

{        Start block (foreach in this case)
 î)      Push loop index (1-based) and increment by 1
   f     Get fibonacci number of that index
    *    Multiply with the array value (0 or 1)
     +   Add top two elements of stack. This implicitly pops the loop index the first iteration, which makes the addition become 0+a, where a is the top of the stack.

JoKing sayesinde 1 bayt, LSB siparişi sayesinde başka bir bayt tasarruf etti.


LSB siparişine gerçekten izin verilir. ayrıca, -1 byte
Jo King

@JoKing Tabii ki, geçen hafta örtük eklemeyi bile uyguladım ... Hoş bir dokunuş, şimdi MathGolf beraberinde ilk sırada!
maxb

2

05AB1E , 11 9 8 bayt

vyiNÌÅfO

Çevrimiçi deneyin!

Açıklama:

v             : For each character in input string (implicit) in LSB order
  yi          : If the current character is truthy (1)
    NÌ        : Add 2 to the current index
       ÅfO    : Add the fibonacci of this number to the stack
  • -2 bayt : @KevinCruijssen'e bu kodu kısaltmanın küçük yollarını gösterdiği için teşekkürler!
  • -1 bayt : Giriş için LSB siparişini işaret ettiği için @JonathanAllan'a teşekkürler!

1
Öğesini kaldırabilirsiniz Θ. 1zaten 05AB1E'de doğrudur. :) Ayrıca, 2+olabilir Ì.
Kevin Cruijssen

1
Girdiyi bir bit (ya da iki?) Kaydetmesi gereken Little-endian biçiminde (yani tersine) alabiliriz.
Jonathan Allan




1

Stax , 6 bayt

çéC◘0â

Çalıştır ve hata ayıkla

:1F^|5+           #Full program, unpacked, implicit input as array    
:1                #Get indicies of truthy
  F               #Use rest of program to loop through elements
   ^              #Increment current element
    |5+           #Get n-th fib and Add

Oldukça düz ileri. LSB Siparişi.



1

C (gcc) , 63 bayt

Girdiyi dizinin uzunluğu ile birlikte 1's ve 0' s dizisi olarak alır. Bu çözüm oldukça basit bir ileri geri döngüdür.

f(_,l,a,b,t)int*_;{a=b=1;for(t=0;l--;b=(a+=b)-b)t+=a*_[l];_=t;}

Çevrimiçi deneyin!


1

Prolog (SWI) , 74 bayt

\D-->[X,Y],{D is 2*X+Y};[D];a,\D.
a,[A],[B]-->[X,Y,Z],{A is X+Y,B is X+Z}.

Çevrimiçi deneyin!

Girdiyi, önce en önemli bit olan 1 ve 0 tamsayıları listesi olarak alır.


0

Retina 0.8.2 , 23 bayt

0?
;
+`1;(1*);
;1$1;1
1

Çevrimiçi deneyin! Bağlantı daha hızlı test senaryolarını içerir. Açıklama:

0?
;

Her yere ayırıcılar ekleyin ve sıfırları silin. Örneğin, 1001olur ;1;;;1;.

+`1;(1*);
;1$1;1

Değerlerinin toplamı orijinalin değerine eşit olduğundan, her birini sonraki iki yerin her birinde 1bir a ile tekrar tekrar değiştirin . bu nedenle son iki yere ulaşana kadar göç edip birikirler (yeni eklenen ayırıcıdan dolayı) artık her ikisinin de değeri vardır .1111

1

Say 1.




0

Aslında 8 bayt

;r⌐@░♂FΣ

Çevrimiçi deneyin!

Giriş, LSB birinci sırada bitlerin bir listesi olarak alınır.

Açıklama:

;r⌐@░♂FΣ
;r        range(0, len(input))
  ⌐       add 2 to every element in range (range(2, len(input)+2))
   @░     filter: take values in range that correspond to 1s in input
     ♂F   Fibonacci number at index of each element in list (Actually uses the F(0)=F(1)=1 definition, which is why we needed to add 2 earlier)
       Σ  sum

0

Powershell, 68 bayt

param($s)$b=1
$s[$s.Length..0]|%{$a,$b=$b,($a+$b)
$x+=($_-48)*$b}
$x

Test komut dosyası:

$f = {
param($s)$b=1
$s[$s.Length..0]|%{$a,$b=$b,($a+$b)
$x+=($_-48)*$b}
$x
}

@(
    ,("1001", 6)
    ,("100101000", 73)
    ,("1000000000", 89)
    ,("1001000000100100010", 8432)
    ,("1010000010001000100001010000", 723452)
) | % {
    $s,$e = $_
    $r = &$f $s
    "$($r-eq$e): $r"
}

Çıktı:

True: 6
True: 73
True: 89
True: 8432
True: 723452

0

Java (OpenJDK 8) , 65 bayt

Java cevabı için oldukça küçük, bundan memnunum. Girişi LSB tarafından sipariş edilen ilk dizi olarak alır.

d->{int s=0,f=1,h=1;for(int i:d){s+=i>0?f:0;f=h+(h=f);}return s;}

Çevrimiçi deneyin!

Ungolfed

d->{                        // Lambda function that takes array of ints
    int s=0,f=1,h=1;        // Initialise sum and fibonacci vars
    for(int i:d){           // Loop through each input integer
        s+=i>0?f:0;         // If it's 1 add current fibonacci number to sum
        f=h+(h=f);          // Increase fibonacci number 
    }return s;              // return sum
}

0

Z80Golf , 34 bayt

00000000: dde1 f1b7 2819 fe30 2812 4504 aff5 3cf5  ....(..0(.E...<.
00000010: d1f1 82d5 f510 f9c1 f17c 8067 2c18 e3dd  .........|.g,...
00000020: e5c9                                     ..

Giriş 1001 ile örnek-Çevrimiçi deneyin!

100101000 girişli örnek-Çevrimiçi deneyin!

Montaj:

zeck:		; input=push on stack in MSB order (eg top is LSB) output=reg h
pop ix		; save return addr in ix
f:
pop af		; get next digit
or a
jr z, return	; if current digit==0, return
cp 0x30
jr z, skip	; if current digit=='0' (e.g. not '1'), skip loop
ld b, l		; find fib of counter
fib:
	inc b	; 1-indexing for func to work
	xor a	; set a to 0 (1st fibo num)
	push af
	inc a	; set a to 1 (2nd fibo num)
	push af
	fib_loop:
		pop de
		pop af
		add d
		push de
		push af
		djnz fib_loop
pop bc		; get the fibo num just calculated
pop af		; pop just to reset stack frame
ld a, h
add b		; add current fibo number to sum
ld h, a
skip:
inc l		; increment counter reg
jr f		; repeat loop
return:
push ix		; push the return addr to ret to it
ret
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.