Skip to content

Commit ad41bce

Browse files
Add phone-number exercise (#50)
1 parent 70680b1 commit ad41bce

File tree

15 files changed

+592
-0
lines changed

15 files changed

+592
-0
lines changed

config.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,14 @@
209209
"prerequisites": [],
210210
"difficulty": 3
211211
},
212+
{
213+
"slug": "phone-number",
214+
"name": "Phone Number",
215+
"uuid": "692e89e0-b392-4a82-98e5-7bf7a948ffbf",
216+
"practices": [],
217+
"prerequisites": [],
218+
"difficulty": 3
219+
},
212220
{
213221
"slug": "rotational-cipher",
214222
"name": "Rotational Cipher",
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Instructions
2+
3+
Clean up phone numbers so that they can be sent SMS messages.
4+
5+
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.
6+
All NANP-countries share the same international country code: `1`.
7+
8+
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.
9+
The first three digits of the local number represent the _exchange code_, followed by the unique four-digit number which is the _subscriber number_.
10+
11+
The format is usually represented as
12+
13+
```text
14+
NXX NXX-XXXX
15+
```
16+
17+
where `N` is any digit from 2 through 9 and `X` is any digit from 0 through 9.
18+
19+
Sometimes they also have the country code (represented as `1` or `+1`) prefixed.
20+
21+
Your task is to clean up differently formatted telephone numbers by removing punctuation and the country code if present.
22+
23+
For example, the inputs
24+
25+
- `+1 (613)-995-0253`
26+
- `613-995-0253`
27+
- `1 613 995 0253`
28+
- `613.995.0253`
29+
30+
should all produce the output
31+
32+
`6139950253`
33+
34+
**Note:** As this exercise only deals with telephone numbers used in NANP-countries, only 1 is considered a valid country code.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Introduction
2+
3+
You've joined LinkLine, a leading communications company working to ensure reliable connections for everyone.
4+
The team faces a big challenge: users submit phone numbers in all sorts of formats — dashes, spaces, dots, parentheses, and even prefixes.
5+
Some numbers are valid, while others are impossible to use.
6+
7+
Your mission is to turn this chaos into order.
8+
You'll clean up valid numbers, formatting them appropriately for use in the system.
9+
At the same time, you'll identify and filter out any invalid entries.
10+
11+
The success of LinkLine's operations depends on your ability to separate the useful from the unusable.
12+
Are you ready to take on the challenge and keep the connections running smoothly?
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace PhoneNumber
2+
3+
def clean (phrase : String) : Option String := Id.run do
4+
if phrase.any (fun (c : Char) => c > '9') then none
5+
else
6+
let mut digits := phrase.toList.filter Char.isDigit
7+
if digits.length == 11 && digits[0]! == '1' then
8+
digits := List.tail? digits |> Option.get!
9+
if digits.length != 10 || digits[0]! <= '1' || digits[3]! <= '1' then none
10+
else some digits.asString
11+
12+
end PhoneNumber
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"authors": [
3+
"keiravillekode"
4+
],
5+
"files": {
6+
"solution": [
7+
"PhoneNumber.lean"
8+
],
9+
"test": [
10+
"PhoneNumberTest.lean"
11+
],
12+
"example": [
13+
".meta/Example.lean"
14+
]
15+
},
16+
"blurb": "Clean up user-entered phone numbers so that they can be sent SMS messages.",
17+
"source": "Exercise by the JumpstartLab team for students at The Turing School of Software and Design.",
18+
"source_url": "https://turing.edu"
19+
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# This is an auto-generated file.
2+
#
3+
# Regenerating this file via `configlet sync` will:
4+
# - Recreate every `description` key/value pair
5+
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
6+
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
7+
# - Preserve any other key/value pair
8+
#
9+
# As user-added comments (using the # character) will be removed when this file
10+
# is regenerated, comments can be added via a `comment` key.
11+
12+
[79666dce-e0f1-46de-95a1-563802913c35]
13+
description = "cleans the number"
14+
15+
[c360451f-549f-43e4-8aba-fdf6cb0bf83f]
16+
description = "cleans numbers with dots"
17+
18+
[08f94c34-9a37-46a2-a123-2a8e9727395d]
19+
description = "cleans numbers with multiple spaces"
20+
21+
[598d8432-0659-4019-a78b-1c6a73691d21]
22+
description = "invalid when 9 digits"
23+
include = false
24+
25+
[2de74156-f646-42b5-8638-0ef1d8b58bc2]
26+
description = "invalid when 9 digits"
27+
reimplements = "598d8432-0659-4019-a78b-1c6a73691d21"
28+
29+
[57061c72-07b5-431f-9766-d97da7c4399d]
30+
description = "invalid when 11 digits does not start with a 1"
31+
32+
[9962cbf3-97bb-4118-ba9b-38ff49c64430]
33+
description = "valid when 11 digits and starting with 1"
34+
35+
[fa724fbf-054c-4d91-95da-f65ab5b6dbca]
36+
description = "valid when 11 digits and starting with 1 even with punctuation"
37+
38+
[c6a5f007-895a-4fc5-90bc-a7e70f9b5cad]
39+
description = "invalid when more than 11 digits"
40+
include = false
41+
42+
[4a1509b7-8953-4eec-981b-c483358ff531]
43+
description = "invalid when more than 11 digits"
44+
reimplements = "c6a5f007-895a-4fc5-90bc-a7e70f9b5cad"
45+
46+
[63f38f37-53f6-4a5f-bd86-e9b404f10a60]
47+
description = "invalid with letters"
48+
include = false
49+
50+
[eb8a1fc0-64e5-46d3-b0c6-33184208e28a]
51+
description = "invalid with letters"
52+
reimplements = "63f38f37-53f6-4a5f-bd86-e9b404f10a60"
53+
54+
[4bd97d90-52fd-45d3-b0db-06ab95b1244e]
55+
description = "invalid with punctuations"
56+
include = false
57+
58+
[065f6363-8394-4759-b080-e6c8c351dd1f]
59+
description = "invalid with punctuations"
60+
reimplements = "4bd97d90-52fd-45d3-b0db-06ab95b1244e"
61+
62+
[d77d07f8-873c-4b17-8978-5f66139bf7d7]
63+
description = "invalid if area code starts with 0"
64+
65+
[c7485cfb-1e7b-4081-8e96-8cdb3b77f15e]
66+
description = "invalid if area code starts with 1"
67+
68+
[4d622293-6976-413d-b8bf-dd8a94d4e2ac]
69+
description = "invalid if exchange code starts with 0"
70+
71+
[4cef57b4-7d8e-43aa-8328-1e1b89001262]
72+
description = "invalid if exchange code starts with 1"
73+
74+
[9925b09c-1a0d-4960-a197-5d163cbe308c]
75+
description = "invalid if area code starts with 0 on valid 11-digit number"
76+
77+
[3f809d37-40f3-44b5-ad90-535838b1a816]
78+
description = "invalid if area code starts with 1 on valid 11-digit number"
79+
80+
[e08e5532-d621-40d4-b0cc-96c159276b65]
81+
description = "invalid if exchange code starts with 0 on valid 11-digit number"
82+
83+
[57b32f3d-696a-455c-8bf1-137b6d171cdf]
84+
description = "invalid if exchange code starts with 1 on valid 11-digit number"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace PhoneNumber
2+
3+
def clean (phrase : String) : Option String :=
4+
sorry
5+
6+
end PhoneNumber
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import LeanTest
2+
import PhoneNumber
3+
4+
open LeanTest
5+
6+
def phoneNumberTests : TestSuite :=
7+
(TestSuite.empty "PhoneNumber")
8+
|>.addTest "cleans the number" (do
9+
return assertEqual (some "2234567890") (PhoneNumber.clean "(223) 456-7890"))
10+
|>.addTest "cleans numbers with dots" (do
11+
return assertEqual (some "2234567890") (PhoneNumber.clean "223.456.7890"))
12+
|>.addTest "cleans numbers with multiple spaces" (do
13+
return assertEqual (some "2234567890") (PhoneNumber.clean "223 456 7890 "))
14+
|>.addTest "invalid when 9 digits" (do
15+
return assertEqual none (PhoneNumber.clean "123456789"))
16+
|>.addTest "invalid when 11 digits does not start with a 1" (do
17+
return assertEqual none (PhoneNumber.clean "22234567890"))
18+
|>.addTest "valid when 11 digits and starting with 1" (do
19+
return assertEqual (some "2234567890") (PhoneNumber.clean "12234567890"))
20+
|>.addTest "valid when 11 digits and starting with 1 even with punctuation" (do
21+
return assertEqual (some "2234567890") (PhoneNumber.clean "+1 (223) 456-7890"))
22+
|>.addTest "invalid when more than 11 digits" (do
23+
return assertEqual none (PhoneNumber.clean "321234567890"))
24+
|>.addTest "invalid with letters" (do
25+
return assertEqual none (PhoneNumber.clean "523-abc-7890"))
26+
|>.addTest "invalid with punctuations" (do
27+
return assertEqual none (PhoneNumber.clean "523-@:!-7890"))
28+
|>.addTest "invalid if area code starts with 0" (do
29+
return assertEqual none (PhoneNumber.clean "(023) 456-7890"))
30+
|>.addTest "invalid if area code starts with 1" (do
31+
return assertEqual none (PhoneNumber.clean "(123) 456-7890"))
32+
|>.addTest "invalid if exchange code starts with 0" (do
33+
return assertEqual none (PhoneNumber.clean "(223) 056-7890"))
34+
|>.addTest "invalid if exchange code starts with 1" (do
35+
return assertEqual none (PhoneNumber.clean "(223) 156-7890"))
36+
|>.addTest "invalid if area code starts with 0 on valid 11-digit number" (do
37+
return assertEqual none (PhoneNumber.clean "1 (023) 456-7890"))
38+
|>.addTest "invalid if area code starts with 1 on valid 11-digit number" (do
39+
return assertEqual none (PhoneNumber.clean "1 (123) 456-7890"))
40+
|>.addTest "invalid if exchange code starts with 0 on valid 11-digit number" (do
41+
return assertEqual none (PhoneNumber.clean "1 (223) 056-7890"))
42+
|>.addTest "invalid if exchange code starts with 1 on valid 11-digit number" (do
43+
return assertEqual none (PhoneNumber.clean "1 (223) 156-7890"))
44+
45+
def main : IO UInt32 := do
46+
runTestSuitesWithExitCode [phoneNumberTests]
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
name = "phone-number"
2+
version = "0.1.0"
3+
defaultTargets = ["PhoneNumberTest"]
4+
testDriver = "PhoneNumberTest"
5+
6+
[[lean_lib]]
7+
name = "LeanTest"
8+
srcDir = "vendor/LeanTest"
9+
10+
[[lean_lib]]
11+
name = "PhoneNumber"
12+
13+
[[lean_exe]]
14+
name = "PhoneNumberTest"
15+
root = "PhoneNumberTest"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
leanprover/lean4:v4.25.2

0 commit comments

Comments
 (0)