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.