Umwandlung einer Zahl von der Zeckendorf-Darstellung in eine Dezimalzahl


18

Über Zeckendorf Vertretungen / Basis Fibonacci Nummern

Dies ist ein Zahlensystem, das Fibonacci-Zahlen als Basis verwendet. Die Zahlen bestehen aus 0 und 1 und jede 1 bedeutet, dass die Zahl die entsprechende Fibonacci-Zahl enthält, und 0 bedeutet, dass dies nicht der Fall ist.

Lassen Sie uns zum Beispiel alle natürlichen Zahlen <= 10 in Basis-Fibonacci konvertieren.

  • 1 wird 1, weil es die Summe von 1 ist, die eine Fibonacci-Zahl ist,

  • 2 wird zu 10, weil es sich um die Summe von 2 handelt, die eine Fibonacci-Zahl ist, und es wird keine 1 benötigt, weil wir bereits die gewünschte Summe erreicht haben.

  • 3 wird zu 100, weil es sich um die Summe von 3 handelt, die eine Fibonacci-Zahl ist und keine 2 oder 1 benötigt, weil wir bereits die gewünschte Summe erreicht haben.

  • 4 wird 101, weil es die Summe von [3,1] ist, die beide Fibonacci-Zahlen sind.
  • 5 wird zu 1000, da es sich um die Summe von 5 handelt, die eine Fibonacci-Zahl ist, und wir keine der anderen Zahlen benötigen.
  • 6 wird 1001, weil es die Summe der Fibonacci-Zahlen 5 und 1 ist.
  • 7 wird 1010, weil es die Summe der Fibonacci-Zahlen 5 und 2 ist.
  • 8 wird zu 10000, da es sich um eine Fibonacci-Zahl handelt.
  • 9 wird 10001, weil es die Summe der Fibonacci-Zahlen 8 und 1 ist.
  • 10 wird zu 10010, weil es die Summe der Fibonacci-Zahlen 8 und 2 ist.

Lassen Sie uns eine zufällige Basis-Fibonacci-Zahl, 10101001010, in eine Dezimalzahl umwandeln: Zuerst schreiben wir die entsprechenden Fibonacci-Zahlen. Dann berechnen wir die Summe der Zahlen unter 1.

 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.

Lesen Sie mehr über Base Fibonacci-Zahlen: link , es gibt auch ein Tool, das reguläre Ganzzahlen in Base Fibonacci umwandelt. Sie können damit experimentieren.

Nun die Frage:

Ihre Aufgabe ist es, eine Zahl in die Zeckendorf-Darstellung aufzunehmen und deren Dezimalwert auszugeben.

Die Eingabe ist eine Zeichenfolge, die nur 0 und 1 enthält (obwohl Sie die Eingabe beliebig verwenden können).

Geben Sie eine Dezimalzahl aus.

Testfälle: (im Format Eingabe-> Ausgabe)

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

Das ist Code-Golf, also gewinnt die kürzeste Antwort in Bytes.

Hinweis: Der Eingang enthält keine führenden Nullen oder aufeinander folgenden Einsen.


Können wir Eingaben als Liste von Bits annehmen?
Weizen-Assistent

Nehmen Sie die Eingabe als ASCII-codiert und konvertieren Sie sie dann in eine Binärdatei oder so ähnlich?
Windmill Cookies

4
Können wir Eingaben in LSB-erster Ordnung vornehmen ?
Mego


1
@ Mego Ja, Sie können
Windmill Cookies

Antworten:


19

Taxi , 1987 1927 Bytes

-60 Byte aufgrund der Erkenntnis, dass Zeilenumbrüche optional sind.

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.

Probieren Sie es online!

Da ich am Ende nicht in die Taxigarage zurückkehre, feuert mich mein Chef und es wird mit einem Fehler beendet.


Joyless Parkscheint ein schöner Ort zu sein
Aloisdg sagt Reinstate Monica

Nun, es sind weniger Zeichen als Sunny Skies Park.
JosiahRyanW

11

Perl 6 , 28 23 Bytes

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

Probieren Sie es online!

Anonymer Codeblock, der eine Liste von 1s und 0s in der LSB-Reihenfolge aufnimmt und eine Zahl zurückgibt.

Erläuterung:

{                     }   # 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 Bytes

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

Probieren Sie es online!

Nimmt die Eingabe als Liste von Einsen und Nullen.

Erläuterung


f=1:scanl(+)2f

Erstellt eine Liste der Fibonacci-Zahlen ohne die erste, in Variablen f.

sum.zipWith(*)f.reverse

Nimmt die Eingabeliste, reversemultipliziert sie jeden Eintrag mit dem entsprechenden Eintrag in f, dann sumdie Ergebnisse.

Haskell , 30 Bytes

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

Probieren Sie es online!

Wenn wir die Eingabe mit dem niedrigstwertigen Bit zuerst einlesen, brauchen wir das nicht, reversesodass wir 8 Bytes sparen können.


4

Python 2 , 43 Bytes

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

Probieren Sie es online!

Übernimmt die Eingabe als Liste. Das Update ist eine kürzere Version von a,b=b+x,a+b+x, die dem Fibonacci-Update gleicht, a,b=b,a+bwenn Sie es ignorieren x.


Python 2 , 45 Bytes

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

Probieren Sie es online!

Übernimmt die Eingabe als Dezimalzahl.


3

Pyth, 13 Bytes

Das meiste davon (8 Bytes) generiert nur die Fibonacci-Zahlen.

