From d30980c98b184f795b0347bd92cb495dee603a90 Mon Sep 17 00:00:00 2001 From: Shinichi Sakata Date: Sat, 12 Apr 2025 16:42:17 -0700 Subject: [PATCH 1/7] 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 --- exercises/practice/phone-number/phone-number-test.el | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/exercises/practice/phone-number/phone-number-test.el b/exercises/practice/phone-number/phone-number-test.el index b89eb82b..36a73088 100644 --- a/exercises/practice/phone-number/phone-number-test.el +++ b/exercises/practice/phone-number/phone-number-test.el @@ -10,15 +10,15 @@ (declare-function pprint "phone-number.el" (num)) (ert-deftest cleans-number-test () - (should (equal (numbers "(123) 456-7890") "1234567890"))) + (should (equal (numbers "(223) 456-7890") "2234567890"))) (ert-deftest cleans-numbers-with-dots-test () - (should (equal (numbers "123.456.7890") "1234567890"))) + (should (equal (numbers "223.456.7890") "2234567890"))) (ert-deftest valid-when-11-digits-and-first-is-1-test () - (should (equal (numbers "11234567890") "1234567890"))) + (should (equal (numbers "12234567890") "2234567890"))) (ert-deftest invalid-when-11-digits-test () @@ -40,15 +40,15 @@ (ert-deftest area-code-test () - (should (equal (area-code "1234567890") "123"))) + (should (equal (area-code "2234567890") "223"))) (ert-deftest pprint-test () - (should (equal (pprint "1234567890") "(123) 456-7890"))) + (should (equal (pprint "2234567890") "(223) 456-7890"))) (ert-deftest pprint-full-us-phone-number-test () - (should (equal (pprint "11234567890") "(123) 456-7890"))) + (should (equal (pprint "12234567890") "(223) 456-7890"))) (provide 'phone-number) From bea706ace9d38235feb951132e079ffa9f650c8c Mon Sep 17 00:00:00 2001 From: Shinichi Sakata Date: Sun, 20 Apr 2025 17:14:24 -0700 Subject: [PATCH 2/7] 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. --- config.json | 21 ++--- .../practice/phone-number/.meta/example.el | 83 +++++++++++++++---- .../practice/phone-number/.meta/tests.toml | 1 + .../phone-number/phone-number-test.el | 75 ++++++++++++----- .../practice/phone-number/phone-number.el | 2 +- 5 files changed, 132 insertions(+), 50 deletions(-) diff --git a/config.json b/config.json index a9e8694f..e57c0927 100644 --- a/config.json +++ b/config.json @@ -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", @@ -942,6 +929,14 @@ "practices": [], "prerequisites": [], "difficulty": 2 + }, + { + "slug": "phone-number", + "name": "Phone Number", + "uuid": "e123577a-aaf8-4552-98f1-2ef94a7195f7", + "practices": [], + "prerequisites": [], + "difficulty": 1 } ] }, diff --git a/exercises/practice/phone-number/.meta/example.el b/exercises/practice/phone-number/.meta/example.el index 03316fa2..ddbe9489 100644 --- a/exercises/practice/phone-number/.meta/example.el +++ b/exercises/practice/phone-number/.meta/example.el @@ -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) diff --git a/exercises/practice/phone-number/.meta/tests.toml b/exercises/practice/phone-number/.meta/tests.toml index 24dbf07a..4fe47d59 100644 --- a/exercises/practice/phone-number/.meta/tests.toml +++ b/exercises/practice/phone-number/.meta/tests.toml @@ -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" + diff --git a/exercises/practice/phone-number/phone-number-test.el b/exercises/practice/phone-number/phone-number-test.el index 36a73088..43725486 100644 --- a/exercises/practice/phone-number/phone-number-test.el +++ b/exercises/practice/phone-number/phone-number-test.el @@ -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: @@ -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"))) @@ -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 + diff --git a/exercises/practice/phone-number/phone-number.el b/exercises/practice/phone-number/phone-number.el index 61cac595..a08eee0c 100644 --- a/exercises/practice/phone-number/phone-number.el +++ b/exercises/practice/phone-number/phone-number.el @@ -1,4 +1,4 @@ -;;; phone-number.el --- phone-number Exercise (exercism) -*- lexical-binding: t; -*- +;;; phone-number.el --- phone-number (exercism) -*- lexical-binding: t; -*- ;;; Commentary: From 38d3ab7dbe9812c91364e7eeaf9e76c72c592d3f Mon Sep 17 00:00:00 2001 From: Shinichi Sakata Date: Tue, 22 Apr 2025 07:29:37 -0700 Subject: [PATCH 3/7] Revert the uuid of "Phone Number" in config.json to the original one. --- config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.json b/config.json index e57c0927..7ec97d6a 100644 --- a/config.json +++ b/config.json @@ -933,7 +933,7 @@ { "slug": "phone-number", "name": "Phone Number", - "uuid": "e123577a-aaf8-4552-98f1-2ef94a7195f7", + "uuid": "c211045e-da97-479d-9df4-5d812573e2d0", "practices": [], "prerequisites": [], "difficulty": 1 From 33b64f46c8f14552c26c7dae659459f76b0e3aca Mon Sep 17 00:00:00 2001 From: borderite Date: Thu, 24 Apr 2025 20:40:15 -0700 Subject: [PATCH 4/7] Update config.json The difficulty of "phone number" is reverted back to 2. --- config.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.json b/config.json index 7ec97d6a..34e200be 100644 --- a/config.json +++ b/config.json @@ -936,7 +936,7 @@ "uuid": "c211045e-da97-479d-9df4-5d812573e2d0", "practices": [], "prerequisites": [], - "difficulty": 1 + "difficulty": 2 } ] }, From 1dc667245f41ce4a8e8d74155dae6fe341267e77 Mon Sep 17 00:00:00 2001 From: Shinichi Sakata Date: Thu, 24 Apr 2025 21:09:41 -0700 Subject: [PATCH 5/7] Put the entry for "Phone Number" back to the original position in ./configu.json. --- config.json | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/config.json b/config.json index 34e200be..8fc2bb5d 100644 --- a/config.json +++ b/config.json @@ -287,6 +287,14 @@ "number_theory" ] }, + { + "slug": "phone-number", + "name": "Phone Number", + "uuid": "c211045e-da97-479d-9df4-5d812573e2d0", + "practices": [], + "prerequisites": [], + "difficulty": 2 + }, { "slug": "queen-attack", "name": "Queen Attack", @@ -929,14 +937,6 @@ "practices": [], "prerequisites": [], "difficulty": 2 - }, - { - "slug": "phone-number", - "name": "Phone Number", - "uuid": "c211045e-da97-479d-9df4-5d812573e2d0", - "practices": [], - "prerequisites": [], - "difficulty": 2 } ] }, From 79395817e9ed00b78b2cf23421f7b1b2070837c1 Mon Sep 17 00:00:00 2001 From: Shinichi Sakata Date: Sat, 26 Apr 2025 06:24:55 -0700 Subject: [PATCH 6/7] 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. --- .../practice/phone-number/.meta/example.el | 28 ++++++++----- .../phone-number/phone-number-test.el | 39 +++++++------------ 2 files changed, 32 insertions(+), 35 deletions(-) diff --git a/exercises/practice/phone-number/.meta/example.el b/exercises/practice/phone-number/.meta/example.el index ddbe9489..79bf0bcf 100644 --- a/exercises/practice/phone-number/.meta/example.el +++ b/exercises/practice/phone-number/.meta/example.el @@ -2,6 +2,16 @@ ;;; Commentary: +(define-error 'short-phone-num-error "must not be fewer than 10 digits") +(define-error 'long-phone-num-error "must not be greater than 11 digits") +(define-error 'letters-in-phone-num-error "letters not permitted") +(define-error 'punctuations-in-phone-num-error "punctuations not permitted") +(define-error 'country-code-error "country code must be 1") +(define-error 'area-code-starting-with-0-error "area code cannot start with zero") +(define-error 'area-code-starting-with-1-error "area code cannot start with one") +(define-error 'exchange-code-starting-with-0-error "exchange code cannot start with zero") +(define-error 'exchange-code-starting-with-1-error "exchange code cannot start with one") + (defun char-digit-p (x) (<= ?0 x ?9)) @@ -42,30 +52,30 @@ "Converts a num string into a string of digits." (cond ((cl-find-if #'char-alphabetic-p num) - (error "letters not permitted")) + (signal 'letters-in-phone-num-error num)) ((cl-find-if #'char-punctuation-p num) - (error "punctuations not permitted"))) + (signal 'punctuations-in-phone-num-error num))) (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"))) + ((< n 10) (signal 'short-phone-num-error num)) + ((> n 11) (signal 'long-phone-num-error num))) (if (= n 11) (if (= (aref digits 0) ?1) (setf digits (substring digits 1)) - (error "11 digits must start with 1"))) + (signal 'country-code-error num))) (let ((y (aref digits 0))) (cond ((= y ?0) - (error "area code cannot start with zero")) + (signal 'area-code-starting-with-0-error num)) ((= y ?1) - (error "area code cannot start with one")))) + (signal 'area-code-starting-with-1-error num))) (let ((y (aref digits 3))) (cond ((= y ?0) - (error "exchange code cannot start with zero")) + (signal 'exchange-code-starting-with-0-error num)) ((= y ?1) - (error "exchange code cannot start with one")))) + (signal 'exchange-code-starting-with-1-error num))))) digits)) (defun area-code (num) diff --git a/exercises/practice/phone-number/phone-number-test.el b/exercises/practice/phone-number/phone-number-test.el index 43725486..b1e66134 100644 --- a/exercises/practice/phone-number/phone-number-test.el +++ b/exercises/practice/phone-number/phone-number-test.el @@ -19,12 +19,10 @@ (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"))) + (should-error (numbers "123456789") :type 'short-phone-num-error)) (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"))) + (should-error (numbers "22234567890") :type 'country-code-error)) (ert-deftest valid-when-11-digits-and-starting-with-1 () (should (string= (numbers "12234567890") "2234567890"))) @@ -33,48 +31,37 @@ (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"))) + (should-error (numbers "321234567890") :type 'long-phone-num-error)) (ert-deftest invalid-with-letters () - (should (string= (cadr (should-error (numbers "523-abc-7890"))) - "letters not permitted"))) + (should-error (numbers "523-abc-7890") :type 'letters-in-phone-num-error)) (ert-deftest invalid-with-punctuations () - (should (string= (cadr (should-error (numbers "523-@:!-7890"))) - "punctuations not permitted"))) + (should-error (numbers "523-@:!-7890") :type 'punctuations-in-phone-num-error)) (ert-deftest invalid-if-area-code-starts-with-0 () - (should (string= (cadr (should-error (numbers "(023) 456-7890"))) - "area code cannot start with zero"))) + (should-error (numbers "(023) 456-7890") :type 'area-code-starting-with-0-error)) (ert-deftest invalid-if-area-code-starts-with-1 () - (should (string= (cadr (should-error (numbers "(123) 456-7890"))) - "area code cannot start with one"))) + (should-error (numbers "(123) 456-7890") :type 'area-code-starting-with-1-error)) (ert-deftest invalid-if-exchange-code-starts-with-0 () - (should (string= (cadr (should-error (numbers "(223) 056-7890"))) - "exchange code cannot start with zero"))) + (should-error (numbers "(223) 056-7890") :type 'exchange-code-starting-with-0-error)) (ert-deftest invalid-if-exchange-code-starts-with-1 () - (should (string= (cadr (should-error (numbers "(223) 156-7890"))) - "exchange code cannot start with one"))) + (should-error (numbers "(223) 156-7890") :type 'exchange-code-starting-with-1-error)) (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"))) + (should-error (numbers "1 (023) 456-7890") :type 'area-code-starting-with-0-error)) (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"))) + (should-error (numbers "1 (123) 456-7890") :type 'area-code-starting-with-1-error)) (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"))) + (should-error (numbers "1 (223) 056-7890") :type 'exchange-code-starting-with-0-error)) (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"))) + (should-error (numbers "1 (223) 156-7890") :type 'exchange-code-starting-with-1-error)) (ert-deftest area-code-test () (should (equal (area-code "2234567890") "223"))) From 0a6e399d8ea30f81103873d5b96a47e8355a0cf7 Mon Sep 17 00:00:00 2001 From: Shinichi Sakata Date: Sat, 26 Apr 2025 16:50:15 -0700 Subject: [PATCH 7/7] Added borderite to the contributor list of "Phone Number". --- exercises/practice/phone-number/.meta/config.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/exercises/practice/phone-number/.meta/config.json b/exercises/practice/phone-number/.meta/config.json index c475338c..60881337 100644 --- a/exercises/practice/phone-number/.meta/config.json +++ b/exercises/practice/phone-number/.meta/config.json @@ -3,7 +3,8 @@ "cpaulbond" ], "contributors": [ - "yurrriq" + "yurrriq", + "borderite" ], "files": { "solution": [