Binary to decimal converter

Jelly, 5 bytes

DḤ+¥/

Try it online!

Explanation

enter image description here

The cast

  • D is a monad (single argument function): digits, turning 1234 into [1, 2, 3, 4].

  • is a monad that doubles its single argument.

  • + is a dyad (two argument function) that adds its left and right arguments.

From there, it gets a little tricky.

Here’s what happens at parse time

  • D, , and + are read. The chain looks like [D, Ḥ, +].

  • The next two characters are quicks, which act like parse-time postfix operators on the links (functions) we've read so far.

  • When ¥ is read, the last two links get popped and replaced by a link that acts like the dyad formed by composing them. So now the chain looks like [D, dyad(Ḥ+)].

  • When / is read, the last link (which ought to be a dyad) gets popped and replaced by a monad that folds using this dyad (intuitively: f/ takes a list, replaces the commas in it with f, and evaluates the result.)

  • The final chain looks like [D, fold(dyad(Ḥ+))], two monads.

Here's what happens at run time

  • Input (a number) is implicitly read into the working value (say, 101010).

  • D is executed, replacing the working value with its digits ([1,0,1,0,1,0]).

  • fold(dyad(Ḥ+)) is executed, replacing the working value with 1∗0∗1∗0∗1∗0, where is the dyad Ḥ+.

So what does x∗y evaluate to?

  • In a dyadic definition, the working value is initially the left argument, x.

  • , the double monad, doubles this value. The working value is now 2x.

  • +, the plus dyad, lacks a right argument, so this is a hook: a special syntactical pattern where the right argument of this dyad gets injected into +. This yields 2x + y as the final working value, which is returned.

So the whole expression evaluates to:

1∗0∗1∗0∗1∗0 = 2×(2×(2×(2×(2×1+0)+1)+0)+1)+0
            = 32×1 + 16×0 + 8×1 + 4×0 + 2×1 + 1×0
            = 42

Python 2, 49 37 31 30 Bytes

Now this will take a binary number in a decimal representation, since Python can handle arbitrarily large integers.

b=lambda n:n and n%2+2*b(n/10)

thanks to xnor for saving a byte :)

The easiest way to see how this works is by seeing a basic formula for converting binary to decimal:

= 101010 
= 1*(2^5) + 0*(2^4) + 1*(2^3) + 0*(2^2) + 1*(2^1) + 0*(2^0)
= 1*32 + 0*16 + 1*8 + 0*4 + 1*2 + 0*1
= 42

This is a 'standard' way of converting. You can expand the third line like so:

= ((((1*2 + 0)*2 + 1)*2 + 0)*2 + 1)*2 + 0

And this is essentially what the recursive method I've made is doing.

Alternate solutions I had:

b=lambda n:n and n%10+2*b(n/10)
b=lambda n:n%10+2*(n and b(n/10))
b=lambda n:0if n<1else n%10+2*b(n/10)
b=lambda n:0**(n/10)or n%10+2*b(n/10)
b=lambda n,o=0:o*(n<'0')or b(n[1:],2*o+int(n[0]))
lambda j:sum(int(b)*2**a for a,b in enumerate(j,1))

05AB1E, 6 bytes

Code:

$¦v·y+

For the explantion, let's take the example 101010. We start with the number 1 (which is represented by the first digit). After that, we have two cases:

  • If the digit is a 0, multiply the number by 2.
  • If the digit is a 1, multiply the number by 2 and add 1.

So for the 101010 case, the following is calculated:

  • 101010, start with the number 1.
  • 101010, multiply by two, resulting into 2.
  • 101010, multiply by two and add one, resulting into 5.
  • 101010, multiply by two, resulting into 10.
  • 101010, multiply by two and add one, resulting into 21.
  • 101010, multiply by two, resulting into 42, which is the desired result.

Code explanation:

$         # Push 1 and input
 ¦        # Remove the first character
  v       # For each character (starting with the first)
   ·      #   Multiply the carry number by two
    y+    #   Add the current character (converted automatically to a number)

Uses the CP-1252 encoding. Try it online!