s*V_m=+Z|~YZ1

Probieren Sie es mit dieser Testsuite aus!

Erläuterung:

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 Bytes

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

Probieren Sie es online!

Die 24-Byte-Version, die die gemischte Basis für Fibonacci verwendet, wurde verbessert.

Wie es funktioniert

#.~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 Bytes

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

Probieren Sie es online!

Verfeinerte Version der 25-Byte-Lösung von Galen Ivanov .

Verwendet die diagonale Summe des Pascalschen Dreiecks, die der Summe der Binomialkoeffizienten entspricht:

Fn=ich=0nn-ichCich

Wie es funktioniert

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 Bytes

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

Probieren Sie es online!

Monadisches explizites Verb. Erzeugt die gemischte Basis, die die Fibonacci-Basis darstellt, und fließt dann in die Basiskonvertierung ein #..

Wie es funktioniert

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

Alternativen

J , 27 Bytes

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

Probieren Sie es online!

Die Idee:

 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 Bytes

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

Probieren Sie es online!

Dieser hat die meiste Mühe gemacht, um zu bauen. Verwendet den Ausdruck in geschlossener Form mit Rundungstrick. In dem Ausdruck sind der 0. und der 1. Wert 0 bzw. 1, daher muss die tatsächliche Ziffernstärke mit 2 beginnen.

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

Der Fehler ( ((1-sqrt(5))/2)^nTerme) kann sich zwar aufbauen, überschreitet jedoch nie 0,5, sodass der Rundungstrick bis unendlich funktioniert. Mathematisch:

max(|errOr|)=151(1-52)2n=150(1-52)n=5-125<12


Schöne lösung! Ich bin froh zu sehen, dass ein explizites Verb die stillschweigende Lösung schlägt.
Galen Ivanov

Ich versuche eine kürzere stillschweigende Lösung zu finden, aber ohne Erfolg. 25 Bytes für jetzt . Ich benutze Pascals Triange.
Galen Ivanov

@GalenIvanov Nachdem ich die Herausforderung nach einem Jahr noch einmal durchgesehen hatte, bekam ich eine neue, super kurze, implizite Lösung :)
Bubbler

Das ist großartig! Ich werde es mir bald genauer ansehen.
Galen Ivanov

2

MathGolf , 8 6 Bytes

{î)f*+

Probieren Sie es online!

Erläuterung

{        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.

Dank JoKing 1 Byte und dank LSB-Bestellung ein weiteres Byte eingespart.


LSB-Reihenfolge ist in der Tat erlaubt. auch -1 Byte
Jo King

@JoKing Natürlich habe ich erst letzte Woche den impliziten Zusatz implementiert ... Nette Geste, jetzt steht MathGolf an erster Stelle!
Maxb

2

05AB1E , 11 9 8 Bytes

vyiNÌÅfO

Probieren Sie es online!

Erläuterung:

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 Bytes : Vielen Dank an @KevinCruijssen für den Hinweis auf kleine Möglichkeiten, diesen Code zu verkürzen!
  • -1 Byte : Vielen Dank an @ JonathanAllan für den Hinweis auf die LSB-Reihenfolge für die Eingabe!

1
Sie können die entfernen Θ. 1ist in 05AB1E schon wahr. :) 2+Kann auch sein Ì.
Kevin Cruijssen

1
Wir können die Eingabe in Little-Endian-Form nehmen (dh umgekehrt), was ein Byte (oder zwei?) Sparen sollte.
Jonathan Allan




1

Stax , 6 Bytes

çéC◘0â

Führen Sie es aus und debuggen Sie es

: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

Ziemlich einfach. LSB-Bestellung.



1

C (gcc) 63 Bytes

Nimmt die Eingabe als Array von 1's und 0' s zusammen mit der Länge des Arrays. Diese Lösung ist eine eher unkomplizierte Rückwärtsschleife.

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

Probieren Sie es online!


1

Prolog (SWI) , 74 Bytes

\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}.

Probieren Sie es online!

Nimmt die Eingabe als Liste von Ganzzahlen 1 und 0, wobei das höchstwertige Bit an erster Stelle steht.


0

Retina 0.8.2 , 23 Bytes

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

Probieren Sie es online! Link enthält die schnelleren Testfälle. Erläuterung:

0?
;

Fügen Sie überall Trennzeichen ein und löschen Sie alle Nullen. Zum Beispiel 1001wird ;1;;;1;.

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

Ersetzen wiederholt jeweils 1mit einem1 an jeder der nächsten zwei Stellen, da die Summe ihrer Werte dem Wert des Originals entspricht 1.1s migrieren und akkumulieren daher, bis sie die letzten beiden Stellen erreichen, die (aufgrund des neu hinzugefügten Trennzeichens) nun beide Wert haben 1.

1

Zähle die 1 s.




0

Eigentlich 8 Bytes

;r⌐@░♂FΣ

Probieren Sie es online!

Die Eingabe wird als Liste von Bits in der Reihenfolge LSB-First verwendet.

Erläuterung:

;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 Bytes

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

Testskript:

$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"
}

Ausgabe:

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

0

Java (OpenJDK 8) , 65 Byte

Ziemlich klein für eine Java-Antwort, damit bin ich zufrieden. Nimmt Eingaben als ein LSB-erstes geordnetes Array von Ints an.

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

Probieren Sie es online!

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 Bytes

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

Beispiel mit Eingabe 1001-Online ausprobieren!

Beispiel mit Eingabe 100101000-Online ausprobieren!

Versammlung:

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.