बाइनरी फाइबोनैचि


31

चुनौती

आपको एक प्रोग्राम या फ़ंक्शन उत्पन्न करने की आवश्यकता है जो एक सकारात्मक पूर्णांक एन में लेता है, द्विआधारी में फाइबोनैचि अनुक्रम के पहले एन शब्दों की गणना करता है, इसे एक एकल बाइनरी नंबर में जोड़ता है, उस संख्या को दशमलव में वापस परिवर्तित करता है, और फिर दशमलव को दशमलव के रूप में आउटपुट करता है पूर्णांक।

उदाहरण के लिए

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
Tio.run/##DYxBCoQwDAC/… से 0 से 20 तक जोड़ा गया परीक्षण मामले । कार्यक्रम के लिए @alephalpha को श्रेय।
नाथन वुड

6
जैसा कि यह अभी तक नहीं कहा गया है: PPCG में आपका स्वागत है! अच्छी पहली चुनौती।
लकोनी

@ लायकोनी धन्यवाद!
नाथन वुड

वास्तव में भाषा-विशिष्ट सीमा कहां लागू होती है? एक 32-बिट पूर्णांक रिटर्न करने वाले C फ़ंक्शन को अनुमति दी जाएगी? जैसे int32_t binary_concat_Fib(int n), परिणामी आउटपुट मान को 2 ^ 31-1 तक सीमित कर देगा। यानी आप मान लेते हैं कि सभी समतुल्य बिट्स पूर्णांक में फिट होते हैं। या फ़ंक्शन को उस बिंदु तक काम करना चाहिए जहां सबसे बड़ा फाइबोनैचि संख्या अपने आप में एक पूर्णांक में फिट नहीं होती है, इसलिए बिट्स को समेटना विस्तारित परिशुद्धता लेता है?
पीटर कॉर्डेस

1
और क्या "दशमलव में धर्मान्तरित" को स्पष्ट होना है, पूर्णांक कॉल करना -> स्ट्रिंग फ़ंक्शन या एक स्वयं लिखना? बिट्स को एक पूर्णांक में समेटना आपको अंतिम मूल्य का प्रतिनिधित्व देता है। अगर मैं सही तरीके से समझ पाऊं, तो डेनिस का पाइथन उत्तर पूर्णांक लौटा रहा है, जो कॉलर को एक दशमलव स्ट्रिंग में बदलने या इसके साथ जो कुछ भी करता है, उसे छोड़ देता है। जब तक वे स्ट्रिंग्स में संग्रहीत नहीं होते हैं, बिट-शिफ्ट ऑपरेटरों का समर्थन करने वाले कंप्यूटर भाषाओं में पूर्णांक स्वाभाविक रूप से बाइनरी होते हैं, दशमलव नहीं। शिफ्ट / बिटवाइज़ ऑपरेटरों के बिना भाषाओं में, किसी भी आधार का अर्थ नहीं है।
पीटर कॉर्डेस

जवाबों:



10

Jelly,  7  6 bytes

ḶÆḞBẎḄ

Try it online!

How?

ḶÆḞ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
Messing around with the new quicks, I found that the first n Fibonacci numbers can also be found using Ṛc’SƲƤ which could be useful for similar sequences.
miles


7

brainfuck, 397 bytes

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

Well, that was fun!

Takes ASCII input (e.g. 11), outputs result in ASCII.

Note: to try this online, make sure you set the cell size to 32 bits (on the right side of the webpage). If you do not enter an input, your browser might crash.

The interpreter cannot handle input of 11 and higher because it only supports up to 32 bits.

Try it on copy.sh

Explanation

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

Get decimal input and add one (to mitigate off-by-one)

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

Generate fibonacci numbers on the tape.

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

Set up for the incoming binary concatenation loop


So the cells contain the value, starting from the first position,

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

Look at these cells:

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

I'll label this:

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

pow is there to find the maximal power of 2 that is strictly greater than num. sum is the concatenation of numbers so far. cat is the power of 2 that I would need to multiply the num in order to concatenate num in front of the sum (so I would be able to simply add).


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

Loop: Check whether f_n is strictly less than pow.

Truthy:

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

Zero out junk. Then, add num * cat to sum. Next, load the next Fibonacci number (= f_(n-1); if it doesn't exist, exit loop) and set cat to cat * pow. Prepare for next loop (zero out more junk, shift scope by one).

Falsey:

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

Set pow to 2 * pow, restore num.

]

Repeat until there is no Fibonacci number left.


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

Clean garbage. Take each digit of the resulting number and output each (in ascii).


7

Husk, 7 bytes

ḋṁḋ↑Θİf

Try it online!

Explanation

ḋṁḋ↑Θİf                              4
     İf    The Fibonacci numbers     [1,1,2,3,5,8..]
    Θ      Prepends 0                [0,1,1,2,3,5..]
   ↑     Take n elements from list   [0,1,1,2]
  ḋ        Convert to binary digits  [[0],[1],[1],[1,0]]
 ṁ       Map function then concat    [0,1,1,1,0]
ḋ        Convert from base 2         14

Welcome to PPCG! :)
DJMcMayhem

5

Japt, 9 bytes

ÆMgX ¤Ã¬Í

Run it

Explanation:

