Бінарні Фібоначчі


31

Виклик

Вам потрібно створити програму або функцію, яка приймає додатне ціле число N, обчислює перші N членів послідовності Фібоначчі у двійковій формі, об'єднує її в одне двійкове число, перетворює це число назад у десяткове, а потім виводить десяткове у вигляді десяткового ціле число.

Наприклад

1 -> [0] -> 0 to decimal outputs 0
3 -> [0, 1, 1] -> 011 to decimal outputs 3
4 -> [0, 1, 1, 10] -> 01110 to decimal outputs 14

Вам не потрібно виводити ->, а лише число (наприклад, якщо користувач вводить 4, просто виводить 14). Стрілки - лише допомогти пояснити, що програма повинна робити.

Тестові справи

1 -> 0
2 -> 1
3 -> 3
4 -> 14
5 -> 59
6 -> 477
7 -> 7640
8 -> 122253
9 -> 3912117
10 -> 250375522
11 -> 16024033463
12 -> 2051076283353
13 -> 525075528538512
14 -> 134419335305859305
15 -> 68822699676599964537
16 -> 70474444468838363686498
17 -> 72165831136090484414974939
18 -> 147795622166713312081868676669
19 -> 605370868394857726287334099638808
20 -> 4959198153890674493745840944241119317

Програма повинна вміти виводити до межі використовуваної мови. Не дозволяються таблиці пошуку або звичайні обхідні шляхи .

Це , тому відповідь з найменшою кількістю байтів виграє!


1
Додано тестові випадки від 0 до 20 від tio.run/##DYxBCoQwDAC/… . Кредит @alephalpha за програму.
Натан Вуд

6
Як ще не було сказано: Ласкаво просимо до PPCG! Гарний перший виклик.
Лайконі

@Laikoni Дякую!
Натан Вуд

Де саме застосовується обмеження щодо мови? Чи дозволить функцію C, яка повертає 32-бітове ціле число? Як int32_t binary_concat_Fib(int n), що обмежило б отримане значення виходу на 2 ^ 31-1. тобто ви вважаєте, що всі об'єднані біти вміщуються в ціле число. Або функція повинна працювати до того моменту, коли найбільше число Фібоначчі не вкладається в ціле число самостійно, тому об'єднання бітів вимагає великої точності?
Пітер Кордес

1
І чи має бути "перетворення в десятковий" явним, викликаючи цілочисельну-> строкову функцію або записуючи її самостійно? Об'єднання бітів в одне ціле число дає уявлення про кінцеве значення. Якщо я правильно розумію, відповідь Денніса на Python повертає ціле число, залишаючи його абоненту, щоб перетворити це значення в десятковий рядок або зробити що-небудь з ним. Значення цілочисень на комп'ютерних мовах, які підтримують оператори зсуву бітів, природно є двійковими, а не десятковими, якщо вони не зберігаються в рядках. У мовах без змін / бітових операторів нічого не передбачає жодної бази.
Пітер Кордес

Відповіді:



10

Желе ,  7  6 байт

ḶÆḞBẎḄ

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

Як?

ḶÆḞBẎḄ - Link: integer, n
Ḷ      - lowered range -> [0,1,2,3,4,5,...,n]
 ÆḞ    - Fibonacci (vectorises) -> [0,1,1,2,3,5...,F(n)]
   B   - to binary (vectorises) -> [[0],[1],[1],[1,0],[1,1],[1,0,1],...,B(F(n))]
    Ẏ  - tighten -> [0,1,1,1,0,1,1,1,0,1,...,B(F(n))[0],B(F(n))[1],...]
     Ḅ - from binary -> answer

1
Заплутавшись з новими клацаннями, я виявив, що перші n числа Фібоначчі також можна знайти, використовуючи Ṛc’SƲƤякі можуть бути корисні для подібних послідовностей.
милі


7

мозковий ебать , 397 байт

