From c0def58b13c9364e0815f0c931a86ee199b30493 Mon Sep 17 00:00:00 2001 From: Kjetil Orbekk Date: Thu, 25 Nov 2021 10:54:40 -0500 Subject: Add word count exercise --- .../emacs-lisp/word-count/.exercism/config.json | 23 ++++++++ .../emacs-lisp/word-count/.exercism/metadata.json | 1 + exercism/emacs-lisp/word-count/HELP.md | 41 ++++++++++++++ exercism/emacs-lisp/word-count/README.md | 50 +++++++++++++++++ exercism/emacs-lisp/word-count/word-count-test.el | 65 ++++++++++++++++++++++ exercism/emacs-lisp/word-count/word-count.el | 28 ++++++++++ 6 files changed, 208 insertions(+) create mode 100644 exercism/emacs-lisp/word-count/.exercism/config.json create mode 100644 exercism/emacs-lisp/word-count/.exercism/metadata.json create mode 100644 exercism/emacs-lisp/word-count/HELP.md create mode 100644 exercism/emacs-lisp/word-count/README.md create mode 100644 exercism/emacs-lisp/word-count/word-count-test.el create mode 100644 exercism/emacs-lisp/word-count/word-count.el 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 -- cgit v1.2.3