Перетворення числа з представлення Зекендорфа в десяткове


18

Про представлення Зекендорфа / Основи Фібоначчі

Це система чисел, яка використовує числа Фібоначчі як свою основу. Числа складаються з 0 і 1, і кожне 1 означає, що число містить відповідне число Фібоначчі, а 0 означає, що це не так.

Наприклад, перетворимо всі натуральні числа <= 10 в основу Фібоначчі.

  • 1 стане 1, оскільки це сума 1, яка є числом Фібоначчі,

  • 2 стане 10, тому що це сума 2, яка є числом Фібоначчі, і їй не потрібно 1, оскільки ми вже досягли бажаної суми.

  • 3 стане 100, тому що це сума 3, яка є числом Фібоначчі, і їй не потрібно 2 або 1, оскільки ми вже досягли бажаної суми.

  • 4 стане 101, оскільки це сума [3,1], обидва - це числа Фібоначчі.
  • 5 стане 1000, бо це сума 5, яка є числом Фібоначчі, і нам не потрібно жодне з інших чисел.
  • 6 стане 1001, оскільки це сума чисел 5 і 1 Фібоначчі.
  • 7 стане 1010, тому що це сума чисел 5 і 2 Фібоначчі.
  • 8 стане 10000, оскільки це число Фібоначчі.
  • 9 стане 10001, оскільки це сума чисел 8 і 1 Фібоначчі.
  • 10 стане 10010, оскільки це сума чисел 8 і 2 Фібоначчі.

Перетворимо випадкове базове число Фібоначчі, 10101001010 в десятковий: Спочатку запишемо відповідні числа Фібоначчі. Потім обчислюємо суму чисел під 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.

Детальніше про базові числа Фібоначчі: посилання , він також має інструмент, який перетворює звичайні цілі числа в основу Фібоначчі. Ви можете експериментувати з цим.

Тепер питання:

Ваше завдання - взяти число в представництві Зекендорфа і вивести його десяткове значення.

Введення - це рядок, що містить лише 0 і 1 (хоча ви можете взяти вхід будь-яким способом).

Виведіть одне число десятковою.

Тестові приклади: (у форматі введення-> вихід)

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

Це код-гольф, тому найкоротша відповідь у байтах виграє.

Примітка. Вхід не буде містити жодних провідних або послідовних 0.


Чи можемо ми взяти введення як список бітів?
Пост Рок-Гарф Хантер

Мовляв, візьміть кодований вхідний файл ascii, а потім перетворите його на бінарне чи щось подібне?
Windmill Cookies

4
Чи можемо ми взяти вхід у першому порядку ?
Мего


1
@Mego Так, можна
Cookie Windmill

Відповіді:


19

Таксі , 1987, 1927 байт

-60 байт через розуміння того, що розриви рядків необов’язкові.

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.

Спробуйте в Інтернеті!

Оскільки я не повертаюся до гаража таксі в кінці, мій начальник звільняє мене, тож це закінчується помилкою.


Joyless ParkЗдається, приємне місце для відвідування
aloisdg переїжджає на codidact.com

Ну, це менше символів, ніж Sunny Skies Park.
JosiahRyanW

11

Perl 6 , 28 23 байти

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

Спробуйте в Інтернеті!

Анонімний кодовий блок, який приймає список 1s і 0s в порядку замовлення LSB і повертає номер.

Пояснення:

{                     }   # 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 байт

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

Спробуйте в Інтернеті!

Вводиться як список 1 і 0.

Пояснення


f=1:scanl(+)2f

Створює список чисел Фібоначчі, не змінюючи перше f.

sum.zipWith(*)f.reverse

Бере список вхідних даних, reverseпомножує кожен запис на відповідний запис f, а потім sumрезультати.

Haskell , 30 байт

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

Спробуйте в Інтернеті!

Якщо ми спочатку беремо вхід з найменш значущим бітом, він нам не потрібен, reverseтому ми можемо зберегти 8 байт.


4

Python 2 , 43 байти

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

Спробуйте в Інтернеті!

Вводиться як список. Оновлення є коротшою версією a,b=b+x,a+b+x, яка нагадує оновлення Фібоначчі, a,b=b,a+bякщо ви ігноруєте x.


Python 2 , 45 байт

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

Спробуйте в Інтернеті!

Вводить введення у вигляді десяткових чисел.


3

Pyth, 13 байт

Більшість із цього (8 байт) просто генерує числа Фібоначчі.

