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

# konni2018's solution

## to All Your Base in the Elixir Track

Published at May 27 2020 · 0 comments
Instructions
Test suite
Solution

Convert a number, represented as a sequence of digits in one base, to any other base.

Implement general base conversion. Given a number in base a, represented as a sequence of digits, convert it to base b.

## Note

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

In positional notation, a number in base b can be understood as a linear combination of powers of b.

The number 42, in base 10, means:

(4 * 10^1) + (2 * 10^0)

The number 101010, in base 2, means:

(1 * 2^5) + (0 * 2^4) + (1 * 2^3) + (0 * 2^2) + (1 * 2^1) + (0 * 2^0)

The number 1120, in base 3, means:

(1 * 3^3) + (1 * 3^2) + (2 * 3^1) + (0 * 3^0)

I think you got the idea!

Yes. Those three numbers above are exactly the same. Congratulations!

## 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.

## Submitting Incomplete Solutions

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

### all_your_base_test.exs

``````defmodule AllYourBaseTest do
use ExUnit.Case

test "convert single bit one to decimal" do
assert AllYourBase.convert([1], 2, 10) == [1]
end

@tag :pending
test "convert binary to single decimal" do
assert AllYourBase.convert([1, 0, 1], 2, 10) == [5]
end

@tag :pending
test "convert single decimal to binary" do
assert AllYourBase.convert([5], 10, 2) == [1, 0, 1]
end

@tag :pending
test "convert binary to multiple decimal" do
assert AllYourBase.convert([1, 0, 1, 0, 1, 0], 2, 10) == [4, 2]
end

@tag :pending
test "convert decimal to binary" do
assert AllYourBase.convert([4, 2], 10, 2) == [1, 0, 1, 0, 1, 0]
end

@tag :pending
test "convert trinary to hexadecimal" do
assert AllYourBase.convert([1, 1, 2, 0], 3, 16) == [2, 10]
end

@tag :pending
test "convert hexadecimal to trinary" do
assert AllYourBase.convert([2, 10], 16, 3) == [1, 1, 2, 0]
end

@tag :pending
test "convert 15-bit integer" do
assert AllYourBase.convert([3, 46, 60], 97, 73) == [6, 10, 45]
end

@tag :pending
test "convert empty list" do
assert AllYourBase.convert([], 2, 10) == nil
end

@tag :pending
test "convert single zero" do
assert AllYourBase.convert([0], 10, 2) == [0]
end

@tag :pending
test "convert multiple zeros" do
assert AllYourBase.convert([0, 0, 0], 10, 2) == [0]
end

@tag :pending
assert AllYourBase.convert([0, 6, 0], 7, 10) == [4, 2]
end

@tag :pending
test "convert first base is one" do
assert AllYourBase.convert([0], 1, 10) == nil
end

@tag :pending
test "convert first base is zero" do
assert AllYourBase.convert([], 0, 10) == nil
end

@tag :pending
test "convert first base is negative" do
assert AllYourBase.convert([1], -2, 10) == nil
end

@tag :pending
test "convert negative digit" do
assert AllYourBase.convert([1, -1, 1, 0, 1, 0], 2, 10) == nil
end

@tag :pending
test "convert invalid positive digit" do
assert AllYourBase.convert([1, 2, 1, 0, 1, 0], 2, 10) == nil
end

@tag :pending
test "convert second base is one" do
assert AllYourBase.convert([1, 0, 1, 0, 1, 0], 2, 1) == nil
end

@tag :pending
test "convert second base is zero" do
assert AllYourBase.convert([7], 10, 0) == nil
end

@tag :pending
test "convert second base is negative" do
assert AllYourBase.convert([1], 2, -7) == nil
end

@tag :pending
test "convert both bases are negative" do
assert AllYourBase.convert([1], -2, -7) == nil
end
end``````

### test_helper.exs

``````ExUnit.start()
ExUnit.configure(exclude: :pending, trace: true)``````
``````defmodule AllYourBase do
@doc """
Given a number in base a, represented as a sequence of digits, converts it to base b,
or returns nil if either of the bases are less than 2
"""

@spec convert(list, integer, integer) :: list
def convert(_, base_a, base_b) when base_a < 2 or base_b < 2, do: nil
def convert([], _, _), do: nil

def convert(digits, base_a, base_b) do
digits
|> to_decimal(base_a, 0)
|> decimal_to(base_b)
end

defp to_decimal([], _, acc), do: acc
defp to_decimal([head | tail], base, acc), do: to_decimal(tail, base, acc * base + head)

defp decimal_to(number, base, digits \\ [])
defp decimal_to(nil, _, _), do: nil
defp decimal_to(number, base, digits) when number < base, do: [rem(number, base) | digits]

defp decimal_to(number, base, digits) do
decimal_to(div(number, base), base, [rem(number, base) | digits])
end
end``````