commit adbef525e5942818ac6f4ed75127389007e15a99
parent 2b8d338b5fa85447e118d2806326215c090b8d03
Author: dwrz <dwrz@dwrz.net>
Date: Sun, 20 Jan 2019 05:38:02 +0000
Add elisp/anagram
Work-in-progress.
Diffstat:
3 files changed, 110 insertions(+), 0 deletions(-)
diff --git a/elisp/anagram/README.md b/elisp/anagram/README.md
@@ -0,0 +1,13 @@
+# Anagram
+
+Given a word and a list of possible anagrams, select the correct sublist.
+
+Given `"listen"` and a list of candidates like `"enlists" "google"
+"inlets" "banana"` the program should return a list containing
+`"inlets"`.
+## Source
+
+Inspired by the Extreme Startup game [https://github.com/rchatley/extreme_startup](https://github.com/rchatley/extreme_startup)
+
+## Submitting Incomplete Solutions
+It's possible to submit an incomplete solution so you can see how others have completed the exercise.
diff --git a/elisp/anagram/anagram-test.el b/elisp/anagram/anagram-test.el
@@ -0,0 +1,53 @@
+;;; anagram-test.el --- Tests for Anagram (exercism)
+;;; Commentary:
+
+;;; Code:
+
+(load-file "anagram.el")
+
+(ert-deftest no-matches ()
+ (should (equal '() (anagrams-for
+ "diaper"
+ '("hello" "world" "zombies" "pants")))))
+
+(ert-deftest detect-simple-anagram ()
+ (should (equal '("tan") (anagrams-for
+ "ant"
+ '("tan" "stand" "at")))))
+
+(ert-deftest does-not-confuse-different-duplicates ()
+ (should (equal '() (anagrams-for
+ "galea"
+ '("eagle")))))
+
+(ert-deftest eliminate-anagram-subsets ()
+ (should (equal '() (anagrams-for
+ "good"
+ '("dog" "goody")))))
+
+(ert-deftest detect-anagram ()
+ (should (equal '("inlets") (anagrams-for
+ "listen"
+ '("enlists" "google" "inlets" "banana")))))
+
+(ert-deftest multiple-anagrams ()
+ (should (equal '("gallery" "regally" "largely")
+ (anagrams-for
+ "allergy"
+ '("gallery" "ballerina" "regally" "clergy" "largely" "leading")))))
+
+(ert-deftest case-insensitive-anagrams ()
+ (should (equal '("Carthorse")
+ (anagrams-for
+ "Orchestra"
+ '("cashregister" "Carthorse" "radishes")))))
+
+(ert-deftest word-is-not-own-anagram ()
+ (should (equal '()
+ (anagrams-for
+ "banana"
+ '("banana")))))
+
+
+(provide 'anagram-test)
+;;; anagram-test.el ends here
diff --git a/elisp/anagram/anagram.el b/elisp/anagram/anagram.el
@@ -0,0 +1,44 @@
+;;; anagram.el --- Anagram (exercism)
+
+;;; Commentary:
+
+;;; Code:
+
+(require 'cl)
+
+(provide 'anagram)
+
+(defun make-char-count(s)
+ (let ((char-list (mapcar (lambda (char) (string char)) s))
+ (char-counts ()))
+ ;; Build an associative list from the character list.
+ (dolist (char char-list char-counts)
+ (if (assoc char char-counts)
+ (setcdr (assoc char char-counts)
+ (1+ (cdr (assoc char char-counts))))
+ (setq char-counts (cons (cons char 1) char-counts))))))
+
+(defun compare-char-counts(char-counts comparison-char-counts)
+ (let ((are-equal t))
+ (dolist (char-count char-counts are-equal)
+ (if (not are-equal) nil)
+ (if (assoc (car char-count) comparison-char-counts)
+ (if (not (equal
+ (cdr char-count)
+ (cdr (assoc (car char-count) comparison-char-counts))))
+ (setq are-equal nil))
+ (setq are-equal nil)))))
+
+(defun anagrams-for(word anagrams)
+ (let ((candidates ())
+ (word-char-count (make-char-count word)))
+ (dolist (candidate anagrams candidates)
+ (if (and
+ (not (string-equal word candidate))
+ (equal (length word) (length candidate))
+ (compare-char-counts word-char-count (make-char-count candidate)))
+ (if (> (length candidates) 0)
+ (add-to-list 'candidates candidate t)
+ (setq candidates (cons candidate nil)))))))
+
+;;; anagram.el ends here