s*V_m=+Z|~YZ1

Спробуйте це за допомогою цього тестового набору!

Пояснення:

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 байт

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

Спробуйте в Інтернеті!

У 24-байтовій версії гольфу було використано змішану базу для Фібоначчі.

Як це працює

#.~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 байт

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

Спробуйте в Інтернеті!

Вдосконалена версія 25-байтного рішення Галена Іванова .

Використовується діагональна сума трикутника Паскаля, що еквівалентна сумі біноміальних коефіцієнтів:

Жн=i=0нн-iСi

Як це працює

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 байти

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

Спробуйте в Інтернеті!

Монадійське явне дієслово. Створює змішану базу, яка представляє базу Фібоначчі, а потім подає на перетворення бази #..

Як це працює

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

Альтернативи

J , 27 байт

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

Спробуйте в Інтернеті!

Ідея:

 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 байт

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

Спробуйте в Інтернеті!

Цей побудував найбільше зусиль для побудови. Використовує вираз закритої форми з фокусом округлення. У виразі 0-го та 1-го значень відповідно 0 та 1, тому фактична цифрова потужність повинна починатися з 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

Хоча помилка ( ((1-sqrt(5))/2)^nумови) може наростати, вона ніколи не перевищує 0,5, тому фокус округлення працює до нескінченності. Математично:

макс(|еrrоr|)=151(1-52)2н=150(1-52)н=5-125<12


Приємне рішення! Я радий бачити явне дієслово, яке б’є мовчазне рішення.
Гален Іванов

Я намагаюся знайти коротше мовчазне рішення, але без успіху. На даний момент 25 байт . Я використовую трикутник Паскаля.
Гален Іванов

@GalenIvanov Переглядаючи випробування через рік, я отримав нове, надто коротке мовчазне рішення :)
Bubbler

Це чудово! Невдовзі я розгляну це детальніше.
Гален Іванов

2

MathGolf , 8 6 байт

{î)f*+

Спробуйте в Інтернеті!

Пояснення

{        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 байт завдяки JoKing, а ще один байт завдяки впорядкуванню LSB.


Наказ LSB дійсно дозволений. також, -1 байт
Джо Кінг

@JoKing Звичайно, я навіть застосував неявне доповнення лише минулого тижня ... Приємний дотик, зараз MathGolf - на першому місці!
maxb

2

05AB1E , 11 9 8 байт

vyiNÌÅfO

Спробуйте в Інтернеті!

Пояснення:

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 байти : Дякуємо @KevinCruijssen за вказівку невеликих способів скоротити цей код!
  • -1 байт : Дякую @JonathanAllan за вказівку порядку LSB для введення!

1
Ви можете видалити Θ. 1вже в 05AB1E. :) Також, 2+може бути Ì.
Кевін Кройсейсен

1
Ми можемо взяти вхід у формі Little-endian (тобто зворотній), який повинен зберегти байт (або два?).
Джонатан Аллан






1

C (gcc) , 63 байти

Приймає вхід як масив 1's і 0' s, а також довжину масиву. Це рішення - досить пряма назад петля.

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

Спробуйте в Інтернеті!



0

Сітківка 0,8,2 , 23 байти

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

Спробуйте в Інтернеті! Посилання включає більш швидкі тестові випадки. Пояснення:

0?
;

Вставте роздільники скрізь і видаліть нулі. Наприклад, 1001стає ;1;;;1;.

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

Неодноразово замінюйте кожне 1на а 1в кожному з наступних двох місць, оскільки сума їх значень дорівнює значенню оригіналу 1. 1s, тому мігрують та накопичуються до тих пір, поки вони не досягнуть останніх двох місць, які (завдяки щойно доданому сепаратору) тепер мають обоє значення 1.

1

Порахуйте 1с.




0

Власне , 8 байт

;r⌐@░♂FΣ

Спробуйте в Інтернеті!

Введення приймається як список бітів у першому порядку LSB.

Пояснення:

;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 байт

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

Тестовий сценарій:

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

Вихід:

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

0

Java (OpenJDK 8) , 65 байт

Дуже маленький, щоб відповісти Java, я задоволений цим. Приймає введення як спочатку впорядкований LSB масив ints.

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

Спробуйте в Інтернеті!

Безумовно

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 байти

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

Приклад із введенням 1001 - Спробуйте в Інтернеті!

Приклад із введенням 100101000 - Спробуйте в Інтернеті!

Збірка:

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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.