Conversione di un numero dalla rappresentazione di Zeckendorf in decimale


18

Informazioni su rappresentazioni di Zeckendorf / numeri di Fibonacci di base

Questo è un sistema numerico che utilizza i numeri di Fibonacci come base. I numeri sono composti da 0 e 1 e ogni 1 indica che il numero contiene il corrispondente numero di Fibonacci e 0 indica che non lo è.

Ad esempio, convertiamo tutti i numeri naturali <= 10 in Fibonacci base.

  • 1 diventerà 1, perché è la somma di 1, che è un numero di Fibonacci,

  • 2 diventerà 10, perché è la somma di 2, che è un numero di Fibonacci, e non ha bisogno di 1, perché abbiamo già ottenuto la somma desiderata.

  • 3 diventerà 100, perché è la somma di 3, che è un numero di Fibonacci e non ha bisogno di 2 o 1 perché abbiamo già ottenuto la somma desiderata.

  • 4 diventerà 101, perché è la somma di [3,1], che sono entrambi numeri di Fibonacci.
  • 5 diventerà 1000, perché è la somma di 5, che è un numero di Fibonacci, e non abbiamo bisogno di nessuno degli altri numeri.
  • 6 diventerà 1001, perché è la somma dei numeri di Fibonacci 5 e 1.
  • 7 diventerà 1010, perché è la somma dei numeri di Fibonacci 5 e 2.
  • 8 diventerà 10000, perché è un numero di Fibonacci.
  • 9 diventerà 10001, perché è la somma dei numeri 8 e 1 di Fibonacci.
  • 10 diventerà 10010, perché è la somma dei numeri di Fibonacci 8 e 2.

Convertiamo un numero casuale di Fibonacci, 10101001010 in decimale: per prima cosa scriviamo i corrispondenti numeri di Fibonacci. Quindi calcoliamo la somma dei numeri sotto 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.

Maggiori informazioni sui numeri di Fibonacci di base: link , ha anche uno strumento che converte interi regolari in Fibonacci di base. Puoi sperimentarlo.

Ora la domanda:

Il tuo compito è prendere un numero nella rappresentazione Zeckendorf e produrre il suo valore decimale.

L'input è una stringa che contiene solo 0 e 1 (sebbene sia possibile accettare l'input nel modo desiderato).

Emette un numero in decimale.

Casi di prova: (nel formato input-> output)

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

Questo è code-golf, quindi vince la risposta più breve in byte.

Nota: l'ingresso non conterrà alcun 0 iniziale o 1 consecutivo.


Possiamo prendere l'input come un elenco di bit?
Wheat Wizard

Ad esempio, prendi l'input ASCII codificato e convertilo in binario o qualcosa del genere?
Windmill Cookies

4
Possiamo prendere input nel primo ordine LSB ?
Mego


1
@Mego Sì, puoi
Windmill Cookies

Risposte:


19

Taxi , 1987 1927 byte

-60 byte a causa della consapevolezza che le interruzioni di riga sono opzionali.

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.

Provalo online!

Perché alla fine non torno al Taxi Garage, il mio capo mi licenzia, quindi esce con un errore.


Joyless Parksembra un bel posto da visitare
aloisdg dice Reinstate Monica l'

Bene, sono meno personaggi di Sunny Skies Park.
JosiahRyanW,

11

Perl 6 , 28 23 byte

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

Provalo online!

Anonimo codeblock che prende una lista di 1s e 0s in LSB ordine e restituisce un numero.

Spiegazione:

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

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

Provalo online!

Accetta input come un elenco di 1 e 0 secondi.

Spiegazione


f=1:scanl(+)2f

Fa un elenco dei numeri di Fibonacci senza il primo, in variabile f.

sum.zipWith(*)f.reverse

Prende la lista di input reversemoltiplica ogni voce per la voce corrispondente in f, quindi sumi risultati.

Haskell , 30 byte

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

Provalo online!

Se prima prendiamo l'input con il bit meno significativo, non ne reverseabbiamo bisogno, quindi possiamo salvare 8 byte.


4

Python 2 , 43 byte

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

Provalo online!

Accetta input come elenco. L'aggiornamento è una versione più breve di a,b=b+x,a+b+x, che è come l'aggiornamento di Fibonacci a,b=b,a+bse si ignora x.


Python 2 , 45 byte

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

Provalo online!

Accetta input come numeri decimali.


3

Pyth, 13 byte

La maggior parte di questo (8 byte) sta semplicemente generando i numeri di Fibonacci.

s*V_m=+Z|~YZ1