>,[<++++++[->--------<]>>[->++++++++++<]>[-<+>]<<[->+<],]>+[-<<+>>[-[->+<]<<[->+>+<<]<[->+>+<<]>[-<+>]>>[-<<+>>]>]]<<[->+>>>>>+<<<<<<]>[-<+>]>+>>+>>>+<[[->-[<<]>]>[[-]<<<<<<<[->>[-<+>>+<]>[-<+>]<<<]<[->+>>>>>+<<<<<<]>[-<+>]>[-<+>]>[->>[-<+<<+>>>]<[->+<]<]>+>[-]>>+>]<<<<<[[->++>+>++<<<]>[-<+>]<<]>>>]>[-]<<<[-]<<[-]<<->[>++++++++++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>>>]<+[->++++++[-<++++++++>]<.<<<+]

Ну, це було весело!

Приймає вхід ASCII (наприклад 11), виводить результат ASCII.

Примітка. Щоб спробувати це в Інтернеті, переконайтеся, що ви встановили розмір комірки в 32 біти (праворуч на веб-сторінці). Якщо ви не введете дані, ваш браузер може вийти з ладу.

Інтерпретатор не може обробляти вхід 11і вище, оскільки він підтримує до 32 біт.

Спробуйте це на copy.sh

Пояснення

>,[<++++++[->--------<]>>[->++++++++++<]>[-<+>]<<[->+<],]>+

Отримайте десятковий ввід і додайте його (щоб пом'якшити окремо)

[-<<+>>[-[->+<]<<[->+>+<<]<[->+>+<<]>[-<+>]>>[-<<+>>]>]]

Згенеруйте числа стрічок на стрічці.

<<[->+>>>>>+<<<<<<]>[-<+>]>+>>+>>>+<

Налаштуйте цикл вхідної бінарної конкатенації


Отже, комірки містять значення, починаючи з першої позиції,

1 | 0 | 1 | 1 | 2 | 3 | 5 | ... | f_n | 0 | 1 | 0 | 1 | 0 | f_n | 1 | 0 | 0 | 0...

Подивіться на ці клітини:

f_n | 0 | 1 | 0 | 1 | 0 | f_n | 1

Я позначу це:

num | sum | cat | 0 | pow | 0 | num | pow

powє, щоб знайти максимальну потужність 2, яка суворо більша за num. sumпоки що є об'єднання чисел. catце сила 2, яку мені знадобиться би помножити на те num, щоб об'єднатися numперед sum(так що я міг би просто додати).


[[->-[<<]>]>

Петля: Перевірте, чи f_nстрого менше pow.

Truthy:

[[-]<<<<<<<[->>[-<+>>+<]>[-<+>]<<<]<[->+>>>>>+<<<<<<]>[-<+>]>[-<+>]>[->>[-<+<<+>>>]<[->+<]<]>+>[-]>>+>]

Нульовий сміття. Потім додайте num* catдо sum. Далі, завантажте наступний ряд Фібоначчі (= f_(n-1), якщо він не існує, цикл виходу) і встановити catв cat* pow. Підготуйтеся до наступного циклу (з нуля більше сміття, змістіть область на одну).

Фальсі:

<<<<<[[->++>+>++<<<]>[-<+>]<<]

Встановити pow2 * pow, відновити num.

]

Повторюйте, поки не залишиться число Фібоначчі.


>[-]<<<[-]<<[-]<<->[>++++++++++<[->-[>+>>]>[+[-<+>]>+>>]<<<<<]>>>]<+[->++++++[-<++++++++>]<.<<<+]

Чисте сміття. Візьміть кожну цифру отриманого числа і виведіть кожну (у вигляді).




4

Піт, 22 байти

JU2VQ=+Js>2J)is.BM<JQ2

Спробуйте тут

Пояснення

JU2VQ=+Js>2J)is.BM<JQ2
JU2                       Set J = [0, 1].
   VQ       )             <Input> times...
     =+Js>2J              ... add the last 2 elements of J and put that in J.
                  <JQ     Take the first <input> elements...
               .BM        ... convert each to binary...
              s           ... concatenate them...
             i       2    ... and convert back to decimal.




