Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 8 additions & 13 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -287,19 +287,6 @@
"number_theory"
]
},
{
"slug": "phone-number",
"name": "Phone Number",
"uuid": "c211045e-da97-479d-9df4-5d812573e2d0",
"practices": [],
"prerequisites": [],
"difficulty": 2,
"topics": [
"interfaces",
"parsing",
"strings"
]
},
{
"slug": "queen-attack",
"name": "Queen Attack",
Expand Down Expand Up @@ -942,6 +929,14 @@
"practices": [],
"prerequisites": [],
"difficulty": 2
},
{
"slug": "phone-number",
"name": "Phone Number",
"uuid": "c211045e-da97-479d-9df4-5d812573e2d0",
"practices": [],
"prerequisites": [],
"difficulty": 1
}
]
},
Expand Down
83 changes: 66 additions & 17 deletions exercises/practice/phone-number/.meta/example.el
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,81 @@

;;; Commentary:

;;; Code:
(defun char-digit-p (x)
(<= ?0 x ?9))

(defun char-lowercase-p (x)
(<= ?a x ?z))

(defun numbers (num)
(let ((number (replace-regexp-in-string "[^0-9]+" "" num)))
(cond
((= (length number) 10) number)
((and (= (length number) 11)
(string-equal (substring number 0 1) "1")) (substring number 1))
(t "0000000000"))))


(defun area-code (num)
(substring (numbers num) 0 3))
(defun char-uppercase-p (x)
(<= ?A x ?Z))

(defun char-alphabetic-p (x)
(or (char-lowercase-p x)
(char-uppercase-p x)))

(defun prefix (num)
(substring (numbers num) 3 6))
(defun char-punctuation-p (x)
(or (<= 33 x 39)
(= x 42)
(= x 44)
(= x 47)
(<= 58 x 64)
(<= 91 x 96)
(<= 123 x 126)))

(defun negate (pred)
(lambda (&rest args) (apply pred args)))

(defun line-number (num)
(substring (numbers num) 6))
(defun string-remove (s pred)
(let* ((n (length s))
(to-str (make-string n ?\0))
(k 0))
(dotimes (i n)
(let ((x (aref s i)))
(when (funcall pred x)
(setf (aref to-str k) x)
(cl-incf k))))
(substring to-str 0 k)))

