diff --git a/config.json b/config.json index 54698df..87e51f0 100644 --- a/config.json +++ b/config.json @@ -585,6 +585,22 @@ ], "difficulty": 2 }, + { + "slug": "say", + "name": "Say", + "uuid": "f8a4f68b-df8d-469f-9969-8b4f53c1b41b", + "practices": [ + "numbers", + "strings", + "conditionals" + ], + "prerequisites": [ + "numbers", + "strings", + "conditionals" + ], + "difficulty": 3 + }, { "slug": "secret-handshake", "name": "Secret Handshake", diff --git a/exercises/practice/say/.docs/instructions.md b/exercises/practice/say/.docs/instructions.md new file mode 100644 index 0000000..fb4a6df --- /dev/null +++ b/exercises/practice/say/.docs/instructions.md @@ -0,0 +1,50 @@ +# Instructions + +Given a number from 0 to 999,999,999,999, spell out that number in English. + +## Step 1 + +Handle the basic case of 0 through 99. + +If the input to the program is `22`, then the output should be `'twenty-two'`. + +Your program should complain loudly if given a number outside the blessed range. + +Some good test cases for this program are: + +- 0 +- 14 +- 50 +- 98 +- -1 +- 100 + +### Extension + +If you're on a Mac, shell out to Mac OS X's `say` program to talk out loud. +If you're on Linux or Windows, eSpeakNG may be available with the command `espeak`. + +## Step 2 + +Implement breaking a number up into chunks of thousands. + +So `1234567890` should yield a list like 1, 234, 567, and 890, while the far simpler `1000` should yield just 1 and 0. + +The program must also report any values that are out of range. + +## Step 3 + +Now handle inserting the appropriate scale word between those chunks. + +So `1234567890` should yield `'1 billion 234 million 567 thousand 890'` + +The program must also report any values that are out of range. +It's fine to stop at "trillion". + +## Step 4 + +Put it all together to get nothing but plain English. + +`12345` should give `twelve thousand three hundred forty-five`. + +The program must also report any values that are out of range. diff --git a/exercises/practice/say/.meta/config.json b/exercises/practice/say/.meta/config.json new file mode 100644 index 0000000..0a42b9d --- /dev/null +++ b/exercises/practice/say/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "ErikSchierboom" + ], + "files": { + "solution": [ + "src/say.cljs" + ], + "test": [ + "test/say_test.cljs" + ], + "example": [ + ".meta/src/example.cljs" + ] + }, + "blurb": "Given a number from 0 to 999,999,999,999, spell out that number in English.", + "source": "A variation on the JavaRanch CattleDrive, Assignment 4", + "source_url": "https://coderanch.com/wiki/718804" +} diff --git a/exercises/practice/say/.meta/src/example.cljs b/exercises/practice/say/.meta/src/example.cljs new file mode 100644 index 0000000..5cf3aa9 --- /dev/null +++ b/exercises/practice/say/.meta/src/example.cljs @@ -0,0 +1,9 @@ +(ns say + (:require [clojure.pprint :as pp] + [clojure.string :as s])) + +(defn number [input] + (if + (or (< input 0) (> input 999999999999)) + (throw (js/Error. "Out of range")) + (s/replace (pp/cl-format nil "~R" input) #"," ""))) diff --git a/exercises/practice/say/.meta/tests.toml b/exercises/practice/say/.meta/tests.toml new file mode 100644 index 0000000..df50fd1 --- /dev/null +++ b/exercises/practice/say/.meta/tests.toml @@ -0,0 +1,48 @@ +# This is an auto-generated file. Regular comments will be removed when this +# file is regenerated. Regenerating will not touch any manually added keys, +# so comments can be added in a "comment" key. + +[5d22a120-ba0c-428c-bd25-8682235d83e8] +description = "zero" + +[9b5eed77-dbf6-439d-b920-3f7eb58928f6] +description = "one" + +[7c499be1-612e-4096-a5e1-43b2f719406d] +description = "fourteen" + +[f541dd8e-f070-4329-92b4-b7ce2fcf06b4] +description = "twenty" + +[d78601eb-4a84-4bfa-bf0e-665aeb8abe94] +description = "twenty-two" + +[e417d452-129e-4056-bd5b-6eb1df334dce] +description = "one hundred" + +[d6924f30-80ba-4597-acf6-ea3f16269da8] +description = "one hundred twenty-three" + +[3d83da89-a372-46d3-b10d-de0c792432b3] +description = "one thousand" + +[865af898-1d5b-495f-8ff0-2f06d3c73709] +description = "one thousand two hundred thirty-four" + +[b6a3f442-266e-47a3-835d-7f8a35f6cf7f] +description = "one million" + +[2cea9303-e77e-4212-b8ff-c39f1978fc70] +description = "one million two thousand three hundred forty-five" + +[3e240eeb-f564-4b80-9421-db123f66a38f] +description = "one billion" + +[9a43fed1-c875-4710-8286-5065d73b8a9e] +description = "a big number" + +[49a6a17b-084e-423e-994d-a87c0ecc05ef] +description = "numbers below zero are out of range" + +[4d6492eb-5853-4d16-9d34-b0f61b261fd9] +description = "numbers above 999,999,999,999 are out of range" diff --git a/exercises/practice/say/deps.edn b/exercises/practice/say/deps.edn new file mode 100644 index 0000000..5c65da5 --- /dev/null +++ b/exercises/practice/say/deps.edn @@ -0,0 +1,10 @@ +{:deps + {org.clojure/clojure {:mvn/version "1.10.1"} + org.clojure/clojurescript {:mvn/version "1.10.773"}} + + :aliases + {:test + {:extra-paths ["test"] + :extra-deps + {olical/cljs-test-runner {:mvn/version "3.8.0"}} + :main-opts ["-m" "cljs-test-runner.main"]}}} diff --git a/exercises/practice/say/src/say.cljs b/exercises/practice/say/src/say.cljs new file mode 100644 index 0000000..1af8705 --- /dev/null +++ b/exercises/practice/say/src/say.cljs @@ -0,0 +1,5 @@ +(ns say) + +(defn number [num] ;; <- arglist goes here + ;; your code goes here +) diff --git a/exercises/practice/say/test/say_test.cljs b/exercises/practice/say/test/say_test.cljs new file mode 100644 index 0000000..68e6cc3 --- /dev/null +++ b/exercises/practice/say/test/say_test.cljs @@ -0,0 +1,48 @@ +(ns say-test + (:require [clojure.test :refer [deftest is]] + say)) + +(deftest zero-test + (is (= "zero" (say/number 0)))) + +(deftest one-test + (is (= "one" (say/number 1)))) + +(deftest fourteen-test + (is (= "fourteen" (say/number 14)))) + +(deftest twenty-test + (is (= "twenty" (say/number 20)))) + +(deftest twenty-two-test + (is (= "twenty-two" (say/number 22)))) + +(deftest one-hundred-test + (is (= "one hundred" (say/number 100)))) + +(deftest one-hundred-twenty-three-test + (is (= "one hundred twenty-three" (say/number 123)))) + +(deftest one-thousand-test + (is (= "one thousand" (say/number 1000)))) + +(deftest one-thousand-two-hundred-thirty-four-test + (is (= "one thousand two hundred thirty-four" (say/number 1234)))) + +(deftest one-million-test + (is (= "one million" (say/number 1000000)))) + +(deftest one-million-two-thousand-three-hundred-forty-five-test + (is (= "one million two thousand three hundred forty-five" (say/number 1002345)))) + +(deftest one-billion-test + (is (= "one billion" (say/number 1000000000)))) + +(deftest a-big-number-test + (is (= "nine hundred eighty-seven billion six hundred fifty-four million three hundred twenty-one thousand one hundred twenty-three" (say/number 987654321123)))) + +(deftest below-zero-is-out-of-range-test + (is (thrown? js/Error (say/number -1)))) + +(deftest numbers-above-999999999999-out-of-range-test + (is (thrown? js/Error (say/number 1000000000000))))