2

J, 36 байт

3 :'#.;<@#:"0]2}.(,{:+_2&{)^:y _1 1'

Пояснення:

3 :'#.;<@#:"0]2}.(,{:+_2&{)^:y _1 1' | Explicit function
                 (,{:+_2&{)^:y _1 1  | Make n fibonacci numbers, with _1 1 leading
              2}.                    | Drop the _1 1
       <@#:"0]                       | Convert each item to binary and box
      ;                              | Unbox and join
    #.                               | Convert back from binary

2

x86, 37 22 21 байт

Журнал змін

  • -13 за допомогою bsr. Дякую Пітеру Кордесу!
  • -2 за нульовими регістрами зmul .

  • -1, використовуючи час циклу замість loopі push/ pop ecx(кредит Peter Cordes).

Вхід edi, вихід у edx.

.section .text
.globl main
main:
        mov     $5, %edi            # n = 5

start:
        dec     %edi                # Adjust loop count
        xor     %ebx, %ebx          # b = 0
        mul     %ebx                # a = result = 0
        inc     %ebx                # b = 1

fib:
        add     %ebx, %eax          # a += b
        xchg    %eax, %ebx          # swap a,b
        bsr     %eax, %ecx          # c = (bits of a) - 1
        inc     %ecx                # c += 1
        sal     %cl, %edx           # result >>= c
        add     %eax, %edx          # result += a

        dec     %edi                # n--; do while(n)
        jnz     fib 

        ret

Objdump:

00000005 <start>:
   5:   4f                      dec    %edi
   6:   31 db                   xor    %ebx,%ebx
   8:   f7 e3                   mul    %ebx
   a:   43                      inc    %ebx

0000000b <fib>:
   b:   01 d8                   add    %ebx,%eax
   d:   93                      xchg   %eax,%ebx
   e:   0f bd c8                bsr    %eax,%ecx
  11:   41                      inc    %ecx
  12:   d3 e2                   shl    %cl,%edx
  14:   01 c2                   add    %eax,%edx
  16:   4f                      dec    %edi
  17:   75 f2                   jne    b <fib>
  19:   c3                      ret    

1
Використовуйте leaдля переключення та додавання у fib2. Крім того, витягувати кожен біт по одному не потрібно. Використовуйте bsr %eax, %ecxдля пошуку кількості бітів у двійковому поданні та використовуйте зсув на CL / або для злиття, як це робить відповідь Dennis's Python.
Пітер Кордес

1
Вам потрібні clпідрахунки змін, тому візьміть свій лічильник циклу в інший регістр (як %edi) і використовуйте dec %edi / jnz(3 байти в 32-бітовому коді, 4 байти в 64-бітовому). У 32-розрядному коді це дозволяє економити 1 байт від падіння ec / push ecx. Не потрапляйте в пастку використання, loopколи це ускладнює проблему, а не простіше. (Угода про дзвінки вже призначена для користувача, клобірування %ebx, тому не дзвоніть на свою функцію main) Можливо, ви зможете повернутися в EAX, використовуючи ще один байт xchg, не потрібно бути нестандартним, якщо цього не потрібно.
Пітер Кордес

1
Ви можете замінити додатковий inc %ecxрахунок зміни на додатковий лівий зсув у міру додавання, використовуючи lea (%eax, %edx, 2), %edx. Нейтральний в байтах для 32-бітних, економить один для x86-64. Але зберігає інструкцію.
Пітер Кордес

1
Кожен раз, коли я закінчую використовувати loopв коді гольф, я відчуваю себе брудним. Ну не зовсім, але розчарований, що я не зміг знайти однаково малу реалізацію, яка б уникнула цієї повільної інструкції; поза кодом гольфу, loopє одним із моїх вихованців . Я б хотів, щоб це було швидко на сучасних процесорах, оскільки це було б дуже приємно для циклів з підвищеною точністю без парціальних прапорців, але це не так і слід розглядати лише як незрозумілу інструкцію щодо оптимізації розмірів, яка робить ваш код повільним.
Пітер Кордес

1
У будь-якому випадку, приємна робота. За винятком push / pop / loop -> dec / jnz, я не бачу жодної економії, лише прискорення LEA, яке нейтральне за розміром коду. Мені завжди було цікаво, чи існував колись справжній випадок використання xor/ mulтрюк до нуля трьох регістрів (чи вам коли-небудь знадобиться стільки нулів?), Але використання цього як частини створення матриці 1робить це більш розумним.
Пітер Кордес


2

Haskell , 89 76 75 байт

f=0:scanl(+)1f
foldr1(\x y->y+x*2*2^floor(logBase 2.read.show$y)).(`take`f)

Безгольова версія:

import Data.Bits

fib = 0:scanl (+) 1 fib

catInt :: Integer -> Integer -> Integer
catInt x y = x' + y where
    position = floor $ succ $ logBase 2 $ realToFrac y
    x' = shift x position

answer :: Integer -> Integer
answer n = foldr1 catInt fib' where
    fib' = take n fib

1
Ласкаво просимо в гольф PPCG та Haskell зокрема! Коротший спосіб створення нескінченного списку чисел Фібоначчі f=0:scanl(+)1f(взято звідси ). Функції можуть бути анонімними, тому ви можете скинути провідні g=, дивіться наш Керівництво з правил гогольфінгу в Haskell .
Лайконі

Спасибі! Це компенсує деякі довші функції, що використовуються. Я витратив деякий час, намагаючись знайти спосіб здійснити зміну бітів більш стислим способом, але прийшов недовго.
користувач9549915

Ви можете замінити $realToFrac yз .read.show$yодного байта
H.PWiz


1

APL + WIN, 55 байт

Підказки для екранного введення цілого числа.

v←b←0 1⋄⍎∊(⎕-2)⍴⊂'v←v,c←+/¯2↑v⋄b←b,((1+⌊2⍟c)⍴2)⊤c⋄'⋄2⊥b

Максимальна ціла точність APL + WIN - 17, а граничне число - порядка 10E300, тому максимальне вхідне число 55, а результат: 1.2492739026634838E300



1

Желе , 6 байт

ḶÆḞBFḄ

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

owered діапазон -> п - й ÆḞibonacci номер -> від дес до BІнарі -> Flatten -> від Інарі в десяткову


Я не розумів цю мову, але я вважав, що вихід не завжди є правильним. наприклад, "Введення", 10і ви отримаєте 16024033463, це неправильно (правильна відповідь 250375522).
Гоян Цинь



1

MATL , 21 байт

0li:"yy+]xx&h"@B]&hXB

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