(defun numbers (num)
"Converts a num string into a string of digits."
(cond
((cl-find-if #'char-alphabetic-p num)
(error "letters not permitted"))
((cl-find-if #'char-punctuation-p num)
(error "punctuations not permitted")))
(let* ((digits (string-remove num (negate #'char-digit-p)))
(n (length digits)))
(cond
((< n 10) (error "must not be fewer than 10 digits"))
((> n 11) (error "must not be greater than 11 digits")))
(if (= n 11)
(if (= (aref digits 0) ?1)
(setf digits (substring digits 1))
(error "11 digits must start with 1")))
(let ((y (aref digits 0)))
(cond
((= y ?0)
(error "area code cannot start with zero"))
((= y ?1)
(error "area code cannot start with one"))))
(let ((y (aref digits 3)))
(cond
((= y ?0)
(error "exchange code cannot start with zero"))
((= y ?1)
(error "exchange code cannot start with one"))))
digits))

(defun area-code (num)
(let ((digits (numbers num)))
(substring digits 0 3)))

(defun pprint (num)
(format "(%s) %s-%s" (area-code num) (prefix num) (line-number num)))
(let ((digits (numbers num)))
(format "(%s) %s-%s" (substring digits 0 3)
(substring digits 3 6)
(substring digits 6 10))))


(provide 'phone-number)
Expand Down
1 change: 1 addition & 0 deletions exercises/practice/phone-number/.meta/tests.toml
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,4 @@ description = "invalid if exchange code starts with 0 on valid 11-digit number"

[57b32f3d-696a-455c-8bf1-137b6d171cdf]
description = "invalid if exchange code starts with 1 on valid 11-digit number"

75 changes: 56 additions & 19 deletions exercises/practice/phone-number/phone-number-test.el
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
;;; phone-number-test.el --- Tests for phone-number (exercism) -*- lexical-binding: t; -*-
;;; phone-number-test.el --- Phone Number (exercism) -*- lexical-binding: t; -*-

;;; Commentary:

Expand All @@ -9,35 +9,72 @@
(declare-function area-code "phone-number.el" (num))
(declare-function pprint "phone-number.el" (num))

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

(ert-deftest cleans-numbers-with-dots ()
(should (string= (numbers "223.456.7890") "2234567890")))

(ert-deftest cleans-numbers-with-dots-test ()
(should (equal (numbers "223.456.7890") "2234567890")))
(ert-deftest cleans-numbers-with-multiple-spaces ()
(should (string= (numbers "223 456 7890 ") "2234567890")))

(ert-deftest invalid-when-9-digits ()
(should (string= (cadr (should-error (numbers "123456789")))
"must not be fewer than 10 digits")))

(ert-deftest valid-when-11-digits-and-first-is-1-test ()
(should (equal (numbers "12234567890") "2234567890")))
(ert-deftest invalid-when-11-digits-does-not-start-with-a-1 ()
(should (string= (cadr (should-error (numbers "22234567890")))
"11 digits must start with 1")))

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

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

(ert-deftest invalid-when-more-than-11-digits ()
(should (string= (cadr (should-error (numbers "321234567890")))
"must not be greater than 11 digits")))

(ert-deftest invalid-when-9-digits-test ()
(should (equal (numbers "123456789") "0000000000")))
(ert-deftest invalid-with-letters ()
(should (string= (cadr (should-error (numbers "523-abc-7890")))
"letters not permitted")))

(ert-deftest invalid-when-more-than-11-digits-test ()
(should (equal (numbers "321234567890") "0000000000")))
(ert-deftest invalid-with-punctuations ()
(should (string= (cadr (should-error (numbers "523-@:!-7890")))
"punctuations not permitted")))

(ert-deftest invalid-with-letters ()
(should (equal (numbers "523-abc-7890") "0000000000")))
(ert-deftest invalid-if-area-code-starts-with-0 ()
(should (string= (cadr (should-error (numbers "(023) 456-7890")))
"area code cannot start with zero")))

(ert-deftest invalid-if-area-code-starts-with-1 ()
(should (string= (cadr (should-error (numbers "(123) 456-7890")))
"area code cannot start with one")))

(ert-deftest invalid-with-punctuations ()
(should (equal (numbers "523-@:!-7890") "0000000000")))
(ert-deftest invalid-if-exchange-code-starts-with-0 ()
(should (string= (cadr (should-error (numbers "(223) 056-7890")))
"exchange code cannot start with zero")))

(ert-deftest invalid-if-exchange-code-starts-with-1 ()
(should (string= (cadr (should-error (numbers "(223) 156-7890")))
"exchange code cannot start with one")))

(ert-deftest invalid-if-area-code-starts-with-0-on-valid-11-digit-number ()
(should (string= (cadr (should-error (numbers "1 (023) 456-7890")))
"area code cannot start with zero")))

(ert-deftest invalid-if-area-code-starts-with-1-on-valid-11-digit-number ()
(should (string= (cadr (should-error (numbers "1 (123) 456-7890")))
"area code cannot start with one")))

(ert-deftest invalid-if-exchange-code-starts-with-0-on-valid-11-digit-number ()
(should (string= (cadr (should-error (numbers "1 (223) 056-7890")))
"exchange code cannot start with zero")))

(ert-deftest invalid-if-exchange-code-starts-with-1-on-valid-11-digit-number ()
(should (string= (cadr (should-error (numbers "1 (223) 156-7890")))
"exchange code cannot start with one")))

(ert-deftest area-code-test ()
(should (equal (area-code "2234567890") "223")))
Expand All @@ -50,6 +87,6 @@
(ert-deftest pprint-full-us-phone-number-test ()
(should (equal (pprint "12234567890") "(223) 456-7890")))


(provide 'phone-number)
(provide 'phone-number-test)
;;; phone-number-test.el ends here

2 changes: 1 addition & 1 deletion exercises/practice/phone-number/phone-number.el
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
;;; phone-number.el --- phone-number Exercise (exercism) -*- lexical-binding: t; -*-
;;; phone-number.el --- phone-number (exercism) -*- lexical-binding: t; -*-

;;; Commentary:

Expand Down