summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKjetil Orbekk <kj@orbekk.com>2021-11-25 10:54:40 -0500
committerKjetil Orbekk <kj@orbekk.com>2021-11-25 10:54:40 -0500
commitc0def58b13c9364e0815f0c931a86ee199b30493 (patch)
tree710ed51bb155b8de1f0e484e3a633d76ec280276
parent5218079d3f20b16514aa10d2c21824fd391d1f0d (diff)
Add word count exercise
-rw-r--r--exercism/emacs-lisp/word-count/.exercism/config.json23
-rw-r--r--exercism/emacs-lisp/word-count/.exercism/metadata.json1
-rw-r--r--exercism/emacs-lisp/word-count/HELP.md41
-rw-r--r--exercism/emacs-lisp/word-count/README.md50
-rw-r--r--exercism/emacs-lisp/word-count/word-count-test.el65
-rw-r--r--exercism/emacs-lisp/word-count/word-count.el28
6 files changed, 208 insertions, 0 deletions
diff --git a/exercism/emacs-lisp/word-count/.exercism/config.json b/exercism/emacs-lisp/word-count/.exercism/config.json
new file mode 100644
index 0000000..95e785a
--- /dev/null
+++ b/exercism/emacs-lisp/word-count/.exercism/config.json
@@ -0,0 +1,23 @@
+{
+ "blurb": "Given a phrase, count the occurrences of each word in that phrase.",
+ "authors": [],
+ "contributors": [
+ "canweriotnow",
+ "npostavs",
+ "vermiculus",
+ "wasamasa",
+ "yurrriq"
+ ],
+ "files": {
+ "solution": [
+ "word-count.el"
+ ],
+ "test": [
+ "word-count-test.el"
+ ],
+ "example": [
+ ".meta/example.el"
+ ]
+ },
+ "source": "This is a classic toy problem, but we were reminded of it by seeing it in the Go Tour."
+}
diff --git a/exercism/emacs-lisp/word-count/.exercism/metadata.json b/exercism/emacs-lisp/word-count/.exercism/metadata.json
new file mode 100644
index 0000000..b5d023f
--- /dev/null
+++ b/exercism/emacs-lisp/word-count/.exercism/metadata.json
@@ -0,0 +1 @@
+{"track":"emacs-lisp","exercise":"word-count","id":"66b39ed799384512ac08213e176ac353","url":"https://exercism.org/tracks/emacs-lisp/exercises/word-count","handle":"orbekk","is_requester":true,"auto_approve":false} \ No newline at end of file
diff --git a/exercism/emacs-lisp/word-count/HELP.md b/exercism/emacs-lisp/word-count/HELP.md
new file mode 100644
index 0000000..50effbd
--- /dev/null
+++ b/exercism/emacs-lisp/word-count/HELP.md
@@ -0,0 +1,41 @@
+# Help
+
+## Running the tests
+
+Tests can be run several ways:
+
+1. Interactively and individually, with `M-x ert RET test-name RET`
+2. Interactively and all at once, with `M-x ert RET t RET`
+3. From the terminal, in batch mode, with `emacs -batch -l ert -l my-test.el -f ert-run-tests-batch-and-exit`
+4. Other options can be found in the docs, `C-h i m ert RET`
+
+## Submitting your solution
+
+You can submit your solution using the `exercism submit word-count.el` command.
+This command will upload your solution to the Exercism website and print the solution page's URL.
+
+It's possible to submit an incomplete solution which allows you to:
+
+- See how others have completed the exercise
+- Request help from a mentor
+
+## Need to get help?
+
+If you'd like help solving the exercise, check the following pages:
+
+- The [Emacs Lisp track's documentation](https://exercism.org/docs/tracks/emacs-lisp)
+- [Exercism's support channel on gitter](https://gitter.im/exercism/support)
+- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
+
+Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
+
+To get help if you're having trouble, you can use one of the following resources:
+
+- [The Emacs Wiki](http://emacswiki.org/) is invaluable. Spend lots of time here.
+- [The Emacs Editor](http://www.gnu.org/software/emacs/manual/html_node/emacs/index.html) is the official manual for GNU Emacs.
+- IRC - there are [freenode](https://freenode.net/) channels for `#emacs`, `#prelude`, and many Emacs
+ packages, and many helpful folks around. And with emacs, IRC is as close as
+ `M-x erc`.
+- [Exercism Support](https://gitter.im/exercism/support) Gitter chat is also a good place to get help from the
+ exercism community.
+- [StackOverflow](http://stackoverflow.com/questions/tagged/elisp) can be used to search for your problem and see if it has been answered already. You can also ask and answer questions. \ No newline at end of file
diff --git a/exercism/emacs-lisp/word-count/README.md b/exercism/emacs-lisp/word-count/README.md
new file mode 100644
index 0000000..cf536c4
--- /dev/null
+++ b/exercism/emacs-lisp/word-count/README.md
@@ -0,0 +1,50 @@
+# Word Count
+
+Welcome to Word Count on Exercism's Emacs Lisp Track.
+If you need help running the tests or submitting your code, check out `HELP.md`.
+
+## Instructions
+
+Given a phrase, count the occurrences of each _word_ in that phrase.
+
+For the purposes of this exercise you can expect that a _word_ will always be one of:
+
+1. A _number_ composed of one or more ASCII digits (ie "0" or "1234") OR
+2. A _simple word_ composed of one or more ASCII letters (ie "a" or "they") OR
+3. A _contraction_ of two _simple words_ joined by a single apostrophe (ie "it's" or "they're")
+
+When counting words you can assume the following rules:
+
+1. The count is _case insensitive_ (ie "You", "you", and "YOU" are 3 uses of the same word)
+2. The count is _unordered_; the tests will ignore how words and counts are ordered
+3. Other than the apostrophe in a _contraction_ all forms of _punctuation_ are ignored
+4. The words can be separated by _any_ form of whitespace (ie "\t", "\n", " ")
+
+For example, for the phrase `"That's the password: 'PASSWORD 123'!", cried the Special Agent.\nSo I fled.` the count would be:
+
+```text
+that's: 1
+the: 2
+password: 2
+123: 1
+cried: 1
+special: 1
+agent: 1
+so: 1
+i: 1
+fled: 1
+```
+
+## Source
+
+### Contributed to by
+
+- @canweriotnow
+- @npostavs
+- @vermiculus
+- @wasamasa
+- @yurrriq
+
+### Based on
+
+This is a classic toy problem, but we were reminded of it by seeing it in the Go Tour. \ No newline at end of file
diff --git a/exercism/emacs-lisp/word-count/word-count-test.el b/exercism/emacs-lisp/word-count/word-count-test.el
new file mode 100644
index 0000000..1029b68
--- /dev/null
+++ b/exercism/emacs-lisp/word-count/word-count-test.el
@@ -0,0 +1,65 @@
+;;; word-count-test.el --- Tests for word-count (exercism)
+
+;;; Commentary:
+
+;;; Code:
+
+(load-file "word-count.el")
+
+
+(defun equal-assoc (a b)
+ (let ((strcmp (lambda (a b) (not (string< (car a) (car b))))))
+ (equal (sort (copy-sequence a) strcmp)
+ (sort (copy-sequence b) strcmp))))
+
+
+(ert-deftest no-words-test ()
+ (should (equal-assoc (word-count "")
+ nil)))
+
+
+(ert-deftest count-one-word-test ()
+ (should (equal-assoc (word-count "word")
+ '(("word" . 1)))))
+
+
+(ert-deftest count-one-of-each-word-test ()
+ (should (equal-assoc (word-count "one of each")
+ '(("each" . 1)
+ ("of" . 1)
+ ("one" . 1)))))
+
+
+(ert-deftest multiple-occurrences-of-a-word-test ()
+ (should (equal-assoc (word-count "one fish two fish red fish blue fish")
+ '(("blue" . 1)
+ ("red" . 1)
+ ("two" . 1)
+ ("fish" . 4)
+ ("one" . 1)))))
+
+
+(ert-deftest ignore-punctuation-test ()
+ (should (equal-assoc (word-count "car : carpet as java : javascript!!&@$%^&")
+ '(("javascript" . 1)
+ ("java" . 1)
+ ("as" . 1)
+ ("carpet" . 1)
+ ("car" . 1)))))
+
+
+(ert-deftest include-numbers-test ()
+ (should (equal-assoc (word-count "testing, 1, 2 testing")
+ '(("2" . 1)
+ ("1" . 1)
+ ("testing" . 2)))))
+
+
+(ert-deftest normalize-case-test ()
+ (should (equal-assoc (word-count "go Go GO Stop stop")
+ '(("stop" . 2)
+ ("go" . 3)))))
+
+
+(provide 'word-count)
+;;; word-count-test.el ends here
diff --git a/exercism/emacs-lisp/word-count/word-count.el b/exercism/emacs-lisp/word-count/word-count.el
new file mode 100644
index 0000000..bd51772
--- /dev/null
+++ b/exercism/emacs-lisp/word-count/word-count.el
@@ -0,0 +1,28 @@
+;;; word-count.el --- word-count Exercise (exercism)
+
+;;; Commentary:
+
+(require 'cl-extra)
+
+;;; Code:
+(defun kj/extract-words (str)
+ (let ((pos 0)
+ (result nil))
+ (while (string-match "[[:blank:]'\"]*\\([[:alnum:]']+\\)" str pos)
+ (setq pos (match-end 1))
+ (push (match-string 1 str) result))
+ (nreverse result)))
+
+(defun word-count (str)
+ (let* ((table (make-hash-table :test 'equal))
+ (result nil)
+ (count-word (lambda (w)
+ (setq w (downcase w))
+ (let ((count (gethash w table 0)))
+ (puthash w (1+ count) table))))
+ (push-output (lambda (w c)
+ (push (cons w c) result))))
+ (cl-mapc count-word (kj/extract-words str))
+ (maphash push-output table)
+ result))
+;;; word-count.el ends here