Пояснення

0l        % Push 0, then 1 (initial terms of the Fibonacci sequence)
i:"       % Do n times, where n is the input
  yy+     %   Duplicate top two numbers and push their sum
  ]       % End
xx        % Delete the last two results. The stack now contains the
          % first n Fibonacci numbers, starting at 0
&h        % Concatenate all numbers into a row vector
"         % For each
  @       %   Push current number
  B       %   Convert to binary. Gives a vector of 0 and 1
]         % End
&h        % Concatenate all vectors into a row vector
XB        % Convert from binary to decimal. Implicitly display

1

J , 25 байт

2(#.;)<@#:@(1#.<:!|.)\@i.

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

Пояснення

2(#.;)<@#:@(1#.<:!|.)\@i.  Input: n
                       i.  Range [0, n)
                     \@    For each prefix
                  |.         Reverse
                 !           Binomial coefficient (vectorized)
               <:            Decrement
            1#.              Sum
        #:                   Convert to binary
      <                      Box
    ;                        Link. Join the contents in each box
2 #.                         Convert to decimal from base 2



1

PHP, 124 байти

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

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

Я вважав підхід "округлення" дійсно цікавим, також професор показав мені це деякий час тому.

Код

function f($n,$i=0,$b=''){ if($n>$i){$b.=
decbin(round(pow((sqrt(5)+1)/2,$i)/sqrt(5)));f($n,$i+1,$b);}else{echo bindec($b);}}

Пояснення

function f($n,$i=0,$b=''){           #the function starts with $i=0, our nth-fib number
if($n>$i){                           #it stops once $n (the input) = the nth-fib
    $b.=decbin(                      #decbin returns an integer as bin, concatenates
        round(pow((sqrt(5)+1)/2,$i)/sqrt(5))    
                                       #the formula, basically roundign the expression
        );                           #it returns the (in this case) $i-th fib-number   
    f($n,$i+1,$b);                   #function is called again for the next index
}else{                               #and the current string for fibonacci

    echo bindec($b);                 #"echo" the result, bindec returns the base 10
                                     #value of a base 2 number
}
}

Також перевірте цей пост stackoverflow про найкраща відповідь стосується тієї ж статті у Вікіпедії.


Цікавий спосіб це зробити!
Натан Вуд



1

Піт, 27 байт

JU2V-Q2=aJ+eJ@J_2)is.BM<JQ2

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

Переклад Python 3:
Q=eval(input())
J=list(range(2))
for i in range(Q-2):
    J.append(J[-1]+J[-2])
print(int(''.join(map("{0:b}".format,J[:Q])),2))

37 байт

J[Z1)W<lJQ=aJ+eJ@J_2)Ig1QZ.?ijkm.BdJ2

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

