commit 3019fd50df4da5ab744bdab58d70f5e6d72ea448
parent 5fb38c0bcc5930435ac4d8ff7442d9a8854be03d
Author: dwrz <dwrz@dwrz.net>
Date: Sun, 6 Jan 2019 21:13:30 +0000
Add elisp/bob
Diffstat:
3 files changed, 185 insertions(+), 0 deletions(-)
diff --git a/elisp/bob/README.md b/elisp/bob/README.md
@@ -0,0 +1,20 @@
+# Bob
+
+Bob is a lackadaisical teenager. In conversation, his responses are very limited.
+
+Bob answers 'Sure.' if you ask him a question.
+
+He answers 'Whoa, chill out!' if you yell at him.
+
+He answers 'Calm down, I know what I'm doing!' if you yell a question at him.
+
+He says 'Fine. Be that way!' if you address him without actually saying
+anything.
+
+He answers 'Whatever.' to anything else.
+## Source
+
+Inspired by the 'Deaf Grandma' exercise in Chris Pine's Learn to Program tutorial. [http://pine.fm/LearnToProgram/?Chapter=06](http://pine.fm/LearnToProgram/?Chapter=06)
+
+## 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/bob/bob-test.el b/elisp/bob/bob-test.el
@@ -0,0 +1,110 @@
+;;; bob-test.el --- ERT tests for Bob (exercism)
+
+;;; Commentary:
+;; Common test data version: 1.2.0 6dc2014
+
+;;; Code:
+
+(load-file "bob.el")
+
+(ert-deftest responds-to-stating-something ()
+ (should (string= "Whatever." (response-for "Tom-ay-to, tom-aaaah-to."))))
+
+(ert-deftest responds-to-shouting ()
+ (should
+ (string= "Whoa, chill out!" (response-for "WATCH OUT!"))))
+
+(ert-deftest responds-to-shouting-gibberish ()
+ (should
+ (string= "Whoa, chill out!" (response-for "FCECDFCAAB"))))
+
+(ert-deftest responds-to-asking-a-question ()
+ (should
+ (string= "Sure." (response-for "Does this cryogenic chamber make me look fat?"))))
+
+(ert-deftest responds-to-asking-a-numeric-question ()
+ (should
+ (string= "Sure." (response-for "You are, what, like 15?"))))
+
+(ert-deftest responds-to-asking-gibberish ()
+ (should
+ (string= "Sure." (response-for "fffbbcbeab?"))))
+
+(ert-deftest responds-to-talking-forcefully ()
+ (should
+ (string= "Whatever." (response-for "Let's go make out behind the gym!"))))
+
+(ert-deftest responds-to-using-acronyms-in-regular-speech ()
+ (should
+ (string= "Whatever." (response-for "It's OK if you don't want to go to the DMV."))))
+
+(ert-deftest responds-to-forceful-question ()
+ (should
+ (string= "Calm down, I know what I'm doing!" (response-for "WHAT THE HELL WERE YOU THINKING?"))))
+
+(ert-deftest responds-to-shouting-numbers ()
+ (should
+ (string= "Whoa, chill out!" (response-for "1, 2, 3, GO!"))))
+
+(ert-deftest responds-to-only-numbers ()
+ (should
+ (string= "Whatever." (response-for "1, 2, 3"))))
+
+(ert-deftest responds-to-questions-with-only-numbers ()
+ (should
+ (string= "Sure." (response-for "4?"))))
+
+(ert-deftest responds-to-shouting-with-special-chars ()
+ (should
+ (string= "Whoa, chill out!" (response-for "ZOMG THE %^*@#$(*^ ZOMBIES ARE COMING!!11!!1!"))))
+
+(ert-deftest responds-to-shouting-with-no-exclamation-mark ()
+ (should
+ (string= "Whoa, chill out!" (response-for "I HATE YOU"))))
+
+(ert-deftest responds-to-statement-containing-question-mark ()
+ (should
+ (string= "Whatever." (response-for "Ending with ? means a question."))))
+
+(ert-deftest responds-to-non-letters-with-question ()
+ (should
+ (string= "Sure." (response-for ":) ?"))))
+
+(ert-deftest responds-to-prattling-on ()
+ (should
+ (string= "Sure." (response-for "Wait! Hang on. Are you going to be OK?"))))
+
+(ert-deftest responds-to-silence ()
+ (should
+ (string= "Fine. Be that way!" (response-for ""))))
+
+(ert-deftest responds-to-prolonged-silence ()
+ (should
+ (string= "Fine. Be that way!" (response-for " "))))
+
+(ert-deftest responds-to-alternate-silence ()
+ (should
+ (string= "Fine. Be that way!" (response-for "\t\t\t\t\t\t\t\t\t\t"))))
+
+(ert-deftest responds-to-multiple-line-question ()
+ (should
+ (string= "Whatever." (response-for "\nDoes this cryogenic chamber make me look fat?\nno"))))
+
+(ert-deftest responds-to-starting-with-whitespace ()
+ (should
+ (string= "Whatever." (response-for " hmmmmmmm..."))))
+
+(ert-deftest responds-to-ending-with-whitespace ()
+ (should
+ (string= "Sure." (response-for "Okay if like my spacebar quite a bit? "))))
+
+(ert-deftest responds-to-other-whitespace ()
+ (should
+ (string= "Fine. Be that way!" (response-for "\n\r \t"))))
+
+(ert-deftest responds-to-non-question-ending-with-whitespace ()
+ (should
+ (string= "Whatever." (response-for "This is a statement ending with whitespace "))))
+
+(provide 'bob-test)
+;;;bob-test.el ends here
diff --git a/elisp/bob/bob.el b/elisp/bob/bob.el
@@ -0,0 +1,55 @@
+;;; bob.el --- Bob exercise (exercism)
+
+;;; Commentary:
+;;; Bob implements categorical responses to queries.
+
+;;; Code:
+
+(provide 'bob)
+
+(require 'subr-x)
+
+(defun is-all-caps(s)
+ "Determine whether a string, S, is all capitalized. Return nil if a string has no alpha characters."
+ (let ((case-fold-search nil)) ; make the regex case-sensitive
+ (and (not (string-match-p "[[:lower:]]" s))
+ (not (equal (upcase s) (downcase s)))
+ (> (length s)0))))
+
+(defun is-forceful-question(formatted-query)
+ "Determine whether FORMATTED-QUERY is a forceful question;
+i.e., all capitals and ending in a question mark."
+ (and (is-all-caps (substring formatted-query 0 -1))
+ (is-question formatted-query)))
+
+(defun is-question(formatted-query)
+ "Determine whether FORMATTED-QUERY is a question;
+i.e., ending with a question mark."
+ (string-suffix-p "?" formatted-query))
+
+(defun is-shouting(formatted-query)
+ "Determine whether FORMATTED-QUERY is shouting;
+i.e., either all capitals only or all capitals ending with an exclamation
+mark."
+ (if (not (is-question formatted-query))
+ (cond ((is-all-caps formatted-query) t)
+ ((and (is-all-caps (substring formatted-query 0 -1))
+ (string-suffix-p "!" formatted-query)) t))))
+
+(defun is-silence(formatted-query)
+ "Determine whether FORMATTED-QUERY is silence; i.e., of zero length."
+ (= (length formatted-query) 0))
+
+(defun response-for(query)
+ "Determine the response to QUERY.
+Begins by trimming whitespace, then checking the QUERY type on a
+case-by-case basis."
+ (let ((formatted-query (string-trim query)))
+ (cond ((is-silence formatted-query) "Fine. Be that way!")
+ ((is-forceful-question formatted-query)
+ "Calm down, I know what I'm doing!")
+ ((is-shouting formatted-query) "Whoa, chill out!")
+ ((is-question formatted-query) "Sure.")
+ (t "Whatever."))))
+
+;;; bob.el ends here