 # rootulp's solution

## to Hexadecimal in the Java Track

Published at Jul 13 2018 · 4 comments
Instructions
Test suite
Solution

#### Note:

This solution was written on an old version of Exercism. The tests below might not correspond to the solution code, and the exercise may have changed since this code was written.

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 the tests

You can run all the tests for an exercise by entering

``````\$ gradle test
``````

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

``````import org.junit.Test;
import org.junit.Ignore;
import static org.junit.Assert.assertEquals;

@Test
public void testOne(){
int expected = 1;
}

@Ignore
@Test
public void testC(){
int expected = 12;
}

@Ignore
@Test
public void test10(){
int expected = 16;
}

@Ignore
@Test
public void testAf(){
int expected = 175;
}

@Ignore
@Test
public void test100(){
int expected = 256;
}

@Ignore
@Test
public void test19ace(){
int expected = 105166;
}

@Ignore
@Test
public void testInvalid(){
int expected = 0;
}

@Ignore
@Test
public void testBlack(){
int expected = 0;
}

@Ignore
@Test
public void testWhite(){
int expected = 16777215;
}

@Ignore
@Test
public void testYellow(){
int expected = 16776960;
}
}``````
``````import java.util.HashMap;
import java.util.Map;
import java.util.Set;

private static final Map<Character, Integer> HEX_MAP = hexMap();
private static final Set<Character> VALID_CHARACTERS = HEX_MAP.keySet();

private static Map<Character, Integer> hexMap() {
Map<Character, Integer> hexMap = new HashMap<>();
hexMap.put('0', 0);
hexMap.put('1', 1);
hexMap.put('2', 2);
hexMap.put('3', 3);
hexMap.put('4', 4);
hexMap.put('5', 5);
hexMap.put('6', 6);
hexMap.put('7', 7);
hexMap.put('8', 8);
hexMap.put('9', 9);
hexMap.put('a', 10);
hexMap.put('b', 11);
hexMap.put('c', 12);
hexMap.put('d', 13);
hexMap.put('e', 14);
hexMap.put('f', 15);
return hexMap;
}

public static int toDecimal(String str) {
if (!valid(str)) {
return 0;
}
return calculateDecimal(str);
}

private static int calculateDecimal(String str) {
int decimal = 0;
for (int i = 0; i < str.length(); i++) {
int multiplier = multiplier(i, str.length());
int digit =  digitToDecimal(str.charAt(i));
decimal += digit * multiplier;
}
return decimal;
}

private static int multiplier(int index, int strLength) {
return (int) Math.pow(16, (strLength - 1 - index));
}

private static int digitToDecimal(Character digit) {
return HEX_MAP.get(digit);
}

private static boolean valid(String str) {
for (Character c : str.toCharArray()) {
if (!VALID_CHARACTERS.contains(c)) {
return false;
}
}
return true;
}
}`````` Can you think of an implementation that wouldn't use a Map? valid iterates through the input String once. Then you iterate through the input String again in calculateDecimal. Can you think of a way to incorporate your validation logic such that you only have to iterate through the input String only once? why have multiplier and digitToDecimal (especially the latter)? There's not really a need for VALID_CHARACTERS. I think it's perfectly readable to do something like HEX_MAP.keySet().contains() instead.

### What can you learn from this solution?

A huge amount can be learned from reading other people’s code. This is why we wanted to give exercism users the option of making their solutions public.

Here are some questions to help you reflect on this solution and learn the most from it.

• What compromises have been made?