Conversion d'un nombre de la représentation de Zeckendorf en décimal


18

A propos des représentations de Zeckendorf / Numéros de base de Fibonacci

Il s'agit d'un système numérique qui utilise les nombres de Fibonacci comme base. Les nombres se composent de 0 et de 1 et chaque 1 signifie que le nombre contient le numéro de Fibonacci correspondant, et 0 signifie qu'il n'en contient pas.

Par exemple, convertissons tous les nombres naturels <= 10 en Fibonacci de base.

  • 1 deviendra 1, car c'est la somme de 1, qui est un nombre de Fibonacci,

  • 2 deviendra 10, car c'est la somme de 2, qui est un nombre de Fibonacci, et il n'a pas besoin de 1, car nous avons déjà atteint la somme souhaitée.

  • 3 deviendra 100, car c'est la somme de 3, qui est un nombre de Fibonacci et il n'a pas besoin de 2 ou 1 car nous avons déjà atteint la somme souhaitée.

  • 4 deviendra 101, car il s'agit de la somme de [3,1], tous deux des nombres de Fibonacci.
  • 5 deviendra 1000, car c'est la somme de 5, qui est un nombre de Fibonacci, et nous n'avons besoin d'aucun des autres nombres.
  • 6 deviendra 1001, car c'est la somme des nombres de Fibonacci 5 et 1.
  • 7 deviendra 1010, car c'est la somme des nombres de Fibonacci 5 et 2.
  • 8 deviendra 10000, car il s'agit d'un nombre de Fibonacci.
  • 9 deviendra 10001, car il s'agit de la somme des nombres de Fibonacci 8 et 1.
  • 10 deviendra 10010, car c'est la somme des nombres de Fibonacci 8 et 2.

Convertissons un nombre aléatoire de Fibonacci de base, 10101001010 en décimal: nous écrivons d'abord les nombres de Fibonacci correspondants. Ensuite, nous calculons la somme des nombres sous 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.

En savoir plus sur les nombres de base de Fibonacci: lien , il dispose également d'un outil qui convertit les entiers réguliers en base de Fibonacci. Vous pouvez l'expérimenter.

Maintenant la question:

Votre tâche consiste à prendre un nombre dans la représentation de Zeckendorf et à afficher sa valeur décimale.

L'entrée est une chaîne qui ne contient que 0 et 1 (bien que vous puissiez prendre l'entrée comme vous le souhaitez).

Sortie un nombre en décimal.

Cas de test: (au format entrée-> sortie)

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

Il s'agit de code-golf, donc la réponse la plus courte en octets l'emporte.

Remarque: L'entrée ne contiendra aucun 0 ou 1 consécutif.


Pouvons-nous prendre l'entrée comme une liste de bits?
Post Rock Garf Hunter

Comme, prenez l'entrée ascii encodée puis convertissez-la en binaire ou quelque chose comme ça?
Cookies du moulin à vent

4
Pouvons-nous prendre les données en premier ordre LSB ?
Mego


1
@Mego Oui, vous pouvez
Windmill Cookies

Réponses:


19

Taxi , 1987 1927 octets

-60 octets en raison de la prise de conscience que les sauts de ligne sont facultatifs.

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.

Essayez-le en ligne!

Parce que je ne retourne pas au Taxi Garage à la fin, mon patron me licencie, donc il sort avec une erreur.


Joyless Parksemble un bon endroit à visiter
aloisdg dit Reinstate Monica

Eh bien, c'est moins de caractères que Sunny Skies Park.
JosiahRyanW

11

Perl 6 , 28 23 octets

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

Essayez-le en ligne!

Bloc de code anonyme qui prend une liste de 1s et 0s dans l'ordre LSB et renvoie un nombre.

Explication:

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

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

Essayez-le en ligne!

Prend l'entrée comme une liste de 1 et de 0.

Explication


f=1:scanl(+)2f

Fait une liste des nombres de Fibonacci sans le premier, en variable f.

sum.zipWith(*)f.reverse

Prend la liste des entrées reverses multiplie chaque entrée par l'entrée correspondante dans f, puis sums les résultats.

Haskell , 30 octets

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

Essayez-le en ligne!

Si nous prenons d'abord l'entrée avec le bit le moins significatif, nous n'en avons pas besoin reversepour économiser 8 octets.


4

Python 2 , 43 octets

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

Essayez-le en ligne!

Prend la saisie sous forme de liste. La mise à jour est une version plus courte de a,b=b+x,a+b+x, qui ressemble à la mise à jour de Fibonacci a,b=b,a+bsi vous l'ignorez x.


Python 2 , 45 octets

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

Essayez-le en ligne!

Prend la saisie sous forme de nombres décimaux.


3

Pyth, 13 octets

La plupart de ces informations (8 octets) ne font que générer les nombres de Fibonacci.

