ðŸŽ‰ Exercism Research is now launched. Help Exercism, help science and have some fun at research.exercism.io ðŸŽ‰

## to Binary in the Elixir Track

Published at Aug 03 2019 · 0 comments
Instructions
Test suite
Solution

#### Note:

This exercise has changed since this solution was written.

Convert a binary number, represented as a string (e.g. '101010'), to its decimal equivalent using first principles.

Implement binary to decimal conversion. Given a binary input string, your program should produce a decimal output. The program should handle invalid inputs.

## Note

• Implement the conversion yourself. Do not use something else to perform the conversion for you.

Decimal is a base-10 system.

A number 23 in base 10 notation can be understood as a linear combination of powers of 10:

• The rightmost digit gets multiplied by 10^0 = 1
• The next number gets multiplied by 10^1 = 10
• ...
• The nth number gets multiplied by 10^(n-1).
• All these values are summed.

So: `23 => 2*10^1 + 3*10^0 => 2*10 + 3*1 = 23 base 10`

Binary is similar, but uses powers of 2 rather than powers of 10.

So: `101 => 1*2^2 + 0*2^1 + 1*2^0 => 1*4 + 0*2 + 1*1 => 4 + 1 => 5 base 10`.

## Running tests

Execute the tests with:

``````\$ mix test
``````

### Pending tests

In the test suites, all but the first test have been skipped.

Once you get a test passing, you can unskip the next one by commenting out the relevant `@tag :pending` with a `#` symbol.

For example:

``````# @tag :pending
test "shouting" do
assert Bob.hey("WATCH OUT!") == "Whoa, chill out!"
end
``````

Or, you can enable all the tests by commenting out the `ExUnit.configure` line in the test suite.

``````# ExUnit.configure exclude: :pending, trace: true
``````

If you're stuck on something, it may help to look at some of the available resources out there where answers might be found.

## Source

All of Computer Science http://www.wolframalpha.com/input/?i=binary&a=*C.binary-_*MathWorld-

## Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

### binary_test.exs

``````defmodule BinaryTest do
use ExUnit.Case

# @tag :pending
test "binary 1 is decimal 1" do
assert Binary.to_decimal("1") == 1
end

@tag :pending
test "binary 10 is decimal 2" do
assert Binary.to_decimal("10") == 2
end

@tag :pending
test "binary 11 is decimal 3" do
assert Binary.to_decimal("11") == 3
end

@tag :pending
test "binary 100 is decimal 4" do
assert Binary.to_decimal("100") == 4
end

@tag :pending
test "binary 1001 is decimal 9" do
assert Binary.to_decimal("1001") == 9
end

@tag :pending
test "binary 11010 is decimal 26" do
assert Binary.to_decimal("11010") == 26
end

@tag :pending
test "binary 10001101000 is decimal 1128" do
assert Binary.to_decimal("10001101000") == 1128
end

@tag :pending
test "invalid binary is decimal 0" do
assert Binary.to_decimal("carrot") == 0
end

@tag :pending
test "invalid binary is decimal 0 II" do
assert Binary.to_decimal("convert01") == 0
end

@tag :pending
test "invalid binary is decimal 0 III" do
assert Binary.to_decimal("10convert") == 0
end

@tag :pending
test "invalid binary is decimal 0 IV" do
assert Binary.to_decimal("1carrot0") == 0
end

@tag :pending
test "22 is not a binary number" do
assert Binary.to_decimal("22") == 0
end
end``````

### test_helper.exs

``````ExUnit.start()
ExUnit.configure(exclude: :pending, trace: true)``````
``````defmodule Binary do
require Logger
@doc """
Convert a string containing a binary number to an integer.

On errors returns 0.
"""
@spec to_decimal(String.t()) :: non_neg_integer
def to_decimal(string) do
case is_valid_binary?(string) do
false -> 0
true -> convert_to_decimal(string)
end

end

defp convert_to_decimal(string) do
{converted_number, _} = String.codepoints(string)
|> Enum.reverse
|> Enum.reduce({0, 0}, fn place_value, acc_result ->
{decimal_number, count} = acc_result
{decimal_number + (String.to_integer(place_value) * pow(2, count)), count + 1}
end)
converted_number;
end

def pow(num, power, result \\ 1)
def pow(_num, 0, result), do: result
def pow(num, power, result), do: pow(num, power - 1, num * result)

def is_valid_binary?(binary_string) do
String.codepoints(binary_string)
|> Enum.all?(fn binary ->
binary === "1" or binary === "0"
end)
end
end``````
{"found_math": false, "script_math_tex": 0, "script_math_asciimath": 0, "math_annotations": 0, "math_alttext": 0, "mathml": 0, "mathjax_tag": 0, "mathjax_inline_tex": 0, "mathjax_display_tex": 0, "mathjax_asciimath": 0, "img_math": 0, "codecogs_latex": 0, "wp_latex": 0, "mimetex.cgi": 0, "/images/math/codecogs": 0, "mathtex.cgi": 0, "katex": 0, "math-container": 0, "wp-katex-eq": 0, "align": 0, "equation": 0, "x-ck12": 0, "texerror": 0}