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

# ChristianTovar's solution

## to Hexadecimal in the Elixir Track

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

Convert a hexadecimal number, represented as a string (e.g. "10af8c"), to its decimal equivalent using first principles (i.e. no, you may not use built-in or external libraries to accomplish the conversion).

On the web we use hexadecimal to represent colors, e.g. green: 008000, teal: 008080, navy: 000080).

The program should handle invalid hexadecimal strings.

## 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/examples/NumberBases.html

## Submitting Incomplete Solutions

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

``````defmodule HexadecimalTest do
use ExUnit.Case

test "returns 1 when hex is 1" do
end

@tag :pending
test "returns 12 when hex is c" do
end

@tag :pending
test "hexadecimal is case insensitive" do
end

@tag :pending
test "returns 16 when hex is 10" do
end

@tag :pending
test "returns 175 when hex is af" do
end

@tag :pending
test "returns 256 when hex is 100" do
end

@tag :pending
test "returns 105_166 when hex is 19ace" do
end

@tag :pending
test "returns 0 when hex is invalid" do
end

@tag :pending
test "returns 0 when hex represents black" do
end

@tag :pending
test "returns 16_777_215 when hex represents white" do
end

@tag :pending
test "returns 16_776_960 when hex represents yellow" do
end
end``````

### test_helper.exs

``````ExUnit.start()
ExUnit.configure(exclude: :pending, trace: true)``````
``````defmodule Hexadecimal do
@doc """
Accept a string representing a hexadecimal value and returns the
corresponding decimal value.
It returns the integer 0 if the hexadecimal is invalid.
Otherwise returns an integer representing the decimal value.

## Examples

0

175

"""

@spec to_decimal(binary) :: integer
def to_decimal(hex) do
case valid_hex?(hex) do
true -> get_decimal(hex)
false -> 0
end
end

defp valid_hex?(hex), do: hex =~ ~r/^[0-9a-fA-F]+\$/

defp get_decimal(hex) do
size = String.length(hex) - 1

hex
|> String.graphemes()
|> Enum.zip(size..0)
|> Enum.reduce(0, fn {letter, position}, acc -> acc + get_value(letter, position) end)
end

defp get_value(letter, position) when letter in ["a", "A"], do: 10 * :math.pow(16, position)
defp get_value(letter, position) when letter in ["b", "B"], do: 11 * :math.pow(16, position)
defp get_value(letter, position) when letter in ["c", "C"], do: 12 * :math.pow(16, position)
defp get_value(letter, position) when letter in ["d", "D"], do: 13 * :math.pow(16, position)
defp get_value(letter, position) when letter in ["e", "E"], do: 14 * :math.pow(16, position)
defp get_value(letter, position) when letter in ["f", "F"], do: 15 * :math.pow(16, position)
defp get_value(number, position), do: String.to_integer(number) * :math.pow(16, position)
end``````