Переклад Python 3:
Q=eval(input())
J=[0,1]
while len(J)<Q:
    J.append(J[-1]+J[-2])
if 1>=Q:
    print(0)
else:
    print(int(''.join(map("{0:b}".format,J)),2))



0

Джотлін , 59 байт

g(l(0,1)){l(a.sum(),a[0])}.take(this).j(""){a[0].s(2)}.i(2)

Тестова програма

data class Test(val input: Int, val output: Long)

val tests = listOf(
    Test(1, 0),
    Test(2, 1),
    Test(3, 3),
    Test(4, 14),
    Test(5, 59),
    Test(6, 477),
    Test(7, 7640),
    Test(8, 122253),
    Test(9, 3912117),
    Test(10, 250375522)
)
fun Int.r() = g(l(0,1)){l(a.sum(),a[0])}.take(this).j(""){a[0].s(2)}.i(2)

fun main(args: Array<String>) {
    for (r in tests) {
        println("${r.input.r()} vs ${r.output}")
    }
}

Він підтримує до 10, зміна .i(2)на .toLong(2)підтримує до 14, якщо потрібно


0

Python 2, 88 байт

def f(n):
 a,b,r=0,1,"0"
 for _ in range(n-1):a,b=b,a+b;r+=bin(a)[2:]
 print int(r,2)

0

R , 244 180 179 байт

i=ifelse;g=function(n)i(n<3,1,g(n-1)+g(n-2))
a=scan(,"");i(a==1,0,sum(2^(which(rev(unlist(sapply(g(2:a-1),function(x)(y=rev(as.numeric(intToBits(x))))[which(!!y)[1]:32]))>0))-1)))

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

Збережено кілька байт шляхом об'єднання числових векторів, а не рядків. Кривавий особливий випадок за 0!


Функції прийнятні. Крім того, набагато ефективніше зрушити результат, залишений на кількість бітів, а потім перейнятися числовими векторами. Дивіться мою відповідь пітона або Денніса. Це має додаткову перевагу в обробці справи 0.
qwr

codegolf.stackexchange.com/questions/4024/tips-for-golfing-in-r R гольф для мене занадто багато: /
qwr

@qwr Відповідь - це не функція; Я створюю функцію помічника, тому що вона повинна бути sapply'd до вектора через те, що вона є рекурсивною. Це не може бути все загорнуте в один рядок. Як бачите, програма вимагає ввести інформацію користувача, а потім повертає відповідь. Один байт можна зберегти, створивши ярлик для ifelse. І ... ми можемо видалити ,""з scan, так.
Андрей Костирка
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.