Provalo con questa suite di test!

Spiegazione:

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 byte

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

Provalo online!

Abbassò la versione a 24 byte che utilizza la base mista per Fibonacci.

Come funziona

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

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

Provalo online!

Versione raffinata della soluzione a 25 byte di Galen Ivanov .

Utilizza la somma diagonale del triangolo di Pascal, che è equivalente alla somma dei coefficienti binomiali:

Fn=Σio=0nn-ioCio

Come funziona

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 byte

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

Provalo online!

Verbo esplicito monadico. Genera la base mista che rappresenta la base di Fibonacci e quindi si nutre nella conversione di base #..

Come funziona

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

alternative

J , 27 byte

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

Provalo online!

L'idea:

 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 byte

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

Provalo online!

Questo ha richiesto il massimo sforzo per costruire. Usa l'espressione a forma chiusa con il trucco arrotondato. Nell'espressione, i valori 0 e 1 sono rispettivamente 0 e 1, quindi la potenza effettiva delle cifre deve iniziare con 2.

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

Mentre l'errore ( ((1-sqrt(5))/2)^ntermini) può accumularsi, non supera mai 0,5, quindi il trucco di arrotondamento funziona fino all'infinito. Matematicamente:

max(|error|)=15Σ1(1-52)2n=15Σ0(1-52)n=5-125<12


Bella soluzione! Sono felice di vedere un verbo esplicito che batte la soluzione tacita.
Galen Ivanov,

Sto cercando di trovare una soluzione tacita più breve, ma senza successo. 25 byte per ora . Uso il triange di Pascal.
Galen Ivanov,

@GalenIvanov Rivisitando la sfida dopo un anno, ho ottenuto una nuova soluzione tacita super breve :)
Bubbler

È fantastico! Lo guarderò presto in maggiori dettagli.
Galen Ivanov,

2

MathGolf , 8 6 byte

{î)f*+

Provalo online!

Spiegazione

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

Salvato 1 byte grazie a JoKing e un altro byte grazie all'ordinamento LSB.


L'ordine LSB è infatti consentito. anche -1 byte
Jo King

@JoKing Naturalmente, ho anche implementato l'aggiunta implicita proprio la scorsa settimana ... Bel tocco, ora MathGolf è al primo posto legato!
max

2

05AB1E , 11 9 8 byte

vyiNÌÅfO

Provalo online!

Spiegazione:

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 byte : grazie a @KevinCruijssen per aver indicato piccoli modi per abbreviare questo codice!
  • -1 byte : grazie a @JonathanAllan per aver segnalato l'ordine LSB per l'input!

1
È possibile rimuovere il Θ. 1è già vero in 05AB1E. :) Inoltre, 2+può essere Ì.
Kevin Cruijssen,

1
Possiamo prendere l'input in forma di Little-endian (cioè invertito), che dovrebbe salvare un byte (o due?).
Jonathan Allan,




1

Stax , 6 byte

çéC◘0â

Esegui ed esegui il debug

: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

Abbastanza diretto. Ordinazione LSB.



1

C (gcc) , 63 byte

Prende l'input come una matrice di 1"se 0", insieme alla lunghezza della matrice. Questa soluzione è un ciclo all'indietro piuttosto diretto.

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

Provalo online!


1

Prolog (SWI) , 74 byte

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

Provalo online!

Prende l'input come un elenco di numeri interi 1 e 0 con prima il bit più significativo.


0

Retina 0.8.2 , 23 byte

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

Provalo online! Link include i casi di test più veloci. Spiegazione:

0?
;

Inserisci separatori ovunque ed elimina eventuali zeri. Ad esempio, 1001diventa ;1;;;1;.

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

Sostituisci ripetutamente ciascuno 1con a 1in ciascuno dei due posti successivi, poiché la somma dei loro valori è uguale al valore dell'originale 1. 1quindi migrano e si accumulano fino a raggiungere le ultime due posizioni, che (a causa del nuovo separatore aggiunto) ora hanno entrambi valore 1.

1

Conta la 1s.




0

In realtà , 8 byte

;r⌐@░♂FΣ

Provalo online!

L'input viene considerato come un elenco di bit nel primo ordine LSB.

Spiegazione:

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

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

Script di prova:

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

Produzione:

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

0

Java (OpenJDK 8) , 65 byte

Abbastanza piccolo per una risposta Java a cui sono contento. Accetta input come un array di ints ordinato per primo da LSB.

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

Provalo 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 byte

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

Esempio con input 1001-Provalo online!

Esempio con input 100101000-Provalo online!

Montaggio:

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.