Repository: exercism/clojure
Pull request #686 (2024-10-15 13:10:42)

Deprecate exercises
Since **'All your base'** has been implemented, the following exercises are marked as deprecated:
1. Binary
2. Trinary
3. Octal
4. Hexadecimal

I've also deprecated **'accumulate'** since **'list-ops'** will be published soon. Therefore, I'm marking the current PR as draft. It will be merged after https://github.com/exercism/clojure/pull/685


Patch:
diff --git a/_src/clock_generator.clj b/_generators/clock_generator.clj
similarity index 100%
rename from _src/clock_generator.clj
rename to _generators/clock_generator.clj
diff --git a/_src/generator.clj b/_generators/generator.clj
similarity index 100%
rename from _src/generator.clj
rename to _generators/generator.clj
diff --git a/_generators/list-ops-generator.clj b/_generators/list-ops-generator.clj
new file mode 100644
index 0000000..59f7213
--- /dev/null
+++ b/_generators/list-ops-generator.clj
@@ -0,0 +1,177 @@
+#!/usr/bin/env bb
+
+(require '[cheshire.core :as json]
+         '[babashka.fs :as fs]
+         '[clojure.string :as str]
+         '[clojure.edn :as edn])
+
+(comment
+  (def slug "list-ops"))
+
+(def data
+  (let [url "https://raw.githubusercontent.com/exercism/problem-specifications/main/exercises/"]
+    {:canonical-data (json/parse-string (slurp (str url "/" slug "/canonical-data.json")) true)
+     :description (slurp (str url "/" slug "/description.md"))
+     :metadata (slurp (str url "/" slug "/metadata.toml"))}))
+
+(second
+ (str/split (:metadata data) #"="))
+
+(defn get-meta 
+  "Returns a vector containing the exercise title and blurb"
+  [data]
+  (mapv last
+       (map #(map str/trim (str/split % #"="))
+            (str/split-lines (:metadata data)))))
+
+(defn init-deps! [data]
+  (fs/create-dirs (fs/path "exercises" "practice"
+                           (:exercise (:canonical-data data)) "src"))
+  (spit (str (fs/file "exercises" "practice"
+                      (:exercise (:canonical-data data))
+                      "deps.edn"))
+        "{:aliases {:test {:extra-paths [\"test\"]
+                 :extra-deps {io.github.cognitect-labs/test-runner 
+                              {:git/url \"https://github.com/cognitect-labs/test-runner.git\"
+                               :sha \"705ad25bbf0228b1c38d0244a36001c2987d7337\"}}
+                 :main-opts [\"-m\" \"cognitect.test-runner\"]
+                 :exec-fn cognitect.test-runner.api/test}}}"))
+
+(comment
+  (init-deps! data)
+  )
+
+(defn init-lein! [data]
+  (let [slug (:exercise (:canonical-data data))]
+    (spit (str (fs/file "exercises" "practice"
+                        (:exercise (:canonical-data data)) "project.clj"))
+          (str "(defproject " slug " \"0.1.0-SNAPSHOT\"
+  :description \"" slug " exercise.\"
+  :url \"https://github.com/exercism/clojure/tree/main/exercises/" slug "\"
+  :dependencies [[org.clojure/clojure \"1.10.0\"]])
+"))))
+
+(comment
+  (init-lein! data)
+  )
+
+(defn test-ns-form [data]
+  (str "(ns " (:exercise data) "-test
+  (:require [clojure.test :refer [deftest testing is]]\n             "
+       (:exercise data) "))\n\n"))
+
+(defn src-ns-form [data]
+  (str "(ns " (:exercise data) ")\n\n"))
+
+(defn trans-fn [s]
+  (let [[args body] (str/split s #"->")
+        arg-strs (mapv str (edn/read-string args))
+        [arg1 op arg2] (str/split (str/trim body) #"\s")]
+    (str "(fn [" (apply str (interpose " " arg-strs)) "] " 
+         "(" op " " arg1 " " arg2 "))")))
+
+(comment
+  (trans-fn "(x) -> x + 1")  
+  (trans-fn "(x, y) -> x * y")
+  (trans-fn "(acc, el) -> el * acc")
+  )
+
+(defn testing-form [slug test-case]
+  (let [property (symbol (str slug "/" (:property test-case)))
+        input (:input test-case)
+        args (map #(get input %) (keys input))]
+    (str "  (testing \"" (:description test-case) "\"
+     (is (= " (:expected test-case) " "
+         (reverse (into (list property) args)) ")))")))
+
+(comment
+  (testing-form "list-ops" (first (:cases (first (:cases (:canonical-data data))))))
+  )
+
+(defn testing-forms
+  "Outputs a sequence of the test cases for a given property name
+   given its name as a string and the canonical data."
+  [property data]
+  (let [test-cases (filter #(= property (:property %))
+                           (mapcat :cases
+                                   (:cases (:canonical-data data))))]
+    (map #(testing-form (:exercise (:canonical-data data)) %) test-cases)))
+
+(comment
+  (testing-forms "append" data)
+  )
+
+(defn deftest-forms [data]
+  (for [property (distinct (map :property (mapcat :cases
+                                                  (:cases (:canonical-data data)))))]
+    (str "(deftest " property "-test\n"
+         (apply str (interpose "\n"
+                               (testing-forms property data)))
+         ")")))
+
+(comment
+  (deftest-forms data)
+  )
+
+(defn init-tests! [data]
+  (let [path (fs/path "exercises" "practice"
+                      (:exercise (:canonical-data data)) "test")]
+    (when-not (fs/directory? path)
+      (fs/create-dir path))
+    (spit (str (fs/file "exercises" "practice"
+                        (:exercise (:canonical-data data)) "test"
+                        (str (str/replace (:exercise (:canonical-data data)) "-" "_")
+                             "_test.clj")))
+          (str (test-ns-form (:canonical-data data))
+               (apply str (interpose "\n\n"
+                                     (deftest-forms data)))))))
+
+(comment
+  (init-tests! data)
+  )
+
+(defn init-src! [data]
+  (spit (str (fs/file "exercises" "practice" (:exercise (:canonical-data data)) "src"
+                      (str (str/replace (:exercise (:canonical-data data))
+                                        "-" "_") ".clj")))
+        (str (src-ns-form (:canonical-data data))
+             (apply str (interpose "\n\n"
+                                   (for [property (distinct (map :property (mapcat :cases
+                                                                                   (:cases (:canonical-data data)))))]
+                                     (str "(defn " property " []\n  )")))))))
+
+(comment
+  (init-src! data)
+  )
+
+(defn init-description! [data]
+  (let [path ["exercises" "practice" (:exercise (:canonical-data data)) ".docs"]]
+    (when-not (fs/directory? (apply fs/path path))
+      (fs/create-dir (apply fs/path path))
+      (spit (str (apply fs/file (conj path "instructions.md")))
+            (:description data)))))
+
+(comment
+  (init-description! data)
+  )
+
+(defn config [data author blurb]
+  (let [slug (:exercise (:canonical-data data))]
+    {:authors [author],
+     :contributors [],
+     :files {:solution [(str "src/" (str/replace slug "-" "_") ".clj")], 
+             :test [(str "test/" (str/replace slug "-" "_") "_test.clj")], 
+             :example [".meta/src/example.clj"]},
+     :blurb blurb}))
+
+(defn init-config! [data]
+  (let [path ["exercises" "practice" (:exercise (:canonical-data data)) ".meta"]]
+    (when-not (fs/directory? (apply fs/path path))
+   (fs/create-dirs (apply fs/path (conj path "src")))
+      (spit (str (apply fs/file (conj path "config.json")))
+            (json/generate-string (config data "porkostomus" (last (get-meta data)))
+                                  {:pretty true})))))
+
+(comment
+  (init-config! data)
+  )
\ No newline at end of file
diff --git a/generator.clj b/_generators/zipper-generator.clj
similarity index 96%
rename from generator.clj
rename to _generators/zipper-generator.clj
index 3c97c75..6ac5848 100644
--- a/generator.clj
+++ b/_generators/zipper-generator.clj
@@ -16,12 +16,12 @@
 (second
  (str/split (:metadata data) #"="))
 
-(defn get-meta 
+(defn get-meta
   "Returns a vector containing the exercise title and blurb"
   [data]
   (mapv last
-       (map #(map str/trim (str/split % #"="))
-            (str/split-lines (:metadata data)))))
+        (map #(map str/trim (str/split % #"="))
+             (str/split-lines (:metadata data)))))
 
 (defn init-deps [data]
   (fs/create-dirs (fs/path "exercises" "practice"
@@ -122,19 +122,18 @@
   (let [slug (:exercise (:canonical-data data))]
     {:authors [author],
      :contributors [],
-     :files {:solution [(str "src/" (str/replace slug "-" "_") ".clj")], 
-             :test [(str "test/" (str/replace slug "-" "_") "_test.clj")], 
+     :files {:solution [(str "src/" (str/replace slug "-" "_") ".clj")],
+             :test [(str "test/" (str/replace slug "-" "_") "_test.clj")],
              :example [".meta/src/example.clj"]},
      :blurb blurb}))
 
 (defn init-config! [data]
   (let [path ["exercises" "practice" (:exercise (:canonical-data data)) ".meta"]]
     (when-not (fs/directory? (apply fs/path path))
-   (fs/create-dirs (apply fs/path (conj path "src")))
+      (fs/create-dirs (apply fs/path (conj path "src")))
       (spit (str (apply fs/file (conj path "config.json")))
             (json/generate-string (config data "porkostomus" (last (get-meta data)))
                                   {:pretty true})))))
 
 (comment
-  (init-config! data)
-  )
\ No newline at end of file
+  (init-config! data))
\ No newline at end of file
diff --git a/config.json b/config.json
index aacb72e..69d6916 100644
--- a/config.json
+++ b/config.json
@@ -243,13 +243,12 @@
         "name": "Accumulate",
         "uuid": "49f62bbc-0f60-4922-b5a6-f266b80442f4",
         "practices": [],
-        "prerequisites": [
-          "numbers"
-        ],
+        "prerequisites": [],
         "difficulty": 2,
         "topics": [
           "algorithms, core_functions"
-        ]
+        ],
+        "status": "deprecated"
       },
       {
         "slug": "acronym",
@@ -349,6 +348,16 @@
           "math"
         ]
       },
+      {
+        "slug": "eliuds-eggs",
+        "name": "Eliud's Eggs",
+        "uuid": "bfe1789f-8388-4285-bed9-26f694e12c70",
+        "practices": [],
+        "prerequisites": [
+          "basics"
+        ],
+        "difficulty": 2
+      },
       {
         "slug": "etl",
         "name": "ETL",
@@ -734,13 +743,12 @@
         "name": "Binary",
         "uuid": "daf3daed-61ef-4964-8d33-e7a739c7a470",
         "practices": [],
-        "prerequisites": [
-          "numbers"
-        ],
+        "prerequisites": [],
         "difficulty": 3,
         "topics": [
           "math"
-        ]
+        ],
+        "status": "deprecated"
       },
       {
         "slug": "binary-search",
@@ -846,13 +854,12 @@
         "name": "Hexadecimal",
         "uuid": "a4b1b39a-d942-4921-9b67-2bd913ff52a0",
         "practices": [],
-        "prerequisites": [
-          "numbers"
-        ],
+        "prerequisites": [],
         "difficulty": 3,
         "topics": [
           "math"
-        ]
+        ],
+        "status": "deprecated"
       },
       {
         "slug": "isbn-verifier",
@@ -1009,14 +1016,12 @@
         "name": "Trinary",
         "uuid": "f8a7f5eb-e317-4ffa-bdef-6e30a36511eb",
         "practices": [],
-        "prerequisites": [
-          "numbers",
-          "strings"
-        ],
+        "prerequisites": [],
         "difficulty": 3,
         "topics": [
           "math"
-        ]
+        ],
+        "status": "deprecated"
       },
       {
         "slug": "allergies",
@@ -1111,16 +1116,13 @@
         "slug": "octal",
         "name": "Octal",
         "uuid": "fa596153-0cbe-40e9-a4d6-1a66fe6ef7e5",
-        "practices": [
-          "numbers"
-        ],
-        "prerequisites": [
-          "numbers"
-        ],
+        "practices": [],
+        "prerequisites": [],
         "difficulty": 4,
         "topics": [
           "math"
-        ]
+        ],
+        "status": "deprecated"
       },
       {
         "slug": "spiral-matrix",
@@ -1365,10 +1367,10 @@
         "practices": [],
         "prerequisites": [
           "lists",
-          "closures"
+          "closures",
+          "vectors"
         ],
-        "difficulty": 5,
-        "status": "wip"
+        "difficulty": 5
       }
     ]
   },
diff --git a/exercises/concept/annalyns-infiltration/.docs/hints.md b/exercises/concept/annalyns-infiltration/.docs/hints.md
index 6d7ccd6..9d417d4 100644
--- a/exercises/concept/annalyns-infiltration/.docs/hints.md
+++ b/exercises/concept/annalyns-infiltration/.docs/hints.md
@@ -6,11 +6,11 @@ We need to check if the knight is awake and _invert_ its truth value. This can b
 
 ## 2. Check if the group can be spied upon
 
-We want the function to return `true` if _any_ of the supplied predicates are true. This can be done using the [`or`][or] function.
+We want the function to return `true` if _any_ of the supplied predicates are `true`. This can be done using the [`or`][or] function.
 
 ## 3. Check if the prisoner can be signalled
 
-We want to return `true` if and only if _all_ of the supplied predicates are truthy. This can be done with the [`and`][and] function.
+We want to return `true` if and only if _all_ of the supplied predicates are `true`. This can be done with the [`and`][and] function.
 
 ## 4. Check if the prisoner can be freed
 
diff --git a/exercises/concept/annalyns-infiltration/.docs/instructions.md b/exercises/concept/annalyns-infiltration/.docs/instructions.md
index 2b2b330..b5b7976 100644
--- a/exercises/concept/annalyns-infiltration/.docs/instructions.md
+++ b/exercises/concept/annalyns-infiltration/.docs/instructions.md
@@ -20,7 +20,7 @@ You have four tasks: to implement the logic for determining if the above actions
 
 ## 1. Check if a fast attack can be made
 
-Implement the `can-fast-attack?` function that takes a boolean value that indicates if the knight is awake. This function returns `true` if a fast attack can be made based on the state of the knight. Otherwise, returns `false`:
+Implement the `can-fast-attack?` function, which takes a boolean value indicating whether the knight is awake. The function returns `true` if a fast attack can be made based on the state of the knight. Otherwise, it returns `false`:
 
 ```clojure
 (def knight-awake? true)
@@ -31,7 +31,7 @@ Implement the `can-fast-attack?` function that takes a boolean value that indica
 
 ## 2. Check if the group can be spied upon
 
-Implement the `can-spy?` function that takes three boolean values, indicating if the knight, archer and the prisoner, respectively, are awake. The function returns `true` if the group can be spied upon, based on the state of the three characters. Otherwise, returns `false`:
+Implement the `can-spy?` function, which takes three boolean values indicating whether the knight, archer and the prisoner, respectively, are awake. The function returns `true` if the group can be spied upon based on the state of the three characters. Otherwise, it returns `false`:
 
 ```clojure
 (def knight-awake? false)
@@ -44,7 +44,7 @@ Implement the `can-spy?` function that takes three boolean values, indicating if
 
 ## 3. Check if the prisoner can be signalled
 
-Implement the `can-signal-prisoner?` function that takes two boolean values, indicating if the archer and the prisoner, respectively, are awake. The function returns `true` if the prisoner can be signalled, based on the state of the two characters. Otherwise, returns `false`:
+Implement the `can-signal-prisoner?` function, which takes two boolean values indicating whether the archer and the prisoner, respectively, are awake. The function returns `true` if the prisoner can be signalled based on the state of the two characters. Otherwise, it returns `false`:
 
 ```clojure
 (def archer-awake? false)
@@ -56,7 +56,7 @@ Implement the `can-signal-prisoner?` function that takes two boolean values, ind
 
 ## 4. Check if the prisoner can be freed
 
-Implement the `can-free-prisoner?` function that takes four boolean values. The first three parameters indicate if the knight, archer and the prisoner, respectively, are awake. The last parameter indicates if Annalyn's pet dog is present. The function returns `true` if the prisoner can be freed based on the state of the three characters and Annalyn's pet dog presence. Otherwise, it returns `false`:
+Implement the `can-free-prisoner?` function, which takes four boolean values. The first three parameters indicate whether the knight, archer and the prisoner, respectively, are awake. The last parameter indicates whether Annalyn's pet dog is present. The function returns `true` if the prisoner can be freed based on the state of the three characters and Annalyn's pet dog presence. Otherwise, it returns `false`:
 
 ```clojure
 (def knight-awake? false)
diff --git a/exercises/concept/annalyns-infiltration/.docs/introduction.md b/exercises/concept/annalyns-infiltration/.docs/introduction.md
index 6fbaa4a..e116426 100644
--- a/exercises/concept/annalyns-infiltration/.docs/introduction.md
+++ b/exercises/concept/annalyns-infiltration/.docs/introduction.md
@@ -2,6 +2,6 @@
 
 Booleans in Clojure are represented by `true` or `false`.
 
-Predicate functions (functions which return a boolean) will typically end with a quesion mark (`?`), but this is by convention only.
+Predicate functions (functions which return a boolean) will typically end with a question mark (`?`), but this is by convention only.
 
 The core library includes functions for logical operators such as `not`, `and`, and `or`.
diff --git a/exercises/concept/bird-watcher/.docs/hints.md b/exercises/concept/bird-watcher/.docs/hints.md
index e32ffb0..7dd02b2 100644
--- a/exercises/concept/bird-watcher/.docs/hints.md
+++ b/exercises/concept/bird-watcher/.docs/hints.md
@@ -6,7 +6,7 @@
 
 ## 2. Check how many birds visited today
 
-- The [`last`][last] function can be used to return the last item in a sequential collection.
+- The [`peek`][peek] function can be used to return the last item in a vector.
 
 ## 3. Increment today's count
 
@@ -20,13 +20,13 @@
 
 - The [`every?`][every?] function can be used to check if all items in a collection satisfy a given predicate.
 
-- The [`pos?`][pos?] predicate returns true if a number is greater than zero.
+- The [`pos?`][pos?] predicate returns `true` if a number is greater than zero.
 
-- The [`not`][not] function returns true if an expression evaluates to logical false.
+- The [`not`][not] function returns `true` if an expression evaluates to logical false.
 
 ## 5. Calculate the number of visiting birds for the first number of days
 
-- The [`take`][take] function can be used return a sequence of the first n items in a collection.
+- The [`take`][take] function can be used to return a sequence of the first n items in a collection.
 
 - The [`reduce`][reduce] function can be used to add a collection of values together.
 
@@ -36,7 +36,7 @@
 
 ## 7.  Check for odd week
 
-- The [`=`][equality] function can be used to test equality.
+- The [`=`][equality] function can be used to test for equality.
 
 [count]: https://clojuredocs.org/clojure.core/count
 [dec]: https://clojuredocs.org/clojure.core/dec
@@ -44,7 +44,7 @@
 [every?]: https://clojuredocs.org/clojure.core/every_q
 [filter]: https://clojuredocs.org/clojure.core/filter
 [inc]: https://clojuredocs.org/clojure.core/inc
-[last]: https://clojuredocs.org/clojure.core/last
+[peek]: https://clojuredocs.org/clojure.core/peek
 [not]: https://clojuredocs.org/clojure.core/not
 [pos?]: https://clojuredocs.org/clojure.core/pos_q
 [reduce]: https://clojuredocs.org/clojure.core/reduce
diff --git a/exercises/concept/bird-watcher/.docs/instructions.md b/exercises/concept/bird-watcher/.docs/instructions.md
index a3ce8b3..121782c 100755
--- a/exercises/concept/bird-watcher/.docs/instructions.md
+++ b/exercises/concept/bird-watcher/.docs/instructions.md
@@ -62,7 +62,7 @@ Implement the `busy-days` function to return the number of busy days:
 
 ## 7. Check for odd week
 
-Over the last year, you've found that some weeks for the same, odd pattern, where the counts alternate between one and zero birds visiting. Implement the `odd-week?` function that returns `true` if the bird count pattern of this week matches the odd pattern:
+Over the last year, you've found that some weeks form the same, odd pattern, where the counts alternate between one and zero birds visiting. Implement the `odd-week?` function that returns `true` if the bird count pattern of this week matches the odd pattern:
 
 ```clojure
 (odd-week? [1 0 1 0 1 0 1])
diff --git a/exercises/concept/bird-watcher/.docs/introduction.md b/exercises/concept/bird-watcher/.docs/introduction.md
index c6b28b3..a8f2eba 100755
--- a/exercises/concept/bird-watcher/.docs/introduction.md
+++ b/exercises/concept/bird-watcher/.docs/introduction.md
@@ -6,7 +6,7 @@ A `vector` in Clojure is a sequential, indexed, immutable collection of zero or
 (def empty [])
 (def single-value [5])
 (def single-value-alternative (vector 5))
-(def three-values [a b c])
+(def three-values [1 "a" "b"])
 ```
 
 Elements can be retrieved from a vector using an index. Clojure vectors are zero-based, meaning that the first element's index is always zero:
diff --git a/exercises/concept/bird-watcher/.meta/exemplar.clj b/exercises/concept/bird-watcher/.meta/exemplar.clj
index 7473988..cfdb65a 100644
--- a/exercises/concept/bird-watcher/.meta/exemplar.clj
+++ b/exercises/concept/bird-watcher/.meta/exemplar.clj
@@ -3,13 +3,13 @@
 (def last-week [0 2 5 3 7 8 4])
 
 (defn today [birds]
-  (last birds))
+  (peek birds))
 
 (defn inc-bird [birds]
   (update birds (dec (count birds)) inc))
 
 (defn day-without-birds? [birds]
-  (pos? (count (filter zero? birds))))
+  (not (every? pos? birds)))
 
 (defn n-days-count [birds n]
   (reduce + (take n birds)))
diff --git a/exercises/concept/card-games/.docs/hints.md b/exercises/concept/card-games/.docs/hints.md
index 3013115..d37b8cc 100644
--- a/exercises/concept/card-games/.docs/hints.md
+++ b/exercises/concept/card-games/.docs/hints.md
@@ -11,18 +11,18 @@
 ## 3. Finding Prior Rounds
 
 - The [`some`][some] function will return the first logically true value in a collection.
-- [`boolean`][boolean] is useful in cases where a function returns a value but the tests are expecting a boolean.
+- The [`boolean`][boolean] function is useful in cases where a function returns a value but the tests are expecting a boolean.
 
 ## 4. Averaging Card Values
 
 - Recall basic arithmetic operators such as [`/`][division] and [`+`][addition].
 - A collection of numbers can be summed using either [`apply`][apply] or [`reduce`][reduce].
 - The [`count`][count] function returns the number of items in a collection.
-- The `/` function returns a ratio type when operating on integers. You can use [`double`][double] to convert a ratio to a decimal.
+- The [`/`][division] function returns a ratio type when operating on integers. You can use [`double`][double] to convert a ratio to a decimal.
 
 ## 5. Alternate Averages
 
-- There are sequence functions to return the [`first`][first] or [`last`] element of a sequential collection.
+- There are sequence functions to return the [`first`][first] or [`last`][last] element of a sequential collection.
 - To find the middle card you can divide the number of cards by 2, round to the lowest integer with [`int`][int], and retrieve the card at that index using [`nth`][nth].
 - Use [`or`][or] to determine if either condition is true.
 
diff --git a/exercises/concept/log-levels/.docs/hints.md b/exercises/concept/log-levels/.docs/hints.md
index feabaa9..c31a45b 100644
--- a/exercises/concept/log-levels/.docs/hints.md
+++ b/exercises/concept/log-levels/.docs/hints.md
@@ -11,13 +11,13 @@
 
 ## 2. Get log level from a log line
 
-- A `string` can be converted to lowercase using [`lowercase`][lowercase].
+- A `string` can be converted to lowercase using [`lower-case`][lower-case].
 
 ## 3. Reformat a log line
 
 - The [`str`][str] function can be used to concatenate strings.
 
-[lowercase]: https://clojuredocs.org/clojure.string/lower-case
+[lower-case]: https://clojuredocs.org/clojure.string/lower-case
 [split]: https://clojuredocs.org/clojure.string/split
 [str]: https://clojuredocs.org/clojure.core/str
 [string-ns]: https://clojuredocs.org/clojure.string
diff --git a/exercises/concept/squeaky-clean/.docs/hints.md b/exercises/concept/squeaky-clean/.docs/hints.md
index efca0f8..30b79b0 100644
--- a/exercises/concept/squeaky-clean/.docs/hints.md
+++ b/exercises/concept/squeaky-clean/.docs/hints.md
@@ -6,20 +6,20 @@ The built-in `clojure.string` library contains a [`replace`][str-replace] functi
 
 ## 2. Replace control characters with the upper case string "CTRL"
 
-Here we need to use the [`isISOControl`][java-ctrl] method from Java's `Character` class.
+You can use the [`isISOControl`][java-ctrl] method from Java's `Character` class.
 
 ## 3. Convert kebab-case to camelCase
 
-Try separating the string on the hyphens with [`string/split`][str-split].
-If there are no hyphens, we need to pass the original string. You can check using [string/includes?][str-includes]. Use [string/upper-case][str-upper-case] to make the "humps" of the camel. Finally, concatenate them with [string/join][str-join].
+Try separating the string on the hyphens with [`split`][str-split].
+If it contains no hyphens, you should return it as it is. You can check this using [`includes?`][str-includes]. Use [`upper-case`][str-upper-case] to make the "humps" of the camel. Finally, concatenate them with [`join`][str-join].
 
 ## 4. Omit characters that are not letters
 
-You can filter characters using [Character/isLetter][java-isletter] as a predicate.
+You can filter characters using [`Character/isLetter`][java-isletter] as a predicate.
 
-## 5. Omit Greek lower case letters
+## 5. Omit Greek lowercase letters
 
-The lower-case Greek letters are Unicode points `\u03B1` to `\u03C9`, or integer values 945 through 969.
+The Greek lowercase letters are Unicode points `\u03B1` to `\u03C9`, or integer values 945 through 969.
 
 [str-join]: https://clojuredocs.org/clojure.string/join
 [str-upper-case]: https://clojuredocs.org/clojure.string/upper-case
diff --git a/exercises/concept/squeaky-clean/.docs/instructions.md b/exercises/concept/squeaky-clean/.docs/instructions.md
index e697513..83a1d7c 100644
--- a/exercises/concept/squeaky-clean/.docs/instructions.md
+++ b/exercises/concept/squeaky-clean/.docs/instructions.md
@@ -3,14 +3,14 @@
 In this exercise you will implement a partial set of utility routines 
 to help a developer clean up identifier names.
 
-In the 5 tasks you will gradually build up the routine `clean`. 
+In the 5 tasks you will gradually build up the function `clean`.
 A valid identifier comprises zero or more letters and underscores.
 
 In all cases the input string is guaranteed to be non-nil. 
-If an empty string is passed to the `clean` function, 
+If an empty string is passed to the function,
 an empty string should be returned.
 
-Note that the caller should avoid calling the routine `clean` 
+Note that the caller should avoid calling the function
 with an empty identifier since such identifiers are ineffectual.
 
 ## 1. Replace any spaces encountered with underscores
@@ -55,7 +55,7 @@ Note: The underscores must be preserved from the previous step.
 ;; => ""
 ```
 
-## 5. Omit Greek lower case letters
+## 5. Omit Greek lowercase letters
 
 Modify the `clean` function to omit any Greek letters in the range 'α' to 'ω'.
 
diff --git a/exercises/practice/complex-numbers/.docs/instructions.append.md b/exercises/practice/complex-numbers/.docs/instructions.append.md
new file mode 100644
index 0000000..1c6bfad
--- /dev/null
+++ b/exercises/practice/complex-numbers/.docs/instructions.append.md
@@ -0,0 +1,4 @@
+# Instructions append
+
+**Note:** The instructions ask for the exponent function because they are synced with a shared repository to maintain consistency across all language tracks.
+However, for this exercise in the Clojure track, you don't need to implement it.
diff --git a/exercises/practice/eliuds-eggs/.docs/instructions.md b/exercises/practice/eliuds-eggs/.docs/instructions.md
new file mode 100644
index 0000000..b0c2df5
--- /dev/null
+++ b/exercises/practice/eliuds-eggs/.docs/instructions.md
@@ -0,0 +1,8 @@
+# Instructions
+
+Your task is to count the number of 1 bits in the binary representation of a number.
+
+## Restrictions
+
+Keep your hands off that bit-count functionality provided by your standard library!
+Solve this one yourself using other basic tools instead.
diff --git a/exercises/practice/eliuds-eggs/.docs/introduction.md b/exercises/practice/eliuds-eggs/.docs/introduction.md
new file mode 100644
index 0000000..49eaffd
--- /dev/null
+++ b/exercises/practice/eliuds-eggs/.docs/introduction.md
@@ -0,0 +1,47 @@
+# Introduction
+
+Your friend Eliud inherited a farm from her grandma Tigist.
+Her granny was an inventor and had a tendency to build things in an overly complicated manner.
+The chicken coop has a digital display showing an encoded number representing the positions of all eggs that could be picked up.
+
+Eliud is asking you to write a program that shows the actual number of eggs in the coop.
+
+The position information encoding is calculated as follows:
+
+1. Scan the potential egg-laying spots and mark down a `1` for an existing egg or a `0` for an empty spot.
+2. Convert the number from binary to decimal.
+3. Show the result on the display.
+
+Example 1:
+
+```text
+Chicken Coop:
+ _ _ _ _ _ _ _
+|E| |E|E| | |E|
+
+Resulting Binary:
+ 1 0 1 1 0 0 1
+
+Decimal number on the display:
+89
+
+Actual eggs in the coop:
+4
+```
+
+Example 2:
+
+```text
+Chicken Coop:
+ _ _ _ _ _ _ _ _
+| | | |E| | | | |
+
+Resulting Binary:
+ 0 0 0 1 0 0 0 0
+
+Decimal number on the display:
+16
+
+Actual eggs in the coop:
+1
+```
diff --git a/exercises/practice/eliuds-eggs/.meta/config.json b/exercises/practice/eliuds-eggs/.meta/config.json
new file mode 100644
index 0000000..b861900
--- /dev/null
+++ b/exercises/practice/eliuds-eggs/.meta/config.json
@@ -0,0 +1,19 @@
+{
+  "authors": [
+    "kahgoh"
+  ],
+  "files": {
+    "solution": [
+      "src/eliuds_eggs.clj"
+    ],
+    "test": [
+      "test/eliuds_eggs_test.clj"
+    ],
+    "example": [
+      ".meta/src/example.clj"
+    ]
+  },
+  "blurb": "Help Eliud count the number of eggs in her chicken coop by counting the number of 1 bits in a binary representation.",
+  "source": "Christian Willner, Eric Willigers",
+  "source_url": "https://forum.exercism.org/t/new-exercise-suggestion-pop-count/7632/5"
+}
diff --git a/exercises/practice/eliuds-eggs/.meta/src/example.clj b/exercises/practice/eliuds-eggs/.meta/src/example.clj
new file mode 100644
index 0000000..7502808
--- /dev/null
+++ b/exercises/practice/eliuds-eggs/.meta/src/example.clj
@@ -0,0 +1,7 @@
+(ns eliuds-eggs)
+
+(defn egg-count [number]
+  (loop [value number acc 0]
+    (if (= 0 value)
+      acc
+      (recur (quot value 2) (+ acc (rem value 2))))))
\ No newline at end of file
diff --git a/exercises/practice/eliuds-eggs/deps.edn b/exercises/practice/eliuds-eggs/deps.edn
new file mode 100644
index 0000000..561c3e2
--- /dev/null
+++ b/exercises/practice/eliuds-eggs/deps.edn
@@ -0,0 +1,6 @@
+{:aliases {:test {:extra-paths ["test"]
+                 :extra-deps {io.github.cognitect-labs/test-runner 
+                              {:git/url "https://github.com/cognitect-labs/test-runner.git"
+                               :sha "705ad25bbf0228b1c38d0244a36001c2987d7337"}}
+                 :main-opts ["-m" "cognitect.test-runner"]
+                 :exec-fn cognitect.test-runner.api/test}}}
\ No newline at end of file
diff --git a/exercises/practice/eliuds-eggs/project.clj b/exercises/practice/eliuds-eggs/project.clj
new file mode 100644
index 0000000..d73dacf
--- /dev/null
+++ b/exercises/practice/eliuds-eggs/project.clj
@@ -0,0 +1,4 @@
+(defproject eliuds-eggs "0.1.0-SNAPSHOT"
+  :description "eliuds-eggs exercise."
+  :url "https://github.com/exercism/clojure/tree/master/exercises/eliuds-eggs"
+  :dependencies [[org.clojure/clojure "1.10.0"]])
diff --git a/exercises/practice/eliuds-eggs/src/eliuds_eggs.clj b/exercises/practice/eliuds-eggs/src/eliuds_eggs.clj
new file mode 100644
index 0000000..1ade79a
--- /dev/null
+++ b/exercises/practice/eliuds-eggs/src/eliuds_eggs.clj
@@ -0,0 +1,5 @@
+(ns eliuds-eggs)
+
+(defn egg-count [number]
+    ;; your code goes here
+)
\ No newline at end of file
diff --git a/exercises/practice/leap/.approaches/boolean-operations/content.md b/exercises/practice/leap/.approaches/boolean-operations/content.md
index 01a049d..0bd137b 100644
--- a/exercises/practice/leap/.approaches/boolean-operations/content.md
+++ b/exercises/practice/leap/.approaches/boolean-operations/content.md
@@ -11,7 +11,7 @@
 ```
 
 At the core of this approach, three checks are returning three boolean values.
-We can use [Boolean logic](https://en.wikipedia.org/wiki/Boolean_algebra) to combine the results. Multiple variations are possible. One is shown above, but the below is also possible.
+We can use [Boolean logic](https://en.wikipedia.org/wiki/Boolean_algebra) to combine the results. Multiple variations are possible. One is shown above, but the one below is also possible.
 
 ```clojure
 (defn leap-year? [year]
@@ -22,7 +22,7 @@ We can use [Boolean logic](https://en.wikipedia.org/wiki/Boolean_algebra) to com
 
 ## Being explicit
 
-The above examples use a private function `divides?` to be more explicit, to show what logical check is done rather than what operation is performed.
+The above examples use a private function `divides?` to be more explicit, showing what logical check is done rather than what operation is performed.
 This is common in Clojure code, but it is also possible to do the checks directly.
 
 ```clojure
@@ -34,7 +34,7 @@ This is common in Clojure code, but it is also possible to do the checks directl
 
 In this example, in addition, instead of negating the second check, we check if the reminder from the division is greater than zero.
 
-If the concern is that defining `divides?` adds confusion, because it is not known in the only place where it is used, `letfn` can be used. Here is another example.
+If the concern is that defining `divides?` adds confusion because it is not known in the only place where it is used, `letfn` can be used instead. Here is another example.
 
 ```clojure
 (defn leap-year? [year]
diff --git a/exercises/practice/leap/.approaches/flow-control/content.md b/exercises/practice/leap/.approaches/flow-control/content.md
index e65b7a7..1bf0618 100644
--- a/exercises/practice/leap/.approaches/flow-control/content.md
+++ b/exercises/practice/leap/.approaches/flow-control/content.md
@@ -39,7 +39,7 @@ Another option is `cond` which allows for evaluating multiple conditions, simila
     :else false))
 ```
 
-A very similar alternative is to use the `condp` macro, which takes a predicate and applies it to a series of test value and expected result pairs.
+A very similar alternative is to use the `condp` macro, which takes a predicate and applies it to a series of test values and expected result pairs.
 
 ```clojure
 (defn leap-year? [year]
@@ -50,7 +50,7 @@ A very similar alternative is to use the `condp` macro, which takes a predicate
         false))
 ```
 
-When using both `cond` and `condp,` the other matters as the first true condition stops evaluating the list and determines the result.
+When using both `cond` and `condp,` the order matters, as the first true condition stops evaluating the list and determines the result.
 
 ## Case
 
diff --git a/exercises/practice/leap/.approaches/introduction.md b/exercises/practice/leap/.approaches/introduction.md
index 990fcf4..07b559b 100644
--- a/exercises/practice/leap/.approaches/introduction.md
+++ b/exercises/practice/leap/.approaches/introduction.md
@@ -44,7 +44,7 @@ Explore the details in the [boolean operations approach][boolean-approach].
 
 ## Approach: conditional branching
 
-Instead of combining the logical expressions, we can use conditional branching with functions like `if` or `cond` to perform the necessary checks and determin if a given years is a leap one. 
+Instead of combining the logical expressions, we can use conditional branching with functions like `if` or `cond` to perform the necessary checks and determine if a given year is a leap year.
 
 ```clojure
 (if (divides? year 100) 
@@ -56,7 +56,7 @@ In the [flow control expressions approach][flow-control-approach], we discuss th
 
 ## Approach: data shapes
 
-This is a little less straight forward approach, but with a little bit of setup we can get to a `leap-year?` function that looks like so:
+This is a slightly less straightforward approach, but with a bit of setup, we can get to a `leap-year?` function that looks like so:
 
 ```clojure
 (defn leap-year? [year]
diff --git a/exercises/practice/list-ops/.docs/instructions.append.md b/exercises/practice/list-ops/.docs/instructions.append.md
index e226d47..d27f6e1 100644
--- a/exercises/practice/list-ops/.docs/instructions.append.md
+++ b/exercises/practice/list-ops/.docs/instructions.append.md
@@ -1,8 +1,19 @@
 # Instructions append
 
-## Implementation tips
+## Appendix
 
-- The instructions use lists because they are synced with a shared repository to maintain consistency across tracks.
-  However, for this exercise in the Clojure track, you should assume that you are working with vectors instead of lists.
-- It is important not to reuse existing Clojure built-in functions with similar functionality, as doing so would diminish the intended learning value of the exercise.
-  Some of these functions include `into`, `concat`, `cat`, `lazy-cat`, `mapcat`, `flatten`, `filter`, `filterv`, `remove`, `count`, `map`, `mapv`, `reduce`, `transduce`, `reverse`, and `rseq` from the **clojure.core** namespace.
+The instructions are synced with a shared repository to ensure consistency across all language tracks.
+For this exercise in the Clojure track, assume both the input and output are vectors.
+As a stretch goal, consider how you could implement the solution without using lists anywhere in your code.
+Also, think about the efficiency of your program.
+
+It is important not to reuse existing Clojure built-in functions with similar functionality, as doing so would diminish the intended learning value of the exercise.
+Key functions from the **clojure.core** namespace to avoid include `into`, `concat`, `cat`, `lazy-cat`, `mapcat`, `flatten`, `filter`, `filterv`, `remove`, `count`, `map`, `mapv`, `reduce`, `transduce`, `reverse`, and `rseq`.
+
+### Optional goals
+
+Try to pass the tests by devising a solution that assumes both the input and output are lists instead of vectors.
+The test suite does not need to be modified.
+This time, consider how you could implement the solution without using vectors anywhere in your code.
+
+If you decide to publish this solution, be sure to include a comment indicating that it addresses the optional goal of using lists. Don't forget to update the docstrings!
diff --git a/exercises/practice/list-ops/.meta/config.json b/exercises/practice/list-ops/.meta/config.json
index 1035f4f..f1b2c91 100644
--- a/exercises/practice/list-ops/.meta/config.json
+++ b/exercises/practice/list-ops/.meta/config.json
@@ -1,10 +1,10 @@
 {
   "authors": [
-    "bobbicodes"
+    "bobbicodes",
+    "tasxatzial"
   ],
   "contributors": [
-    "kahgoh",
-    "tasxatzial"
+    "kahgoh"
   ],
   "files": {
     "solution": [
diff --git a/exercises/practice/list-ops/.meta/src/example.clj b/exercises/practice/list-ops/.meta/src/example.clj
index c4bc083..7aa1541 100644
--- a/exercises/practice/list-ops/.meta/src/example.clj
+++ b/exercises/practice/list-ops/.meta/src/example.clj
@@ -1,34 +1,50 @@
 (ns list-ops)
 
-(defn foldl [f coll init]
-  (loop [acc init l coll]
-    (cond
-      (empty? l) acc
-      :else (recur (f acc (first l)) (rest l)))))
-
-(defn append [coll1 coll2]
-  (list-ops/foldl (fn [acc elem] (conj acc elem)) coll2 coll1))
-
-(defn concatenate [coll]
-  (cond
-    (empty? coll) []
-    :else (list-ops/foldl (fn [acc elem] (list-ops/append acc elem)) (rest coll) (first coll))))
-
-(defn select-if [pred coll]
-  (loop [acc [] l coll]
-    (cond
-      (empty? l) acc
-      (pred (first l)) (recur (conj acc (first l)) (rest l))
-      :else (recur acc (rest l)))))
-
-(defn length [coll]
-  (list-ops/foldl (fn [acc elem] (+ acc 1)) coll 0))
-
-(defn apply-to-each [f coll]
-  (list-ops/foldl (fn [acc elem] (conj acc (f elem))) coll []))
-
-(defn reverse-order [coll]
-  (list-ops/foldl (fn [acc elem] (cons elem acc)) coll []))
-
-(defn foldr [f coll init]
-  (list-ops/foldl f (list-ops/reverse-order coll) init))
+(declare foldl)
+(declare reverse-order)
+
+(defn append
+  [coll1 coll2]
+  (foldl conj coll2 coll1))
+
+(defn concatenate
+  [colls]
+  (foldl append colls []))
+
+(defn select-if
+  [pred coll]
+  (let [reducer (fn [acc el]
+                  (if (pred el)
+                    (conj acc el)
+                    acc))]
+    (foldl reducer coll [])))
+
+(defn length
+  [coll]
+  (let [reducer (fn [acc _]
+                  (inc acc))]
+    (foldl reducer coll 0)))
+
+(defn apply-to-each
+  [f coll]
+  (let [reducer (fn [acc el]
+                  (conj acc (f el)))]
+    (foldl reducer coll [])))
+
+(defn foldl
+  [f coll acc]
+  (if (seq coll)
+    (recur f (rest coll) (f acc (first coll)))
+    acc))
+
+(defn foldr
+  [f coll acc]
+  (foldl f (reverse-order coll) acc))
+
+(defn reverse-order
+  [coll]
+  (loop [index (dec (length coll))
+         result []]
+    (if (neg? index)
+      result
+      (recur (dec index) (conj result (coll index))))))
diff --git a/exercises/practice/list-ops/.meta/src/example_lists.clj b/exercises/practice/list-ops/.meta/src/example_lists.clj
new file mode 100644
index 0000000..94b9c89
--- /dev/null
+++ b/exercises/practice/list-ops/.meta/src/example_lists.clj
@@ -0,0 +1,46 @@
+(ns list-ops)
+
+(declare foldl)
+(declare reverse-order)
+
+(defn append
+  [coll1 coll2]
+  (reverse-order (foldl conj coll2 (reverse-order coll1))))
+
+(defn concatenate
+  [colls]
+  (foldl append colls ()))
+
+(defn select-if
+  [pred coll]
+  (let [reducer (fn [acc el]
+                  (if (pred el)
+                    (conj acc el)
+                    acc))]
+    (reverse-order (foldl reducer coll ()))))
+
+(defn length
+  [coll]
+  (let [reducer (fn [acc _]
+                  (inc acc))]
+    (foldl reducer coll 0)))
+
+(defn apply-to-each
+  [f coll]
+  (let [reducer (fn [acc el]
+                  (conj acc (f el)))]
+    (reverse-order (foldl reducer coll ()))))
+
+(defn foldl
+  [f coll acc]
+  (if (seq coll)
+    (recur f (rest coll) (f acc (first coll)))
+    acc))
+
+(defn foldr
+  [f coll acc]
+  (foldl f (reverse-order coll) acc))
+
+(defn reverse-order
+  [coll]
+  (foldl conj coll ()))
diff --git a/exercises/practice/list-ops/src/list_ops.clj b/exercises/practice/list-ops/src/list_ops.clj
index 28d30ea..160992a 100644
--- a/exercises/practice/list-ops/src/list_ops.clj
+++ b/exercises/practice/list-ops/src/list_ops.clj
@@ -3,47 +3,47 @@
 (defn append 
   "Given two vectors, it adds all the items in the second vector to the end of the first vector"
   [coll1 coll2]
-  ;; your code goes here
-)
+  ;; function body
+  )
 
 (defn concatenate 
   "Given a vector of vectors, it combines all the vectors into one flattened vector"
   [colls]
-  ;; your code goes here
-)
+  ;; function body
+  )
 
 (defn select-if
   "Given a predicate and a vector, it returns the vector of all items for which predicate(item) is true"
   [pred coll]
-  ;; your code goes here
-)
+  ;; function body
+  )
 
 (defn length 
   "Given a vector, it returns the number of items within it"
   [coll]
-  ;; your code goes here
-)
+  ;; function body
+  )
 
 (defn apply-to-each 
   "Given a function and a vector, it returns the vector of the results of applying function(item) on all items"
   [f coll]
-  ;; your code goes here
-)
+  ;; function body
+  )
 
 (defn foldl 
   "Given a function, a vector, and initial accumulator, it folds (reduces) each item into the accumulator from the left"
-  [f coll init]
-  ;; your code goes here
-)
+  [f coll acc]
+  ;; function body
+  )
 
 (defn foldr
   "Given a function, a vector, and an initial accumulator, it folds (reduces) each item into the accumulator from the right"
-  [f coll init]
-  ;; your code goes here
-)
+  [f coll acc]
+  ;; function body
+  )
 
 (defn reverse-order 
   "Given a vector, it returns a vector with all the original items, but in reverse order"
   [coll]
-  ;; your code goes here
-)
+  ;; function body
+  )


Test patch:
diff --git a/exercises/practice/eliuds-eggs/.meta/tests.toml b/exercises/practice/eliuds-eggs/.meta/tests.toml
new file mode 100644
index 0000000..e11683c
--- /dev/null
+++ b/exercises/practice/eliuds-eggs/.meta/tests.toml
@@ -0,0 +1,22 @@
+# This is an auto-generated file.
+#
+# Regenerating this file via `configlet sync` will:
+# - Recreate every `description` key/value pair
+# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
+# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
+# - Preserve any other key/value pair
+#
+# As user-added comments (using the # character) will be removed when this file
+# is regenerated, comments can be added via a `comment` key.
+
+[559e789d-07d1-4422-9004-3b699f83bca3]
+description = "0 eggs"
+
+[97223282-f71e-490c-92f0-b3ec9e275aba]
+description = "1 egg"
+
+[1f8fd18f-26e9-4144-9a0e-57cdfc4f4ff5]
+description = "4 eggs"
+
+[0c18be92-a498-4ef2-bcbb-28ac4b06cb81]
+description = "13 eggs"
diff --git a/exercises/practice/eliuds-eggs/test/eliuds_eggs_test.clj b/exercises/practice/eliuds-eggs/test/eliuds_eggs_test.clj
new file mode 100644
index 0000000..e660f18
--- /dev/null
+++ b/exercises/practice/eliuds-eggs/test/eliuds_eggs_test.clj
@@ -0,0 +1,15 @@
+(ns eliuds-eggs-test
+  (:require [clojure.test :refer [deftest is]]
+            eliuds-eggs))
+
+(deftest no-eggs
+  (is (= 0 (eliuds-eggs/egg-count 0))))
+
+(deftest one-egg
+  (is (= 1 (eliuds-eggs/egg-count 16))))
+
+(deftest four-eggs
+  (is (= 4 (eliuds-eggs/egg-count 89))))
+
+(deftest thirteen-eggs
+  (is (= 13 (eliuds-eggs/egg-count 2000000000))))
\ No newline at end of file
diff --git a/exercises/practice/kindergarten-garden/.meta/tests.toml b/exercises/practice/kindergarten-garden/.meta/tests.toml
index 1778a61..0cdd9ad 100644
--- a/exercises/practice/kindergarten-garden/.meta/tests.toml
+++ b/exercises/practice/kindergarten-garden/.meta/tests.toml
@@ -1,30 +1,61 @@
-# 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.
+# This is an auto-generated file.
+#
+# Regenerating this file via `configlet sync` will:
+# - Recreate every `description` key/value pair
+# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
+# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
+# - Preserve any other key/value pair
+#
+# As user-added comments (using the # character) will be removed when this file
+# is regenerated, comments can be added via a `comment` key.
 
 [1fc316ed-17ab-4fba-88ef-3ae78296b692]
-description = "garden with single student"
+description = "partial garden -> garden with single student"
 
 [acd19dc1-2200-4317-bc2a-08f021276b40]
-description = "different garden with single student"
+description = "partial garden -> different garden with single student"
 
 [c376fcc8-349c-446c-94b0-903947315757]
-description = "garden with two students"
+description = "partial garden -> garden with two students"
 
 [2d620f45-9617-4924-9d27-751c80d17db9]
-description = "second student's garden"
+description = "partial garden -> multiple students for the same garden with three students -> second student's garden"
 
 [57712331-4896-4364-89f8-576421d69c44]
-description = "third student's garden"
+description = "partial garden -> multiple students for the same garden with three students -> third student's garden"
 
 [149b4290-58e1-40f2-8ae4-8b87c46e765b]
-description = "first student's garden"
+description = "full garden -> for Alice, first student's garden"
 
 [ba25dbbc-10bd-4a37-b18e-f89ecd098a5e]
-description = "second student's garden"
+description = "full garden -> for Bob, second student's garden"
+
+[566b621b-f18e-4c5f-873e-be30544b838c]
+description = "full garden -> for Charlie"
+
+[3ad3df57-dd98-46fc-9269-1877abf612aa]
+description = "full garden -> for David"
+
+[0f0a55d1-9710-46ed-a0eb-399ba8c72db2]
+description = "full garden -> for Eve"
+
+[a7e80c90-b140-4ea1-aee3-f4625365c9a4]
+description = "full garden -> for Fred"
+
+[9d94b273-2933-471b-86e8-dba68694c615]
+description = "full garden -> for Ginny"
+
+[f55bc6c2-ade8-4844-87c4-87196f1b7258]
+description = "full garden -> for Harriet"
+
+[759070a3-1bb1-4dd4-be2c-7cce1d7679ae]
+description = "full garden -> for Ileana"
+
+[78578123-2755-4d4a-9c7d-e985b8dda1c6]
+description = "full garden -> for Joseph"
 
 [6bb66df7-f433-41ab-aec2-3ead6e99f65b]
-description = "second to last student's garden"
+description = "full garden -> for Kincaid, second to last student's garden"
 
 [d7edec11-6488-418a-94e6-ed509e0fa7eb]
-description = "last student's garden"
+description = "full garden -> for Larry, last student's garden"
diff --git a/exercises/practice/kindergarten-garden/test/kindergarten_garden_test.clj b/exercises/practice/kindergarten-garden/test/kindergarten_garden_test.clj
index 0d00448..8017429 100644
--- a/exercises/practice/kindergarten-garden/test/kindergarten_garden_test.clj
+++ b/exercises/practice/kindergarten-garden/test/kindergarten_garden_test.clj
@@ -1,47 +1,88 @@
 (ns kindergarten-garden-test
-  (:require [clojure.test :refer [deftest is]]
+  (:require [clojure.test :refer [deftest testing is]]
             kindergarten-garden))
 
-(deftest garden-test
-  (is (= [:radishes :clover :grass :grass]
-         (:alice (kindergarten-garden/garden "RC\nGG"))))
-  (is (= [:violets :clover :radishes :clover]
-         (:alice (kindergarten-garden/garden "VC\nRC")))))
-
-(deftest small-garden-test
-  (let [small-garden (kindergarten-garden/garden "VVCG\nVVRC")]
-    (is (= [:clover :grass :radishes :clover] (:bob small-garden)))))
-
-(deftest medium-garden-test
-  (let [medium-garden (kindergarten-garden/garden "VVCCGG\nVVCCGG")]
-    (is (= [:clover :clover :clover :clover] (:bob medium-garden)))
-    (is (= [:grass :grass :grass :grass] (:charlie medium-garden)))))
-
-(deftest full-garden-test
-  (let [string "VRCGVVRVCGGCCGVRGCVCGCGV\nVRCCCGCRRGVCGCRVVCVGCGCV"
-        full-garden (kindergarten-garden/garden string)]
-    (is (= [:violets  :radishes :violets  :radishes] (:alice   full-garden)))
-    (is (= [:clover   :grass    :clover   :clover]   (:bob     full-garden)))
-    (is (= [:violets  :violets  :clover   :grass]    (:charlie full-garden)))
-    (is (= [:radishes :violets  :clover   :radishes] (:david   full-garden)))
-    (is (= [:clover   :grass    :radishes :grass]    (:eve     full-garden)))
-    (is (= [:grass    :clover   :violets  :clover]   (:fred    full-garden)))
-    (is (= [:clover   :grass    :grass    :clover]   (:ginny   full-garden)))
-    (is (= [:violets  :radishes :radishes :violets]  (:harriet full-garden)))
-    (is (= [:grass    :clover   :violets  :clover]   (:ileana  full-garden)))
-    (is (= [:violets  :clover   :violets  :grass]    (:joseph  full-garden)))
-    (is (= [:grass    :clover   :clover   :grass]    (:kincaid full-garden)))
-    (is (= [:grass    :violets  :clover   :violets]  (:larry   full-garden)))))
-
-(deftest surprise-garden-test
-  (let [string   "VCRRGVRG\nRVGCCGCV"
-        students ["Samantha" "Patricia" "Xander" "Roger"]
-        surprise-garden (kindergarten-garden/garden string students)]
-    (is (= [:violets  :clover   :radishes :violets]
-           (:patricia surprise-garden)))
-    (is (= [:radishes :radishes :grass    :clover]
-           (:roger    surprise-garden)))
-    (is (= [:grass    :violets  :clover   :grass]
-           (:samantha surprise-garden)))
-    (is (= [:radishes :grass    :clover   :violets]
-           (:xander   surprise-garden)))))
+(deftest test-1fc316ed-17ab-4fba-88ef-3ae78296b692
+  (testing "Partial garden -> Garden with single student"
+    (is (= [:radishes :clover :grass :grass]
+           (:alice (kindergarten-garden/garden "RC\nGG"))))))
+
+(deftest test-acd19dc1-2200-4317-bc2a-08f021276b40
+  (testing "Partial garden -> Different garden with single student"
+    (is (= [:violets :clover :radishes :clover]
+           (:alice (kindergarten-garden/garden "VC\nRC"))))))
+
+(deftest test-c376fcc8-349c-446c-94b0-903947315757
+  (testing "Partial garden -> Garden with two students"
+    (is (= [:clover :grass :radishes :clover]
+           (:bob (kindergarten-garden/garden "VVCG\nVVRC"))))))
+
+(deftest test-2d620f45-9617-4924-9d27-751c80d17db9
+  (testing "Partial garden -> Multiple students for the same garden with three students -> Second student's garden"
+    (is (= [:clover :clover :clover :clover]
+           (:bob (kindergarten-garden/garden "VVCCGG\nVVCCGG"))))))
+
+(deftest test-57712331-4896-4364-89f8-576421d69c44
+  (testing "Partial garden -> Multiple students for the same garden with three students -> Third student's garden"
+    (is (= [:grass :grass :grass :grass]
+           (:charlie (kindergarten-garden/garden "VVCCGG\nVVCCGG"))))))
+
+(deftest test-149b4290-58e1-40f2-8ae4-8b87c46e765b
+  (testing "Full garden -> For Alice first student's garden"
+    (is (= [:violets :radishes :violets :radishes]
+           (:alice (kindergarten-garden/garden "VRCGVVRVCGGCCGVRGCVCGCGV\nVRCCCGCRRGVCGCRVVCVGCGCV"))))))
+
+(deftest test-ba25dbbc-10bd-4a37-b18e-f89ecd098a5e
+  (testing "Full garden -> For Bob second student's garden"
+    (is (= [:clover :grass :clover :clover]
+           (:bob (kindergarten-garden/garden "VRCGVVRVCGGCCGVRGCVCGCGV\nVRCCCGCRRGVCGCRVVCVGCGCV"))))))
+
+(deftest test-566b621b-f18e-4c5f-873e-be30544b838c
+  (testing "Full garden -> For Charlie"
+    (is (= [:violets :violets :clover :grass]
+           (:charlie (kindergarten-garden/garden "VRCGVVRVCGGCCGVRGCVCGCGV\nVRCCCGCRRGVCGCRVVCVGCGCV"))))))
+
+(deftest test-3ad3df57-dd98-46fc-9269-1877abf612aa
+  (testing "Full garden -> For David"
+    (is (= [:radishes :violets :clover :radishes]
+           (:david (kindergarten-garden/garden "VRCGVVRVCGGCCGVRGCVCGCGV\nVRCCCGCRRGVCGCRVVCVGCGCV"))))))
+
+(deftest test-0f0a55d1-9710-46ed-a0eb-399ba8c72db2
+  (testing "Full garden -> For Eve"
+    (is (= [:clover :grass :radishes :grass]
+           (:eve (kindergarten-garden/garden "VRCGVVRVCGGCCGVRGCVCGCGV\nVRCCCGCRRGVCGCRVVCVGCGCV"))))))
+
+(deftest test-a7e80c90-b140-4ea1-aee3-f4625365c9a4
+  (testing "Full garden -> For Fred"
+    (is (= [:grass :clover :violets :clover]
+           (:fred (kindergarten-garden/garden "VRCGVVRVCGGCCGVRGCVCGCGV\nVRCCCGCRRGVCGCRVVCVGCGCV"))))))
+
+(deftest test-9d94b273-2933-471b-86e8-dba68694c615
+  (testing "Full garden -> For Ginny"
+    (is (= [:clover :grass :grass :clover]
+           (:ginny (kindergarten-garden/garden "VRCGVVRVCGGCCGVRGCVCGCGV\nVRCCCGCRRGVCGCRVVCVGCGCV"))))))
+
+(deftest test-f55bc6c2-ade8-4844-87c4-87196f1b7258
+  (testing "Full garden -> For Harriet"
+    (is (= [:violets :radishes :radishes :violets]
+           (:harriet (kindergarten-garden/garden "VRCGVVRVCGGCCGVRGCVCGCGV\nVRCCCGCRRGVCGCRVVCVGCGCV"))))))
+
+(deftest test-759070a3-1bb1-4dd4-be2c-7cce1d7679ae
+  (testing "Full garden -> For Ileana"
+    (is (= [:grass :clover :violets :clover]
+           (:ileana (kindergarten-garden/garden "VRCGVVRVCGGCCGVRGCVCGCGV\nVRCCCGCRRGVCGCRVVCVGCGCV"))))))
+
+(deftest test-78578123-2755-4d4a-9c7d-e985b8dda1c6
+  (testing "Full garden -> For Joseph"
+    (is (= [:violets :clover :violets :grass]
+           (:joseph (kindergarten-garden/garden "VRCGVVRVCGGCCGVRGCVCGCGV\nVRCCCGCRRGVCGCRVVCVGCGCV"))))))
+
+(deftest test-6bb66df7-f433-41ab-aec2-3ead6e99f65b
+  (testing "Full garden -> For Kincaid second to last student's garden"
+    (is (= [:grass :clover :clover :grass]
+           (:kincaid (kindergarten-garden/garden "VRCGVVRVCGGCCGVRGCVCGCGV\nVRCCCGCRRGVCGCRVVCVGCGCV"))))))
+
+(deftest test-d7edec11-6488-418a-94e6-ed509e0fa7eb
+  (testing "Full garden -> For Larry last student's garden"
+    (is (= [:grass :violets :clover :violets]
+           (:larry (kindergarten-garden/garden "VRCGVVRVCGGCCGVRGCVCGCGV\nVRCCCGCRRGVCGCRVVCVGCGCV"))))))
diff --git a/exercises/practice/list-ops/test/list_ops_test.clj b/exercises/practice/list-ops/test/list_ops_test.clj
index 2b26907..83f0544 100644
--- a/exercises/practice/list-ops/test/list_ops_test.clj
+++ b/exercises/practice/list-ops/test/list_ops_test.clj
@@ -2,62 +2,90 @@
   (:require [clojure.test :refer [deftest testing is]]
              list-ops))
 
-(deftest append-test
-  (testing "empty vectors"
-     (is (= [] (list-ops/append [] []))))
-  (testing "vector to empty vector"
-     (is (= [1 2 3 4] (list-ops/append [] [1 2 3 4]))))
-  (testing "empty vector to vector"
-     (is (= [1 2 3 4] (list-ops/append [1 2 3 4] []))))
-  (testing "non-empty vectors"
-     (is (= [1 2 2 3 4 5] (list-ops/append [1 2] [2 3 4 5])))))
-
-(deftest concatenate-test
-  (testing "empty vector"
-     (is (= [] (list-ops/concatenate []))))
-  (testing "vector of vectors"
-     (is (= [1 2 3 4 5 6] (list-ops/concatenate [[1 2] [3] [] [4 5 6]]))))
-  (testing "vector of nested vectors"
-     (is (= [[1] [2] [3] [] [4 5 6]] (list-ops/concatenate [[[1] [2]] [[3]] [[]] [[4 5 6]]])))))
-
-(deftest select-if-test
-  (testing "empty vector"
-     (is (= [] (list-ops/select-if (fn [x] (= (mod x 2) 1)) [])))
-  (testing "non-empty vector"
-     (is (= [1 3 5] (list-ops/select-if (fn [x] (= (mod x 2) 1)) [1 2 3 5]))))))
-
-(deftest length-test
-  (testing "empty vector"
-     (is (= 0 (list-ops/length []))))
-  (testing "non-empty vector"
-     (is (= 4 (list-ops/length [1 2 3 4])))))
-
-(deftest apply-to-each-test
-  (testing "empty vector"
-     (is (= [] (list-ops/apply-to-each (fn [x] (+ x 1)) []))))
-  (testing "non-empty vector"
-     (is (= [2 4 6 8] (list-ops/apply-to-each (fn [x] (+ x 1)) [1 3 5 7])))))
-
-(deftest foldl-test
-  (testing "empty vector"
-     (is (= 2 (list-ops/foldl (fn [acc el] (* el acc)) [] 2))))
-  (testing "direction independent function applied to non-empty vector"
-     (is (= 15 (list-ops/foldl (fn [acc el] (+ el acc)) [1 2 3 4] 5))))
-  (testing "direction dependent function applied to non-empty vector"
-     (is (= 64 (list-ops/foldl (fn [acc el] (/ el acc)) [1 2 3 4] 24)))))
-
-(deftest foldr-test
-  (testing "empty vector"
-     (is (= 2 (list-ops/foldr (fn [acc el] (* el acc)) [] 2))))
-  (testing "direction independent function applied to non-empty vector"
-     (is (= 15 (list-ops/foldr (fn [acc el] (+ el acc)) [1 2 3 4] 5))))
-  (testing "direction dependent function applied to non-empty vector"
-     (is (= 9 (list-ops/foldr (fn [acc el] (/ el acc)) [1 2 3 4] 24)))))
-
-(deftest reverse-order-test
-  (testing "empty vector"
-     (is (= [] (list-ops/reverse-order []))))
-  (testing "non-empty vector"
-     (is (= [7 5 3 1] (list-ops/reverse-order [1 3 5 7]))))
-  (testing "vector of vectors is not flattened"
-     (is (= [[4 5 6] [] [3] [1 2]] (list-ops/reverse-order [[1 2] [3] [] [4 5 6]])))))
+(deftest test-485b9452-bf94-40f7-a3db-c3cf4850066a
+  (testing "append entries to a vector and return the new vector -> empty vectors"
+    (is (= [] (list-ops/append [] [])))))
+
+(deftest test-2c894696-b609-4569-b149-8672134d340a
+  (testing "append entries to a vector and return the new vector -> vector to empty vector"
+    (is (= [1 2 3 4] (list-ops/append [] [1 2 3 4])))))
+
+(deftest test-e842efed-3bf6-4295-b371-4d67a4fdf19c
+  (testing "append entries to a vector and return the new vector -> empty vector to vector"
+    (is (= [1 2 3 4] (list-ops/append [1 2 3 4] [])))))
+
+(deftest test-71dcf5eb-73ae-4a0e-b744-a52ee387922f
+  (testing "append entries to a vector and return the new vector -> non-empty vectors"
+    (is (= [1 2 2 3 4 5] (list-ops/append [1 2] [2 3 4 5])))))
+
+(deftest test-28444355-201b-4af2-a2f6-5550227bde21
+  (testing "concatenate a vector of vectors -> empty vector"
+    (is (= [] (list-ops/concatenate [])))))
+
+(deftest test-331451c1-9573-42a1-9869-2d06e3b389a9
+  (testing "concatenate a vector of vectors -> vector of vectors"
+    (is (= [1 2 3 4 5 6] (list-ops/concatenate [[1 2] [3] [] [4 5 6]])))))
+
+(deftest test-d6ecd72c-197f-40c3-89a4-aa1f45827e09
+  (testing "concatenate a vector of vectors -> vector of nested vectors"
+    (is (= [[1] [2] [3] [] [4 5 6]] (list-ops/concatenate [[[1] [2]] [[3]] [[]] [[4 5 6]]])))))
+
+(deftest test-0524fba8-3e0f-4531-ad2b-f7a43da86a16
+  (testing "filter vector returning only values that satisfy the filter function -> empty vector"
+    (is (= [] (list-ops/select-if (fn [x] (= (mod x 2) 1)) [])))))
+
+(deftest test-88494bd5-f520-4edb-8631-88e415b62d24
+  (testing "filter vector returning only values that satisfy the filter function -> non-empty vector"
+    (is (= [1 3 5] (list-ops/select-if (fn [x] (= (mod x 2) 1)) [1 2 3 5])))))
+
+(deftest test-1cf0b92d-8d96-41d5-9c21-7b3c37cb6aad
+  (testing "returns the length of a vector -> empty vector"
+    (is (= 0 (list-ops/length [])))))
+
+(deftest test-d7b8d2d9-2d16-44c4-9a19-6e5f237cb71e
+  (testing "returns the length of a vector -> non-empty vector"
+    (is (= 4 (list-ops/length [1 2 3 4])))))
+
+(deftest test-c0bc8962-30e2-4bec-9ae4-668b8ecd75aa
+  (testing "return a vector of elements whose values equal the vector value transformed by the mapping function -> empty vector"
+    (is (= [] (list-ops/apply-to-each (fn [x] (+ x 1)) [])))))
+
+(deftest test-11e71a95-e78b-4909-b8e4-60cdcaec0e91
+  (testing "return a vector of elements whose values equal the vector value transformed by the mapping function -> non-empty vector"
+    (is (= [2 4 6 8] (list-ops/apply-to-each (fn [x] (+ x 1)) [1 3 5 7])))))
+
+(deftest test-36549237-f765-4a4c-bfd9-5d3a8f7b07d2
+  (testing "folds (reduces) the given vector from the left with a function -> empty vector"
+    (is (= 2 (list-ops/foldl (fn [acc el] (* el acc)) [] 2)))))
+
+(deftest test-7a626a3c-03ec-42bc-9840-53f280e13067
+  (testing "folds (reduces) the given vector from the left with a function -> direction independent function applied to non-empty vector"
+    (is (= 15 (list-ops/foldl (fn [acc el] (+ el acc)) [1 2 3 4] 5)))))
+
+(deftest test-d7fcad99-e88e-40e1-a539-4c519681f390
+  (testing "folds (reduces) the given vector from the left with a function -> direction dependent function applied to non-empty vector"
+    (is (= 64 (list-ops/foldl (fn [acc el] (/ el acc)) [1 2 3 4] 24)))))
+
+(deftest test-17214edb-20ba-42fc-bda8-000a5ab525b0
+  (testing "folds (reduces) the given vector from the right with a function -> empty vector"
+    (is (= 2 (list-ops/foldr (fn [acc el] (* el acc)) [] 2)))))
+
+(deftest test-e1c64db7-9253-4a3d-a7c4-5273b9e2a1bd
+  (testing "folds (reduces) the given vector from the right with a function -> direction independent function applied to non-empty vector"
+    (is (= 15 (list-ops/foldr (fn [acc el] (+ el acc)) [1 2 3 4] 5)))))
+
+(deftest test-8066003b-f2ff-437e-9103-66e6df474844
+  (testing "folds (reduces) the given vector from the right with a function -> direction dependent function applied to non-empty vector"
+    (is (= 9 (list-ops/foldr (fn [acc el] (/ el acc)) [1 2 3 4] 24)))))
+
+(deftest test-94231515-050e-4841-943d-d4488ab4ee30
+  (testing "reverse the elements of the vector -> empty vector"
+    (is (= [] (list-ops/reverse-order [])))))
+
+(deftest test-fcc03d1e-42e0-4712-b689-d54ad761f360
+  (testing "reverse the elements of the vector -> non-empty vector"
+    (is (= [7 5 3 1] (list-ops/reverse-order [1 3 5 7])))))
+
+(deftest test-40872990-b5b8-4cb8-9085-d91fc0d05d26
+  (testing "reverse the elements of the vector -> vector of vectors is not flattened"
+    (is (= [[4 5 6] [] [3] [1 2]] (list-ops/reverse-order [[1 2] [3] [] [4 5 6]])))))
diff --git a/exercises/practice/rna-transcription/test/rna_transcription_test.clj b/exercises/practice/rna-transcription/test/rna_transcription_test.clj
index 927a823..eafaf2d 100644
--- a/exercises/practice/rna-transcription/test/rna_transcription_test.clj
+++ b/exercises/practice/rna-transcription/test/rna_transcription_test.clj
@@ -1,21 +1,27 @@
 (ns rna-transcription-test
-  (:require [clojure.test :refer [deftest is]]
+  (:require [clojure.test :refer [deftest testing is]]
             rna-transcription))
 
-(deftest transcribes-cytosine-to-guanine
-  (is (= "G" (rna-transcription/to-rna "C"))))
+(deftest empty-sequence
+  (testing "Empty RNA sequence"
+    (is (= "" (rna-transcription/to-rna "")))))
 
-(deftest transcribes-guanine-to-cytosine
-  (is (= "C" (rna-transcription/to-rna "G"))))
+(deftest rna-complement-of-cytosine
+  (testing "RNA complement of cytosine is guanine"
+    (is (= "G" (rna-transcription/to-rna "C")))))
 
-(deftest transcribes-adenine-to-uracil
-  (is (= "U" (rna-transcription/to-rna "A"))))
+(deftest rna-complement-of-guanine
+  (testing "RNA complement of guanine is cytosine"
+    (is (= "C" (rna-transcription/to-rna "G")))))
 
-(deftest it-transcribes-thymine-to-adenine
-  (is (= "A" (rna-transcription/to-rna "T"))))
+(deftest rna-complement-of-thymine
+  (testing "RNA complement of thymine is adenine"
+    (is (= "A" (rna-transcription/to-rna "T")))))
 
-(deftest it-transcribes-all-nucleotides
-  (is (= "UGCACCAGAAUU" (rna-transcription/to-rna "ACGTGGTCTTAA"))))
+(deftest rna-complement-of-adenine
+  (testing "RNA complement of adenine is uracil"
+    (is (= "U" (rna-transcription/to-rna "A")))))
 
-(deftest it-validates-dna-strands
-  (is (thrown? AssertionError (rna-transcription/to-rna "XCGFGGTDTTAA"))))
+(deftest rna-complement
+  (testing "RNA complement"
+    (is (= "UGCACCAGAAUU" (rna-transcription/to-rna "ACGTGGTCTTAA")))))