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

# michaelkpfeifer'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
@digits_map %{
"0" => 0,
"1" => 1,
"2" => 2,
"3" => 3,
"4" => 4,
"5" => 5,
"6" => 6,
"7" => 7,
"8" => 8,
"9" => 9,
"a" => 10,
"b" => 11,
"c" => 12,
"d" => 13,
"e" => 14,
"f" => 15
}

@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
hex
|> String.downcase()
|> String.graphemes()
|> Enum.reverse()
|> Enum.reduce_while({0, 1}, &process_digit/2)
|> elem(0)
end

defp process_digit(digit, {sum, power}) do
case Map.fetch(@digits_map, digit) do
{:ok, value} ->
{:cont, {sum + power * value, power * 16}}

:error ->
{:halt, {0, 0}}
end
end
end``````