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

shmibs's solution

to Phone Number in the Elixir Track

Published at Jul 13 2018 · 0 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.

Clean up user-entered phone numbers so that they can be sent SMS messages.

The North American Numbering Plan (NANP) is a telephone numbering system used by many countries in North America like the United States, Canada or Bermuda. All NANP-countries share the same international country code: `1`.

NANP numbers are ten-digit numbers consisting of a three-digit Numbering Plan Area code, commonly known as area code, followed by a seven-digit local number. The first three digits of the local number represent the exchange code, followed by the unique four-digit number which is the subscriber number.

The format is usually represented as

``````(NXX)-NXX-XXXX
``````

where `N` is any digit from 2 through 9 and `X` is any digit from 0 through 9.

Your task is to clean up differently formatted telephone numbers by removing punctuation and the country code (1) if present.

For example, the inputs

• `+1 (613)-995-0253`
• `613-995-0253`
• `1 613 995 0253`
• `613.995.0253`

should all produce the output

`6139950253`

Note: As this exercise only deals with telephone numbers used in NANP-countries, only 1 is considered a valid country code.

Running tests

Execute the tests with:

``````\$ elixir phone_number_test.exs
``````

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
``````

For more detailed information about the Elixir track, please see the help page.

Source

Event Manager by JumpstartLab http://tutorials.jumpstartlab.com/projects/eventmanager.html

Submitting Incomplete Solutions

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

phone_number_test.exs

``````if !System.get_env("EXERCISM_TEST_EXAMPLES") do
end

ExUnit.start()
ExUnit.configure(exclude: :pending, trace: true)

defmodule PhoneTest do
use ExUnit.Case

test "cleans number" do
assert Phone.number("(212) 555-0100") == "2125550100"
end

@tag :pending
test "cleans number with dots" do
assert Phone.number("212.555.0100") == "2125550100"
end

@tag :pending
test "valid when 11 digits and first is 1" do
assert Phone.number("12125550100") == "2125550100"
end

@tag :pending
test "valid when 11 digits and some decorations" do
assert Phone.number("+1 (212) 555-0100") == "2125550100"
end

@tag :pending
test "invalid when country calling code is not 1" do
assert Phone.number("22125550100") == "0000000000"
end

@tag :pending
test "invalid when 9 digits" do
assert Phone.number("212555010") == "0000000000"
end

@tag :pending
test "invalid when proper number of digits but letters mixed in" do
assert Phone.number("2a1a2a5a5a5a0a1a0a0a") == "0000000000"
end

@tag :pending
test "invalid with correct number of characters but some are letters" do
assert Phone.number("2a1a2a5a5a") == "0000000000"
end

@tag :pending
test "invalid when area code begins with 1" do
assert Phone.number("1125550100") == "0000000000"
end

@tag :pending
test "invalid when area code begins with 0" do
assert Phone.number("0125550100") == "0000000000"
end

@tag :pending
test "invalid when exchange code begins with 1" do
assert Phone.number("2121550100") == "0000000000"
end

@tag :pending
test "invalid when exchange code begins with 0" do
assert Phone.number("2120550100") == "0000000000"
end

@tag :pending
test "area code" do
assert Phone.area_code("2125550100") == "212"
end

@tag :pending
test "area code with full US phone number" do
assert Phone.area_code("12125550100") == "212"
end

@tag :pending
test "invalid area code" do
assert Phone.area_code("(100) 555-1234") == "000"
end

@tag :pending
test "no area code" do
assert Phone.area_code("867.5309") == "000"
end

@tag :pending
test "pretty print" do
assert Phone.pretty("2125550100") == "(212) 555-0100"
end

@tag :pending
test "pretty print with full US phone number" do
assert Phone.pretty("+1 (303) 555-1212") == "(303) 555-1212"
end

@tag :pending
test "pretty print invalid US phone number" do
assert Phone.pretty("212-155-0100") == "(000) 000-0000"
end

@tag :pending
test "pretty print invalid, short US phone number" do
assert Phone.pretty("867.5309") == "(000) 000-0000"
end
end``````
``````defmodule Phone do
@invalid "0000000000"

@doc """
Remove formatting from a phone number.

Returns "0000000000" if phone number is not valid
(10 digits or "1" followed by 10 digits)

## Examples

iex> Phone.number("123-456-7890")
"1234567890"

iex> Phone.number("+1 (303) 555-1212")
"3035551212"

iex> Phone.number("867.5309")
"0000000000"
"""
@spec number(String.t) :: String.t
def number(raw) do
trim = String.replace raw, ~r/[^[:alnum:]]/, ""
trimlen = String.length trim
cond do
trimlen == 11 && String.first(trim) == "1" ->
String.slice trim, 1..trimlen
trimlen == 10 -> trim
true -> @invalid
end
end

@doc """
Extract the area code from a phone number

Returns the first three digits from a phone number,
ignoring long distance indicator

## Examples

iex> Phone.area_code("123-456-7890")
"123"

iex> Phone.area_code("+1 (303) 555-1212")
"303"

iex> Phone.area_code("867.5309")
"000"
"""
@spec area_code(String.t) :: String.t
def area_code(raw) do
String.slice number(raw), 0..2
end

@doc """
Pretty print a phone number

Wraps the area code in parentheses and separates
exchange and subscriber number with a dash.

## Examples

iex> Phone.pretty("123-456-7890")
"(123) 456-7890"

iex> Phone.pretty("+1 (303) 555-1212")
"(303) 555-1212"

iex> Phone.pretty("867.5309")
"(000) 000-0000"
"""
@spec pretty(String.t) :: String.t
def pretty(raw) do
clean = number(raw)
"(" <> String.slice(clean, 0..2) <> ") "
<> String.slice(clean, 3..5) <> "-"
<> String.slice(clean, 6..9)
end
end``````