From 122c82ee981be487630d67ce69f22068aa290030 Mon Sep 17 00:00:00 2001 From: Eric Willigers Date: Mon, 6 May 2024 09:12:42 +1000 Subject: [PATCH] Add isogram exercise (#366) --- config.json | 12 ++++ .../practice/isogram/.docs/instructions.md | 14 ++++ exercises/practice/isogram/.meta/config.json | 19 ++++++ exercises/practice/isogram/.meta/example.el | 27 ++++++++ exercises/practice/isogram/.meta/tests.toml | 52 ++++++++++++++ exercises/practice/isogram/isogram-test.el | 68 +++++++++++++++++++ exercises/practice/isogram/isogram.el | 13 ++++ 7 files changed, 205 insertions(+) create mode 100644 exercises/practice/isogram/.docs/instructions.md create mode 100644 exercises/practice/isogram/.meta/config.json create mode 100644 exercises/practice/isogram/.meta/example.el create mode 100644 exercises/practice/isogram/.meta/tests.toml create mode 100644 exercises/practice/isogram/isogram-test.el create mode 100644 exercises/practice/isogram/isogram.el diff --git a/config.json b/config.json index 1711d0aa..8152e58c 100644 --- a/config.json +++ b/config.json @@ -195,6 +195,18 @@ "strings" ] }, + { + "slug": "isogram", + "name": "Isogram", + "uuid": "63fc7e59-2448-487b-9b66-06c72ab8d6b0", + "practices": [], + "prerequisites": [], + "difficulty": 2, + "topics": [ + "control_flow_loops", + "strings" + ] + }, { "slug": "leap", "name": "Leap", diff --git a/exercises/practice/isogram/.docs/instructions.md b/exercises/practice/isogram/.docs/instructions.md new file mode 100644 index 00000000..2e8df851 --- /dev/null +++ b/exercises/practice/isogram/.docs/instructions.md @@ -0,0 +1,14 @@ +# Instructions + +Determine if a word or phrase is an isogram. + +An isogram (also known as a "non-pattern word") is a word or phrase without a repeating letter, however spaces and hyphens are allowed to appear multiple times. + +Examples of isograms: + +- lumberjacks +- background +- downstream +- six-year-old + +The word _isograms_, however, is not an isogram, because the s repeats. diff --git a/exercises/practice/isogram/.meta/config.json b/exercises/practice/isogram/.meta/config.json new file mode 100644 index 00000000..0a57ef77 --- /dev/null +++ b/exercises/practice/isogram/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "keiravillekode" + ], + "files": { + "solution": [ + "isogram.el" + ], + "test": [ + "isogram-test.el" + ], + "example": [ + ".meta/example.el" + ] + }, + "blurb": "Determine if a word or phrase is an isogram.", + "source": "Wikipedia", + "source_url": "https://en.wikipedia.org/wiki/Isogram" +} diff --git a/exercises/practice/isogram/.meta/example.el b/exercises/practice/isogram/.meta/example.el new file mode 100644 index 00000000..d63dd40f --- /dev/null +++ b/exercises/practice/isogram/.meta/example.el @@ -0,0 +1,27 @@ +;;; isogram.el --- isogram (exercism) -*- lexical-binding: t; -*- + +;;; Commentary: + +;;; Code: + +(require 'cl-lib) + +(defun upper-char-p (c) + "Determine if char C is alphabetic and upper case." + (and + (>= c ?A) + (<= c ?Z))) + +(defun isogramp (phrase) + "Determine if a given phrase is an isogram." + (let* ((bitset 0) + (updated 0) + (characters (cl-coerce (upcase phrase) 'list)) + (letters (cl-remove-if-not 'upper-char-p characters))) + (cl-loop for c in letters + do (setq updated (logior bitset (lsh 1 (- c ?A)))) + always (> updated bitset) + do (setq bitset updated)))) + +(provide 'isogram) +;;; isogram.el ends here diff --git a/exercises/practice/isogram/.meta/tests.toml b/exercises/practice/isogram/.meta/tests.toml new file mode 100644 index 00000000..ba04c664 --- /dev/null +++ b/exercises/practice/isogram/.meta/tests.toml @@ -0,0 +1,52 @@ +# This is an auto-generated file. +# +# Regenerating this file via `configlet sync` will: +# - Recreate every `description` key/value pair +# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications +# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion) +# - Preserve any other key/value pair +# +# As user-added comments (using the # character) will be removed when this file +# is regenerated, comments can be added via a `comment` key. + +[a0e97d2d-669e-47c7-8134-518a1e2c4555] +description = "empty string" + +[9a001b50-f194-4143-bc29-2af5ec1ef652] +description = "isogram with only lower case characters" + +[8ddb0ca3-276e-4f8b-89da-d95d5bae78a4] +description = "word with one duplicated character" + +[6450b333-cbc2-4b24-a723-0b459b34fe18] +description = "word with one duplicated character from the end of the alphabet" + +[a15ff557-dd04-4764-99e7-02cc1a385863] +description = "longest reported english isogram" + +[f1a7f6c7-a42f-4915-91d7-35b2ea11c92e] +description = "word with duplicated character in mixed case" + +[14a4f3c1-3b47-4695-b645-53d328298942] +description = "word with duplicated character in mixed case, lowercase first" + +[423b850c-7090-4a8a-b057-97f1cadd7c42] +description = "hypothetical isogrammic word with hyphen" + +[93dbeaa0-3c5a-45c2-8b25-428b8eacd4f2] +description = "hypothetical word with duplicated character following hyphen" + +[36b30e5c-173f-49c6-a515-93a3e825553f] +description = "isogram with duplicated hyphen" + +[cdabafa0-c9f4-4c1f-b142-689c6ee17d93] +description = "made-up name that is an isogram" + +[5fc61048-d74e-48fd-bc34-abfc21552d4d] +description = "duplicated character in the middle" + +[310ac53d-8932-47bc-bbb4-b2b94f25a83e] +description = "same first and last characters" + +[0d0b8644-0a1e-4a31-a432-2b3ee270d847] +description = "word with duplicated character and with two hyphens" diff --git a/exercises/practice/isogram/isogram-test.el b/exercises/practice/isogram/isogram-test.el new file mode 100644 index 00000000..6fbdbd51 --- /dev/null +++ b/exercises/practice/isogram/isogram-test.el @@ -0,0 +1,68 @@ +;;; isogram-test.el --- Tests for Isogram (exercism) -*- lexical-binding: t; -*- + +;;; Commentary: + +;;; Code: + +(load-file "isogram.el") +(declare-function isogramp "isogram.el" (phrase)) + + +(ert-deftest empty-string () + (should (isogramp ""))) + + +(ert-deftest isogram-with-only-lower-case-characters () + (should (isogramp "isogram"))) + + +(ert-deftest word-with-one-duplicated-character () + (should-not (isogramp "eleven"))) + + +(ert-deftest word-with-one-duplicated-character-from-the-end-of-the-alphabet () + (should-not (isogramp "zzyzx"))) + + +(ert-deftest longest-reported-english-isogram () + (should (isogramp "subdermatoglyphic"))) + + +(ert-deftest word-with-duplicated-character-in-mixed-case () + (should-not (isogramp "Alphabet"))) + + +(ert-deftest word-with-duplicated-character-in-mixed-case-lowercase-first () + (should-not (isogramp "alphAbet"))) + + +(ert-deftest hypothetical-isogrammic-word-with-hyphen () + (should (isogramp "thumbscrew-japingly"))) + + +(ert-deftest hypothetical-word-with-duplicated-character-following-hyphen () + (should-not (isogramp "thumbscrew-jappingly"))) + + +(ert-deftest isogram-with-duplicated-hyphen () + (should (isogramp "six-year-old"))) + + +(ert-deftest made-up-name-that-is-an-isogram () + (should (isogramp "Emily Jung Schwartzkopf"))) + + +(ert-deftest duplicated-character-in-the-middle () + (should-not (isogramp "accentor"))) + + +(ert-deftest same-first-and-last-characters () + (should-not (isogramp "angola"))) + + +(ert-deftest word-with-duplicated-character-and-with-two-hyphens () + (should-not (isogramp "up-to-date"))) + + +(provide 'isogram-test) +;;; isogram-test.el ends here diff --git a/exercises/practice/isogram/isogram.el b/exercises/practice/isogram/isogram.el new file mode 100644 index 00000000..699f0685 --- /dev/null +++ b/exercises/practice/isogram/isogram.el @@ -0,0 +1,13 @@ +;;; isogram.el --- isogram (exercism) -*- lexical-binding: t; -*- + +;;; Commentary: + +;;; Code: + + +(defun isogramp (phrase) + (error "Delete this S-Expression and write your own implementation")) + + +(provide 'isogram) +;;; isogram.el ends here