s*V_m=+Z|~YZ1

Essayez-le avec cette suite de tests!

Explication:

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 octets

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

Essayez-le en ligne!

Golfed down la version 24 octets qui utilise la base mixte pour Fibonacci.

Comment ça fonctionne

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

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

Essayez-le en ligne!

Version raffinée de la solution à 25 octets de Galen Ivanov .

Utilise la somme diagonale du triangle de Pascal, qui est équivalente à la somme des coefficients binomiaux:

Fn=je=0nn-jeCje

Comment ça fonctionne

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 octets

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

Essayez-le en ligne!

Verbe explicite monadique. Génère la base mixte qui représente la base de Fibonacci, puis alimente la conversion de base #..

Comment ça fonctionne

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

Alternatives

J , 27 octets

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

Essayez-le en ligne!

L'idée:

 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 octets

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

Essayez-le en ligne!

Celui-ci a pris le plus d'efforts à construire. Utilise l'expression de forme fermée avec astuce d'arrondi. Dans l'expression, les valeurs 0 et 1 sont respectivement 0 et 1, donc la puissance réelle des chiffres doit commencer par 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

Bien que l'erreur ( ((1-sqrt(5))/2)^ntermes) puisse s'accumuler, elle ne dépasse jamais 0,5, donc l'astuce d'arrondi fonctionne jusqu'à l'infini. Mathématiquement:

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


Bonne solution! Je suis content de voir un verbe explicite battre la solution tacite.
Galen Ivanov

J'essaie de trouver une solution tacite plus courte, mais sans succès. 25 octets pour l'instant . J'utilise le triange de Pascal.
Galen Ivanov

@GalenIvanov Revisitant le défi après un an, j'ai eu une nouvelle solution tacite super courte :)
Bubbler

C'est génial! Je vais l'examiner plus en détail bientôt.
Galen Ivanov

2

MathGolf , 8 6 octets

{î)f*+

Essayez-le en ligne!

Explication

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

1 octet enregistré grâce à JoKing et un autre octet grâce à la commande LSB.


L'ordre LSB est en effet autorisé. aussi, -1 octet
Jo King

@JoKing Bien sûr, j'ai même implémenté l'ajout implicite la semaine dernière ... Nice touch, maintenant MathGolf est à égalité en première place!
max

2

05AB1E , 11 9 8 octets

vyiNÌÅfO

Essayez-le en ligne!

Explication:

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 octets : Merci à @KevinCruijssen d'avoir indiqué de petites façons de raccourcir ce code!
  • -1 octet : Merci à @JonathanAllan d'avoir souligné l'ordre LSB pour la saisie!

1
Vous pouvez supprimer le fichier Θ. 1est déjà vrai dans 05AB1E. :) 2+Peut aussi l'être Ì.
Kevin Cruijssen

1
Nous pouvons prendre l'entrée sous forme Little-endian (ie inversé), ce qui devrait sauver un octet (ou deux?).
Jonathan Allan




1

Stax , 6 octets

çéC◘0â

Exécuter et déboguer

: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

Assez simple. Commande LSB.



1

C (gcc) , 63 octets

Prend l'entrée comme un tableau de 1'et 0', avec la longueur du tableau. Cette solution est une boucle arrière assez simple.

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

Essayez-le en ligne!


1

Prolog (SWI) , 74 octets

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

Essayez-le en ligne!

Prend l'entrée comme une liste d'entiers 1 et 0 avec le bit le plus significatif en premier.


0

Retina 0.8.2 , 23 octets

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

Essayez-le en ligne! Link inclut les cas de test les plus rapides. Explication:

0?
;

Insérez des séparateurs partout et supprimez tous les zéros. Par exemple, 1001devient ;1;;;1;.

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

Remplacez à plusieurs reprises chacun 1par un 1dans chacun des deux emplacements suivants, car la somme de leurs valeurs est égale à la valeur de l'original 1. 1les s migrent et s'accumulent donc jusqu'à atteindre les deux derniers endroits, qui (en raison du séparateur nouvellement ajouté) ont maintenant tous deux de la valeur 1.

1

Comptez le 1s.




0

En fait , 8 octets

;r⌐@░♂FΣ

Essayez-le en ligne!

L'entrée est considérée comme une liste de bits dans le premier ordre LSB.

Explication:

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

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

Script de test:

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

Production:

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

0

Java (OpenJDK 8) , 65 octets

Assez petit pour une réponse Java, j'en suis satisfait. Prend l'entrée comme un tableau ordonné de LSB-first.

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

Essayez-le en ligne!

Non golfé

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 octets

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

Exemple avec l'entrée 1001-Essayez-le en ligne!

Exemple avec l'entrée 100101000-Essayez-le en ligne!

Assemblée:

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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.