ÆMgX ¤Ã¬Í
Æ     Ã     | Iterate X through the range [0...Input]
 MgX        |   Xth Fibonacci number
     ¤      |   Binary
       ¬    | Join into a string
        Í   | Convert into a base-2 number

1
Bah! Beat me to it!
Shaggy

1
@Shaggy I knew this one was going to be a race against you :P
Oliver

4

Pyth, 22 bytes

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

Try it here

Explanation

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 Bytes

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

Explanation:

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 bytes

Changelog

  • -13 by using bsr. Thanks Peter Cordes!
  • -2 by zeroing registers with mul.

  • -1 by using a while loop instead of loop and push/pop ecx (credit Peter Cordes).

Input in edi, output in 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
Use lea to shift-and-add in fib2. Also, extracting each bit one at a time is unnecessary. Use bsr %eax, %ecx to find the number of bits in the binary representation, and use a shift by CL / or to merge, like Dennis's Python answer is doing.
Peter Cordes

1
You need cl for shift counts, so take your loop counter in a different reg (like %edi) and use dec %edi / jnz (3 bytes in 32-bit code, 4 bytes in 64-bit). In 32-bit code, that saves 1 byte total from dropping the push/pop ecx. Don't fall into the trap of using loop when it makes the problem harder, not easier. (Your calling convention is already custom, clobbering %ebx, so don't call your function main) You might be able to return in EAX while still taking advantage of 1-byte xchg, no need to be non-standard if you don't need to.
Peter Cordes

1
You can replace the extra inc %ecx of the shift count with an extra left-shift as you add, using lea (%eax, %edx, 2), %edx. Neutral in bytes for 32-bit, saves one for x86-64. But saves an instruction.
Peter Cordes

1
Every time I end up using loop in code golf, I feel dirty. Well not quite, but disappointed that I couldn't find an equally small implementation that avoided that slow instruction; outside of code golf, loop is one of my pet peeves. I wish it was fast on modern CPUs, because it would be very nice for extended-precision loops without partial-flag stalls, but it's not and should be considered only as an obscure size optimization instruction that makes your code slow.
Peter Cordes

1
Anyway, nice job. Other than push/pop/loop -> dec/jnz, I don't see any savings, just the LEA speedup that's neutral in code-size. I'd always wondered if there was ever a real use case for the xor/mul trick to zero three registers (do you ever need that many zeroes?), but using that as part of creating a 1 makes it more sensible.
Peter Cordes


2

Haskell, 89 76 75 bytes

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

Ungolfed version:

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
Welcome to PPCG and Haskell golfing in particular! A shorter way to generate an infinite list of Fibonacci numbers is f=0:scanl(+)1f (taken from here). Functions can be anonymous, so you can drop the leading g=, see our Guide to Ggolfing Rules in Haskell.
Laikoni

Thanks! That compensates for some of the longer functions used. I spent a while trying to find a way to implement bit-shifting in a more concise way, but came up short.
user9549915

You can replace $realToFrac y with .read.show$y for one byte
H.PWiz


1

APL+WIN, 55 bytes

Prompts for screen input of integer.

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

APL+WIN's maximum integer precision is 17 and integer limit is of the order of 10E300 therefore the maximum input number is 55 and the result is: 1.2492739026634838E300




1

MATL, 21 bytes

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

Try it online!

Explanation

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 bytes

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

Try it online!

Explanation

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 Bytes

Try it online!

So I was looking for a way to output fibonacci numbers using the series, until I found this. It turns out you can calculate the fibonacci series via rounding, so I tried the challenge with a recursive function.

I found the approach of "rounding" really interesting, also a professor showed me this a while ago.

Code

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);}}

Explanation

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

Also check this stackoverflow post the best answer refers to the same article on Wikipedia.


Interesting way to do it!
Nathan Wood

1

Stax, 9 bytes

ü1∞╓♪εw≤+

Run and debug it at staxlang.xyz!

Unpacked (10 bytes) and explanation:

vr{|5|Bm|B
v             Decrement integer from input. Stax's Fibonacci sequence starts with 1 :(
 r            Integer range [0..n).
  {    m      Map a block over each value in an array.
   |5           Push nth Fibonacci number.
     |B         Convert to binary.
        |B    Implicit concatenate. Convert from binary. Implicit print.


1

Pyth, 27 bytes

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

Test suite

Python 3 translation:
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 bytes

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

Test suite

Python 3 translation:
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

Jotlin, 59 bytes

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

Test Program

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

It supports up to 10, changing .i(2) for .toLong(2) would support up to 14 if needed


0

Python 2, 88 bytes

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 bytes

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)))

Try it online!

Saved some bytes by concatenating numeric vectors, not strings. Bloody special case for 0!


Functions are acceptable. Also it is much more efficient to shift the result left by the number of bits then to bother with numeric vectors. See my or Dennis's python answer. This has the added benefit of handling the 0 case.
qwr


@qwr The answer is not a function; I am creating a helper function because it must be sapply’d to a vector due to the fact that it is recursive. It cannot be all wrapped into one line. As you see, the programme prompts for user’s input and then returns the answer. One byte can be saved by creating a shortcut for ifelse. And... we can remove ,"" from scan, yes.
Andreï Kostyrka
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.