Skip to content

Commit 2c5f028

Browse files
authored
Implemented all "Phone Number" problems from the canonical test data. (#465) (#472)
* Corrected a few tests of "Phone Number". - Revised the following tests using the canonical test data. cleans-number-test cleans-numbers-with-dots-test valid-when-11-digits-and-first-is-1-test - Revised the following tests specific for "Phone Number" to conform the requirements for phone numbers. area-code-test pprint-test pprint-full-us-phone-number-test * Implemented all "Phone Number" problems from the canonical test data. (#465) - The track-specific three problems are still included, but their solutions have been corrected. * Revert the uuid of "Phone Number" in config.json to the original one. * Update config.json The difficulty of "phone number" is reverted back to 2. * Put the entry for "Phone Number" back to the original position in ./configu.json. * Revised the test and example files of the "Phone Number" exercise. - The tests expecting errors now check custom errors instead of error messages. - The example test has been modified so that it passes the modified tests. * Added borderite to the contributor list of "Phone Number".
1 parent 59a411b commit 2c5f028

File tree

6 files changed

+123
-43
lines changed

6 files changed

+123
-43
lines changed

config.json

+1-6
Original file line numberDiff line numberDiff line change
@@ -293,12 +293,7 @@
293293
"uuid": "c211045e-da97-479d-9df4-5d812573e2d0",
294294
"practices": [],
295295
"prerequisites": [],
296-
"difficulty": 2,
297-
"topics": [
298-
"interfaces",
299-
"parsing",
300-
"strings"
301-
]
296+
"difficulty": 2
302297
},
303298
{
304299
"slug": "queen-attack",

exercises/practice/phone-number/.meta/config.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
"cpaulbond"
44
],
55
"contributors": [
6-
"yurrriq"
6+
"yurrriq",
7+
"borderite"
78
],
89
"files": {
910
"solution": [

exercises/practice/phone-number/.meta/example.el

+75-16
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,91 @@
22

33
;;; Commentary:
44

5-
;;; Code:
5+
(define-error 'short-phone-num-error "must not be fewer than 10 digits")
6+
(define-error 'long-phone-num-error "must not be greater than 11 digits")
7+
(define-error 'letters-in-phone-num-error "letters not permitted")
8+
(define-error 'punctuations-in-phone-num-error "punctuations not permitted")
9+
(define-error 'country-code-error "country code must be 1")
10+
(define-error 'area-code-starting-with-0-error "area code cannot start with zero")
11+
(define-error 'area-code-starting-with-1-error "area code cannot start with one")
12+
(define-error 'exchange-code-starting-with-0-error "exchange code cannot start with zero")
13+
(define-error 'exchange-code-starting-with-1-error "exchange code cannot start with one")
614

15+
(defun char-digit-p (x)
16+
(<= ?0 x ?9))
717

8-
(defun numbers (num)
9-
(let ((number (replace-regexp-in-string "[^0-9]+" "" num)))
10-
(cond
11-
((= (length number) 10) number)
12-
((and (= (length number) 11)
13-
(string-equal (substring number 0 1) "1")) (substring number 1))
14-
(t "0000000000"))))
18+
(defun char-lowercase-p (x)
19+
(<= ?a x ?z))
1520

21+
(defun char-uppercase-p (x)
22+
(<= ?A x ?Z))
1623

17-
(defun area-code (num)
18-
(substring (numbers num) 0 3))
19-
24+
(defun char-alphabetic-p (x)
25+
(or (char-lowercase-p x)
26+
(char-uppercase-p x)))
2027

21-
(defun prefix (num)
22-
(substring (numbers num) 3 6))
28+
(defun char-punctuation-p (x)
29+
(or (<= 33 x 39)
30+
(= x 42)
31+
(= x 44)
32+
(= x 47)
33+
(<= 58 x 64)
34+
(<= 91 x 96)
35+
(<= 123 x 126)))
2336

37+
(defun negate (pred)
38+
(lambda (&rest args) (apply pred args)))
2439

25-
(defun line-number (num)
26-
(substring (numbers num) 6))
40+
(defun string-remove (s pred)
41+
(let* ((n (length s))
42+
(to-str (make-string n ?\0))
43+
(k 0))
44+
(dotimes (i n)
45+
(let ((x (aref s i)))
46+
(when (funcall pred x)
47+
(setf (aref to-str k) x)
48+
(cl-incf k))))
49+
(substring to-str 0 k)))
2750

51+
(defun numbers (num)
52+
"Converts a num string into a string of digits."
53+
(cond
54+
((cl-find-if #'char-alphabetic-p num)
55+
(signal 'letters-in-phone-num-error num))
56+
((cl-find-if #'char-punctuation-p num)
57+
(signal 'punctuations-in-phone-num-error num)))
58+
(let* ((digits (string-remove num (negate #'char-digit-p)))
59+
(n (length digits)))
60+
(cond
61+
((< n 10) (signal 'short-phone-num-error num))
62+
((> n 11) (signal 'long-phone-num-error num)))
63+
(if (= n 11)
64+
(if (= (aref digits 0) ?1)
65+
(setf digits (substring digits 1))
66+
(signal 'country-code-error num)))
67+
(let ((y (aref digits 0)))
68+
(cond
69+
((= y ?0)
70+
(signal 'area-code-starting-with-0-error num))
71+
((= y ?1)
72+
(signal 'area-code-starting-with-1-error num)))
73+
(let ((y (aref digits 3)))
74+
(cond
75+
((= y ?0)
76+
(signal 'exchange-code-starting-with-0-error num))
77+
((= y ?1)
78+
(signal 'exchange-code-starting-with-1-error num)))))
79+
digits))
80+
81+
(defun area-code (num)
82+
(let ((digits (numbers num)))
83+
(substring digits 0 3)))
2884

2985
(defun pprint (num)
30-
(format "(%s) %s-%s" (area-code num) (prefix num) (line-number num)))
86+
(let ((digits (numbers num)))
87+
(format "(%s) %s-%s" (substring digits 0 3)
88+
(substring digits 3 6)
89+
(substring digits 6 10))))
3190

3291

3392
(provide 'phone-number)

exercises/practice/phone-number/.meta/tests.toml

+1
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,4 @@ description = "invalid if exchange code starts with 0 on valid 11-digit number"
8282

8383
[57b32f3d-696a-455c-8bf1-137b6d171cdf]
8484
description = "invalid if exchange code starts with 1 on valid 11-digit number"
85+
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
;;; phone-number-test.el --- Tests for phone-number (exercism) -*- lexical-binding: t; -*-
1+
;;; phone-number-test.el --- Phone Number (exercism) -*- lexical-binding: t; -*-
22

33
;;; Commentary:
44

@@ -9,35 +9,59 @@
99
(declare-function area-code "phone-number.el" (num))
1010
(declare-function pprint "phone-number.el" (num))
1111

12-
(ert-deftest cleans-number-test ()
13-
(should (equal (numbers "(223) 456-7890") "2234567890")))
12+
(ert-deftest cleans-the-number ()
13+
(should (string= (numbers "(223) 456-7890") "2234567890")))
1414

15+
(ert-deftest cleans-numbers-with-dots ()
16+
(should (string= (numbers "223.456.7890") "2234567890")))
1517

16-
(ert-deftest cleans-numbers-with-dots-test ()
17-
(should (equal (numbers "223.456.7890") "2234567890")))
18+
(ert-deftest cleans-numbers-with-multiple-spaces ()
19+
(should (string= (numbers "223 456 7890 ") "2234567890")))
1820

21+
(ert-deftest invalid-when-9-digits ()
22+
(should-error (numbers "123456789") :type 'short-phone-num-error))
1923

20-
(ert-deftest valid-when-11-digits-and-first-is-1-test ()
21-
(should (equal (numbers "12234567890") "2234567890")))
24+
(ert-deftest invalid-when-11-digits-does-not-start-with-a-1 ()
25+
(should-error (numbers "22234567890") :type 'country-code-error))
2226

27+
(ert-deftest valid-when-11-digits-and-starting-with-1 ()
28+
(should (string= (numbers "12234567890") "2234567890")))
2329

24-
(ert-deftest invalid-when-11-digits-test ()
25-
(should (equal (numbers "21234567890") "0000000000")))
30+
(ert-deftest valid-when-11-digits-and-starting-with-1-even-with-punctuation ()
31+
(should (string= (numbers "+1 (223) 456-7890") "2234567890")))
2632

33+
(ert-deftest invalid-when-more-than-11-digits ()
34+
(should-error (numbers "321234567890") :type 'long-phone-num-error))
2735

28-
(ert-deftest invalid-when-9-digits-test ()
29-
(should (equal (numbers "123456789") "0000000000")))
36+
(ert-deftest invalid-with-letters ()
37+
(should-error (numbers "523-abc-7890") :type 'letters-in-phone-num-error))
3038

31-
(ert-deftest invalid-when-more-than-11-digits-test ()
32-
(should (equal (numbers "321234567890") "0000000000")))
39+
(ert-deftest invalid-with-punctuations ()
40+
(should-error (numbers "523-@:!-7890") :type 'punctuations-in-phone-num-error))
3341

34-
(ert-deftest invalid-with-letters ()
35-
(should (equal (numbers "523-abc-7890") "0000000000")))
42+
(ert-deftest invalid-if-area-code-starts-with-0 ()
43+
(should-error (numbers "(023) 456-7890") :type 'area-code-starting-with-0-error))
3644

45+
(ert-deftest invalid-if-area-code-starts-with-1 ()
46+
(should-error (numbers "(123) 456-7890") :type 'area-code-starting-with-1-error))
3747

38-
(ert-deftest invalid-with-punctuations ()
39-
(should (equal (numbers "523-@:!-7890") "0000000000")))
48+
(ert-deftest invalid-if-exchange-code-starts-with-0 ()
49+
(should-error (numbers "(223) 056-7890") :type 'exchange-code-starting-with-0-error))
50+
51+
(ert-deftest invalid-if-exchange-code-starts-with-1 ()
52+
(should-error (numbers "(223) 156-7890") :type 'exchange-code-starting-with-1-error))
4053

54+
(ert-deftest invalid-if-area-code-starts-with-0-on-valid-11-digit-number ()
55+
(should-error (numbers "1 (023) 456-7890") :type 'area-code-starting-with-0-error))
56+
57+
(ert-deftest invalid-if-area-code-starts-with-1-on-valid-11-digit-number ()
58+
(should-error (numbers "1 (123) 456-7890") :type 'area-code-starting-with-1-error))
59+
60+
(ert-deftest invalid-if-exchange-code-starts-with-0-on-valid-11-digit-number ()
61+
(should-error (numbers "1 (223) 056-7890") :type 'exchange-code-starting-with-0-error))
62+
63+
(ert-deftest invalid-if-exchange-code-starts-with-1-on-valid-11-digit-number ()
64+
(should-error (numbers "1 (223) 156-7890") :type 'exchange-code-starting-with-1-error))
4165

4266
(ert-deftest area-code-test ()
4367
(should (equal (area-code "2234567890") "223")))
@@ -50,6 +74,6 @@
5074
(ert-deftest pprint-full-us-phone-number-test ()
5175
(should (equal (pprint "12234567890") "(223) 456-7890")))
5276

53-
54-
(provide 'phone-number)
77+
(provide 'phone-number-test)
5578
;;; phone-number-test.el ends here
79+

exercises/practice/phone-number/phone-number.el

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
;;; phone-number.el --- phone-number Exercise (exercism) -*- lexical-binding: t; -*-
1+
;;; phone-number.el --- phone-number (exercism) -*- lexical-binding: t; -*-
22

33
;;; Commentary:
44

0 commit comments

Comments
 (0)