Alphabetic telephone number translator

The problem

Many companies use telephone numbers like 555-GET-Food so the number is easier for their customers to remember. On a standard telephone, the alphabetic letters are mapped to numbers in the following fashion:

  • A, B, and C = 2
  • D, E, and F = 3
  • G, H, and I = 4
  • J, K, and L = 5
  • M, N, and O = 6
  • P, Q, R, and S = 7
  • T, U, and V = 8
  • W, X, y, and Z = 9

Write an application that asks the user to enter a 10-character telephone number in the format XXX-XXX-XXXX. The application should display the telephone number with any alphabetic characters that appeared in the original translated to their numeric equivalent. For example, if the user enters 555-GET-FOOD the application should display 555-438-3663.

Breaking it down

For this exercise we will use a popular third party library created by Google called guava. We could write a series of if statement with a bunch of or statements which could get kind of ugly OR find a collection that will hold a one-to-many relationship. Guava's multimap is a collection that maps keys to values, similar to Map, but in which each key may be associated with multiple values. We will use this to associate the translation between alpha and phone digit.

Create a collection to hold translated values

static ImmutableMultimap<String, String> numberAlphaTrans = null;

static {
    numberAlphaTrans = new ImmutableMultimap.Builder<String, String>()
            .putAll("2", Lists.<String> newArrayList("A", "B", "C"))
            .putAll("3", Lists.<String> newArrayList("D", "E", "F"))
            .putAll("4", Lists.<String> newArrayList("G", "H", "I"))
            .putAll("5", Lists.<String> newArrayList("J", "K", "L"))
            .putAll("6", Lists.<String> newArrayList("M", "N", "O"))
            .putAll("7", Lists.<String> newArrayList("P", "Q", "R", "S"))
            .putAll("8", Lists.<String> newArrayList("T", "U", "V"))
            .putAll("9", Lists.<String> newArrayList("W", "X", "Y", "Z"))
            .build();
}

Main program

We will ask the user to enter input from keyboard and use guava Splitter to turn the string into a list based on a fixed length. Using java 8 syntax we will use an inline java.util.function to check if element is a character and if so look up the value in numberAlphaTrans. Finally using java 8 we will join the elements in list.

public static void main(String[] args) {

    // Create a Scanner to get keyboard input
    Scanner keyboard = new Scanner(System.in);

    // Get a phone number.
    System.out.print("Enter a phone number for translation: ");
    String phoneNumber = keyboard.nextLine();

    // close scanner
    keyboard.close();

    List<String> convertedPhone = Splitter
            .fixedLength(1)
            .splitToList(phoneNumber)
            .stream()
            .map(t -> {
                if (Character.isAlphabetic(t.codePointAt(0))) {
                    return numberAlphaTrans.inverse().get(t).asList()
                            .get(0);
                } else {
                    return t;
                }
            }).collect(Collectors.toList());

    System.out.println(String.join("", convertedPhone));
}

Output

Enter a phone number for translation: 555-GET-FOOD
555-438-3663

Level Up

  • If a user inputs a character in for the area code, should the program ignore, throw an error or ?. Modify the program on how you feel it should work.