Repository: exercism/clojure
Pull request #720 (2025-01-05 19:24:02)

Simplify example file structure
This makes the practice exercise's structure more in line with the concept exercise's structure

tasxatzial: This seems to be changing the location of the example.clj to ".meta/example.clj"

The PRs that refactor test.clj and scaffold the exercises, still appear to be using "./meta/src/example.clj". Not sure about the PR that verifies the exercises, though.

You aware of all this, right? Are you planning to update this PR once the other PRs are merged?


ErikSchierboom: > You aware of all this, right? Are you planning to update this PR once the other PRs are merged?

Yes

Patch:
diff --git a/_generators/list-ops-generator.clj b/_generators/list-ops-generator.clj
index 59f7213..e3eb86b 100644
--- a/_generators/list-ops-generator.clj
+++ b/_generators/list-ops-generator.clj
@@ -17,12 +17,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"
@@ -38,8 +38,7 @@
                  :exec-fn cognitect.test-runner.api/test}}}"))
 
 (comment
-  (init-deps! data)
-  )
+  (init-deps! data))
 
 (defn init-lein! [data]
   (let [slug (:exercise (:canonical-data data))]
@@ -52,8 +51,7 @@
 "))))
 
 (comment
-  (init-lein! data)
-  )
+  (init-lein! data))
 
 (defn test-ns-form [data]
   (str "(ns " (:exercise data) "-test
@@ -67,14 +65,13 @@
   (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)) "] " 
+    (str "(fn [" (apply str (interpose " " arg-strs)) "] "
          "(" op " " arg1 " " arg2 "))")))
 
 (comment
-  (trans-fn "(x) -> x + 1")  
+  (trans-fn "(x) -> x + 1")
   (trans-fn "(x, y) -> x * y")
-  (trans-fn "(acc, el) -> el * acc")
-  )
+  (trans-fn "(acc, el) -> el * acc"))
 
 (defn testing-form [slug test-case]
   (let [property (symbol (str slug "/" (:property test-case)))
@@ -85,8 +82,7 @@
          (reverse (into (list property) args)) ")))")))
 
 (comment
-  (testing-form "list-ops" (first (:cases (first (:cases (:canonical-data data))))))
-  )
+  (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
@@ -98,8 +94,7 @@
     (map #(testing-form (:exercise (:canonical-data data)) %) test-cases)))
 
 (comment
-  (testing-forms "append" data)
-  )
+  (testing-forms "append" data))
 
 (defn deftest-forms [data]
   (for [property (distinct (map :property (mapcat :cases
@@ -110,8 +105,7 @@
          ")")))
 
 (comment
-  (deftest-forms data)
-  )
+  (deftest-forms data))
 
 (defn init-tests! [data]
   (let [path (fs/path "exercises" "practice"
@@ -127,8 +121,7 @@
                                      (deftest-forms data)))))))
 
 (comment
-  (init-tests! data)
-  )
+  (init-tests! data))
 
 (defn init-src! [data]
   (spit (str (fs/file "exercises" "practice" (:exercise (:canonical-data data)) "src"
@@ -141,8 +134,7 @@
                                      (str "(defn " property " []\n  )")))))))
 
 (comment
-  (init-src! data)
-  )
+  (init-src! data))
 
 (defn init-description! [data]
   (let [path ["exercises" "practice" (:exercise (:canonical-data data)) ".docs"]]
@@ -152,26 +144,24 @@
             (:description data)))))
 
 (comment
-  (init-description! data)
-  )
+  (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"]},
+     :files {:solution [(str "src/" (str/replace slug "-" "_") ".clj")],
+             :test [(str "test/" (str/replace slug "-" "_") "_test.clj")],
+             :example [".meta/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/_generators/zipper-generator.clj b/_generators/zipper-generator.clj
index 466a8e7..042cb6f 100644
--- a/_generators/zipper-generator.clj
+++ b/_generators/zipper-generator.clj
@@ -124,7 +124,7 @@
      :contributors [],
      :files {:solution [(str "src/" (str/replace slug "-" "_") ".clj")],
              :test [(str "test/" (str/replace slug "-" "_") "_test.clj")],
-             :example [".meta/src/example.clj"]},
+             :example [".meta/example.clj"]},
      :blurb blurb}))
 
 (defn init-config! [data]
diff --git a/bin/add-practice-exercise b/bin/add-practice-exercise
new file mode 100755
index 0000000..f27001d
--- /dev/null
+++ b/bin/add-practice-exercise
@@ -0,0 +1,109 @@
+#!/usr/bin/env bash
+
+# Synopsis:
+# Scaffold the files for a new practice exercise.
+# After creating the exercise, follow the instructions in the output.
+
+# Example:
+# bin/add-practice-exercise two-fer
+
+# Example with difficulty:
+# bin/add-practice-exercise -d 5 two-fer
+
+# Example with author and difficulty:
+# bin/add-practice-exercise -a foo -d 3 two-fer
+
+set -euo pipefail
+scriptname=$0
+
+help_and_exit() {
+    echo >&2 "Scaffold the files for a new practice exercise."
+    echo >&2 "Usage: ${scriptname} [-h] [-a author] [-d difficulty] <exercise-slug>"
+    echo >&2 "Where: author is the GitHub username of the exercise creator."
+    echo >&2 "Where: difficulty is between 1 (easiest) to 10 (hardest)."
+    exit 1
+}
+
+die() { echo >&2 "$*"; exit 1; }
+
+required_tool() {
+    command -v "${1}" >/dev/null 2>&1 ||
+        die "${1} is required but not installed. Please install it and make sure it's in your PATH."
+}
+
+require_files_template() {
+    jq -e --arg key "${1}" '.files[$key] | length > 0' config.json > /dev/null ||
+        die "The '.files.${1}' array in the 'config.json' file is empty. Please add at least one file. See https://exercism.org/docs/building/tracks/config-json#h-files for more information."
+}
+
+required_tool jq
+
+require_files_template "solution"
+require_files_template "test"
+require_files_template "example"
+
+[[ -f ./bin/fetch-configlet ]] || die "Run this script from the repo's root directory."
+
+author=''
+difficulty='1'
+while getopts :ha:d: opt; do
+    case $opt in
+        h) help_and_exit ;;
+        a) author=$OPTARG ;;
+        d) difficulty=$OPTARG ;;
+        ?) echo >&2 "Unknown option: -$OPTARG"; help_and_exit ;;
+    esac
+done
+shift "$((OPTIND - 1))"
+
+(( $# >= 1 )) || help_and_exit
+
+slug="${1}"
+
+if [[ -z "${author}" ]]; then
+    read -rp 'Your GitHub username: ' author
+fi
+
+./bin/fetch-configlet
+./bin/configlet create --practice-exercise "${slug}" --author "${author}" --difficulty "${difficulty}"
+
+exercise_dir="exercises/practice/${slug}"
+config_json_file="${exercise_dir}/.meta/config.json"
+files=$(jq -r --arg dir "${exercise_dir}" '.files | to_entries | map({key: .key, value: (.value | map("'"'"'" + $dir + "/" + . + "'"'"'") | join(" and "))}) | from_entries' "${config_json_file}")
+
+sample_exercise_dir="exercises/practice/acronym"
+for sample_file in deps.edn project.clj; do
+    if [[ ! -f "${sample_exercise_dir}/${sample_file}" ]]; then
+        die "The sample exercise directory is missing the '${sample_file}' file."
+    fi
+
+    cp "${sample_exercise_dir}/${sample_file}" "${exercise_dir}/${sample_file}"
+done
+
+sed -i "s/acronym/${slug}/g" "${exercise_dir}/project.clj"
+
+test_file=$(jq -r '.files.test[0]' "${config_json_file}")
+cat >"${exercise_dir}/${test_file}" << TEST_FILE
+(ns ${slug}-test
+  (:require [clojure.test :refer [deftest testing is]]
+            ${slug}))
+TEST_FILE
+
+for file_type in solution example; do
+    solution_file=$(jq -r --arg file_type "${file_type}" '.files[$file_type][0]' "${config_json_file}")
+    cat >"${exercise_dir}/${solution_file}" << FILE
+(ns ${slug})
+FILE
+done
+
+cat << NEXT_STEPS
+Your next steps are:
+- Create the test suite in $(jq -r '.test' <<< "${files}")
+  - The tests should be based on the canonical data at 'https://github.com/exercism/problem-specifications/blob/main/exercises/${slug}/canonical-data.json'
+  - Any test cases you don't implement, mark them in 'exercises/practice/${slug}/.meta/tests.toml' with "include = false"
+- Create the example solution in $(jq -r '.example' <<< "${files}")
+- Verify the example solution passes the tests by running 'bin/verify-exercises ${slug}'
+- Create the stub solution in $(jq -r '.solution' <<< "${files}")
+- Update the 'difficulty' value for the exercise's entry in the 'config.json' file in the repo's root
+- Validate CI using 'bin/configlet lint' and 'bin/configlet fmt'
+NEXT_STEPS
diff --git a/bin/verify-exercises b/bin/verify-exercises
new file mode 100755
index 0000000..ca58ff9
--- /dev/null
+++ b/bin/verify-exercises
@@ -0,0 +1,24 @@
+#!/usr/bin/env bash
+
+# Synopsis:
+# Verify that each exercise's example/exemplar solution passes the tests.
+# You can either verify all exercises or a single exercise.
+
+# Example: verify all exercises
+# bin/verify-exercises
+
+# Example: verify single exercise
+# bin/verify-exercises two-fer
+
+set -eo pipefail
+
+die() { echo "$*" >&2; exit 1; }
+
+required_tool() {
+    command -v "${1}" >/dev/null 2>&1 ||
+        die "${1} is required but not installed. Please install it and make sure it's in your PATH."
+}
+
+required_tool bb
+
+bb test.clj "$@"
diff --git a/bin/verify-exercises-in-docker b/bin/verify-exercises-in-docker
new file mode 100755
index 0000000..906f6ce
--- /dev/null
+++ b/bin/verify-exercises-in-docker
@@ -0,0 +1,92 @@
+#!/usr/bin/env bash
+
+# Synopsis:
+# Verify that each exercise's example/exemplar solution passes the tests
+# using the track's test runner Docker image.
+# You can either verify all exercises or a single exercise.
+
+# Example: verify all exercises in Docker
+# bin/verify-exercises-in-docker
+
+# Example: verify single exercise in Docker
+# bin/verify-exercises-in-docker two-fer
+
+set -eo pipefail
+
+die() { echo "$*" >&2; exit 1; }
+
+required_tool() {
+    command -v "${1}" >/dev/null 2>&1 ||
+        die "${1} is required but not installed. Please install it and make sure it's in your PATH."
+}
+
+required_tool docker
+
+copy_example_or_examplar_to_solution() {
+    jq -c '[.files.solution, .files.exemplar // .files.example] | transpose | map({src: .[1], dst: .[0]}) | .[]' .meta/config.json \
+    | while read -r src_and_dst; do
+        cp "$(jq -r '.src' <<< "${src_and_dst}")" "$(jq -r '.dst' <<< "${src_and_dst}")"
+    done
+}
+
+pull_docker_image() {
+    # shellcheck disable=SC1083
+    docker pull exercism/clojure-test-runner ||
+        die $'Could not find the `exercism/clojure-test-runner` Docker image.\nCheck the test runner docs at https://exercism.org/docs/building/tooling/test-runners for more information.'
+}
+
+run_tests() {
+    local slug
+    slug="${1}"
+
+    # shellcheck disable=SC1083
+    docker run \
+        --rm \
+        --network none \
+        --read-only \
+        --mount type=bind,src="${PWD}",dst=/solution \
+        --mount type=bind,src="${PWD}",dst=/output \
+        --mount type=tmpfs,dst=/tmp \
+        exercism/clojure-test-runner "${slug}" /solution /output
+    jq -e '.status == "pass"' "${PWD}/results.json" >/dev/null 2>&1
+}
+
+verify_exercise() {
+    local dir
+    local slug
+    local tmp_dir
+    dir=$(realpath "${1}")
+    slug=$(basename "${dir}")
+    tmp_dir=$(mktemp -d -t "exercism-verify-${slug}-XXXXX")
+
+    echo "Verifying ${slug} exercise..."
+
+    (
+        trap 'rm -rf "$tmp_dir"' EXIT    # remove tempdir when subshell ends
+        cp -r "${dir}/." "${tmp_dir}"
+        cd "${tmp_dir}"
+
+        copy_example_or_examplar_to_solution
+        run_tests "${slug}"
+    )
+}
+
+verify_exercises() {
+    local exercise_slug
+    exercise_slug="${1}"
+
+    shopt -s nullglob
+    count=0
+    for exercise_dir in ./exercises/{concept,practice}/${exercise_slug}/; do
+        if [[ -d "${exercise_dir}" ]]; then
+            verify_exercise "${exercise_dir}"
+            ((++count))
+        fi
+    done
+    ((count > 0)) || die 'no matching exercises found!'
+}
+
+pull_docker_image
+
+exercise_slug="${1:-*}"
+verify_exercises "${exercise_slug}"
diff --git a/config.json b/config.json
index f1b2aba..f4ff734 100644
--- a/config.json
+++ b/config.json
@@ -26,7 +26,7 @@
       "test/%{snake_slug}_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ],
     "exemplar": [
       ".meta/exemplar.clj"
diff --git a/exercises/practice/accumulate/.meta/config.json b/exercises/practice/accumulate/.meta/config.json
index 63b15e1..fb40def 100644
--- a/exercises/practice/accumulate/.meta/config.json
+++ b/exercises/practice/accumulate/.meta/config.json
@@ -1,7 +1,5 @@
 {
-  "authors": [
-    "geofflane"
-  ],
+  "authors": ["geofflane"],
   "contributors": [
     "AndreaCrotti",
     "canweriotnow",
@@ -14,15 +12,9 @@
     "yurrriq"
   ],
   "files": {
-    "solution": [
-      "src/accumulate.clj"
-    ],
-    "test": [
-      "test/accumulate_test.clj"
-    ],
-    "example": [
-      ".meta/src/example.clj"
-    ]
+    "solution": ["src/accumulate.clj"],
+    "test": ["test/accumulate_test.clj"],
+    "example": [".meta/example.clj"]
   },
   "blurb": "Implement the `accumulate` operation, which, given a collection and an operation to perform on each element of the collection, returns a new collection containing the result of applying that operation to each element of the input collection.",
   "source": "Conversation with James Edward Gray II",
diff --git a/exercises/practice/accumulate/.meta/src/example.clj b/exercises/practice/accumulate/.meta/example.clj
similarity index 100%
rename from exercises/practice/accumulate/.meta/src/example.clj
rename to exercises/practice/accumulate/.meta/example.clj
diff --git a/exercises/practice/acronym/.meta/config.json b/exercises/practice/acronym/.meta/config.json
index 9878e02..4599cf8 100644
--- a/exercises/practice/acronym/.meta/config.json
+++ b/exercises/practice/acronym/.meta/config.json
@@ -15,7 +15,7 @@
       "test/acronym_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Convert a long phrase to its acronym.",
diff --git a/exercises/practice/acronym/.meta/src/example.clj b/exercises/practice/acronym/.meta/example.clj
similarity index 100%
rename from exercises/practice/acronym/.meta/src/example.clj
rename to exercises/practice/acronym/.meta/example.clj
diff --git a/exercises/practice/all-your-base/.meta/config.json b/exercises/practice/all-your-base/.meta/config.json
index de899b1..95cb2dd 100644
--- a/exercises/practice/all-your-base/.meta/config.json
+++ b/exercises/practice/all-your-base/.meta/config.json
@@ -15,7 +15,7 @@
       "test/all_your_base_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Convert a number, represented as a sequence of digits in one base, to any other base."
diff --git a/exercises/practice/all-your-base/.meta/src/example.clj b/exercises/practice/all-your-base/.meta/example.clj
similarity index 100%
rename from exercises/practice/all-your-base/.meta/src/example.clj
rename to exercises/practice/all-your-base/.meta/example.clj
diff --git a/exercises/practice/allergies/.meta/config.json b/exercises/practice/allergies/.meta/config.json
index a137e05..998ef0e 100644
--- a/exercises/practice/allergies/.meta/config.json
+++ b/exercises/practice/allergies/.meta/config.json
@@ -21,7 +21,7 @@
       "test/allergies_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Given a person's allergy score, determine whether or not they're allergic to a given item, and their full list of allergies.",
diff --git a/exercises/practice/allergies/.meta/src/example.clj b/exercises/practice/allergies/.meta/example.clj
similarity index 100%
rename from exercises/practice/allergies/.meta/src/example.clj
rename to exercises/practice/allergies/.meta/example.clj
diff --git a/exercises/practice/anagram/.meta/config.json b/exercises/practice/anagram/.meta/config.json
index f29ad60..9793cbf 100644
--- a/exercises/practice/anagram/.meta/config.json
+++ b/exercises/practice/anagram/.meta/config.json
@@ -26,7 +26,7 @@
       "test/anagram_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Given a word and a list of possible anagrams, select the correct sublist.",
diff --git a/exercises/practice/anagram/.meta/src/example.clj b/exercises/practice/anagram/.meta/example.clj
similarity index 100%
rename from exercises/practice/anagram/.meta/src/example.clj
rename to exercises/practice/anagram/.meta/example.clj
diff --git a/exercises/practice/armstrong-numbers/.meta/config.json b/exercises/practice/armstrong-numbers/.meta/config.json
index a39c443..26ce55a 100644
--- a/exercises/practice/armstrong-numbers/.meta/config.json
+++ b/exercises/practice/armstrong-numbers/.meta/config.json
@@ -18,7 +18,7 @@
       "test/armstrong_numbers_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Determine if a number is an Armstrong number.",
diff --git a/exercises/practice/armstrong-numbers/.meta/src/example.clj b/exercises/practice/armstrong-numbers/.meta/example.clj
similarity index 100%
rename from exercises/practice/armstrong-numbers/.meta/src/example.clj
rename to exercises/practice/armstrong-numbers/.meta/example.clj
diff --git a/exercises/practice/atbash-cipher/.meta/config.json b/exercises/practice/atbash-cipher/.meta/config.json
index 48a0632..c837e48 100644
--- a/exercises/practice/atbash-cipher/.meta/config.json
+++ b/exercises/practice/atbash-cipher/.meta/config.json
@@ -20,7 +20,7 @@
       "test/atbash_cipher_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Create an implementation of the atbash cipher, an ancient encryption system created in the Middle East.",
diff --git a/exercises/practice/atbash-cipher/.meta/src/example.clj b/exercises/practice/atbash-cipher/.meta/example.clj
similarity index 100%
rename from exercises/practice/atbash-cipher/.meta/src/example.clj
rename to exercises/practice/atbash-cipher/.meta/example.clj
diff --git a/exercises/practice/bank-account/.meta/config.json b/exercises/practice/bank-account/.meta/config.json
index 2b8ec48..a3fda6d 100644
--- a/exercises/practice/bank-account/.meta/config.json
+++ b/exercises/practice/bank-account/.meta/config.json
@@ -21,7 +21,7 @@
       "test/bank_account_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Simulate a bank account supporting opening/closing, withdraws, and deposits of money. Watch out for concurrent transactions!"
diff --git a/exercises/practice/bank-account/.meta/src/example.clj b/exercises/practice/bank-account/.meta/example.clj
similarity index 100%
rename from exercises/practice/bank-account/.meta/src/example.clj
rename to exercises/practice/bank-account/.meta/example.clj
diff --git a/exercises/practice/beer-song/.meta/config.json b/exercises/practice/beer-song/.meta/config.json
index ff13d12..5754642 100644
--- a/exercises/practice/beer-song/.meta/config.json
+++ b/exercises/practice/beer-song/.meta/config.json
@@ -25,7 +25,7 @@
       "test/beer_song_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Produce the lyrics to that beloved classic, that field-trip favorite: 99 Bottles of Beer on the Wall.",
diff --git a/exercises/practice/beer-song/.meta/src/example.clj b/exercises/practice/beer-song/.meta/example.clj
similarity index 100%
rename from exercises/practice/beer-song/.meta/src/example.clj
rename to exercises/practice/beer-song/.meta/example.clj
diff --git a/exercises/practice/binary-search-tree/.meta/config.json b/exercises/practice/binary-search-tree/.meta/config.json
index 61db42b..bdce195 100644
--- a/exercises/practice/binary-search-tree/.meta/config.json
+++ b/exercises/practice/binary-search-tree/.meta/config.json
@@ -20,7 +20,7 @@
       "test/binary_search_tree_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Insert and search for numbers in a binary tree.",
diff --git a/exercises/practice/binary-search-tree/.meta/src/example.clj b/exercises/practice/binary-search-tree/.meta/example.clj
similarity index 100%
rename from exercises/practice/binary-search-tree/.meta/src/example.clj
rename to exercises/practice/binary-search-tree/.meta/example.clj
diff --git a/exercises/practice/binary-search/.meta/config.json b/exercises/practice/binary-search/.meta/config.json
index 3f2f53b..0541983 100644
--- a/exercises/practice/binary-search/.meta/config.json
+++ b/exercises/practice/binary-search/.meta/config.json
@@ -20,7 +20,7 @@
       "test/binary_search_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Implement a binary search algorithm.",
diff --git a/exercises/practice/binary-search/.meta/src/example.clj b/exercises/practice/binary-search/.meta/example.clj
similarity index 100%
rename from exercises/practice/binary-search/.meta/src/example.clj
rename to exercises/practice/binary-search/.meta/example.clj
diff --git a/exercises/practice/binary/.meta/config.json b/exercises/practice/binary/.meta/config.json
index 587a4f6..4b9da1b 100644
--- a/exercises/practice/binary/.meta/config.json
+++ b/exercises/practice/binary/.meta/config.json
@@ -1,7 +1,5 @@
 {
-  "authors": [
-    "rubysolo"
-  ],
+  "authors": ["rubysolo"],
   "contributors": [
     "AndreaCrotti",
     "canweriotnow",
@@ -14,15 +12,9 @@
     "yurrriq"
   ],
   "files": {
-    "solution": [
-      "src/binary.clj"
-    ],
-    "test": [
-      "test/binary_test.clj"
-    ],
-    "example": [
-      ".meta/src/example.clj"
-    ]
+    "solution": ["src/binary.clj"],
+    "test": ["test/binary_test.clj"],
+    "example": [".meta/example.clj"]
   },
   "blurb": "Convert a binary number, represented as a string (e.g. '101010'), to its decimal equivalent using first principles.",
   "source": "All of Computer Science",
diff --git a/exercises/practice/binary/.meta/src/example.clj b/exercises/practice/binary/.meta/example.clj
similarity index 100%
rename from exercises/practice/binary/.meta/src/example.clj
rename to exercises/practice/binary/.meta/example.clj
diff --git a/exercises/practice/bob/.meta/config.json b/exercises/practice/bob/.meta/config.json
index 2df3702..515e8a2 100644
--- a/exercises/practice/bob/.meta/config.json
+++ b/exercises/practice/bob/.meta/config.json
@@ -29,7 +29,7 @@
       "test/bob_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Bob is a lackadaisical teenager. In conversation, his responses are very limited.",
diff --git a/exercises/practice/bob/.meta/src/example.clj b/exercises/practice/bob/.meta/example.clj
similarity index 100%
rename from exercises/practice/bob/.meta/src/example.clj
rename to exercises/practice/bob/.meta/example.clj
diff --git a/exercises/practice/change/.meta/config.json b/exercises/practice/change/.meta/config.json
index c648272..107dad7 100644
--- a/exercises/practice/change/.meta/config.json
+++ b/exercises/practice/change/.meta/config.json
@@ -16,7 +16,7 @@
       "test/change_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Correctly determine change to be given using the least number of coins.",
diff --git a/exercises/practice/change/.meta/src/example.clj b/exercises/practice/change/.meta/example.clj
similarity index 100%
rename from exercises/practice/change/.meta/src/example.clj
rename to exercises/practice/change/.meta/example.clj
diff --git a/exercises/practice/clock/.meta/config.json b/exercises/practice/clock/.meta/config.json
index fd7444c..101b7f5 100644
--- a/exercises/practice/clock/.meta/config.json
+++ b/exercises/practice/clock/.meta/config.json
@@ -14,7 +14,7 @@
       "test/clock_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Implement a clock that handles times without dates.",
diff --git a/exercises/practice/clock/.meta/src/example.clj b/exercises/practice/clock/.meta/example.clj
similarity index 100%
rename from exercises/practice/clock/.meta/src/example.clj
rename to exercises/practice/clock/.meta/example.clj
diff --git a/exercises/practice/collatz-conjecture/.meta/config.json b/exercises/practice/collatz-conjecture/.meta/config.json
index 763b89d..437553a 100644
--- a/exercises/practice/collatz-conjecture/.meta/config.json
+++ b/exercises/practice/collatz-conjecture/.meta/config.json
@@ -14,7 +14,7 @@
       "test/collatz_conjecture_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Calculate the number of steps to reach 1 using the Collatz conjecture.",
diff --git a/exercises/practice/collatz-conjecture/.meta/src/example.clj b/exercises/practice/collatz-conjecture/.meta/example.clj
similarity index 100%
rename from exercises/practice/collatz-conjecture/.meta/src/example.clj
rename to exercises/practice/collatz-conjecture/.meta/example.clj
diff --git a/exercises/practice/complex-numbers/.meta/config.json b/exercises/practice/complex-numbers/.meta/config.json
index 5decca6..c50b24a 100644
--- a/exercises/practice/complex-numbers/.meta/config.json
+++ b/exercises/practice/complex-numbers/.meta/config.json
@@ -13,7 +13,7 @@
       "test/complex_numbers_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Implement complex numbers.",
diff --git a/exercises/practice/complex-numbers/.meta/src/example.clj b/exercises/practice/complex-numbers/.meta/example.clj
similarity index 100%
rename from exercises/practice/complex-numbers/.meta/src/example.clj
rename to exercises/practice/complex-numbers/.meta/example.clj
diff --git a/exercises/practice/crypto-square/.meta/config.json b/exercises/practice/crypto-square/.meta/config.json
index eb9b629..d7f662f 100644
--- a/exercises/practice/crypto-square/.meta/config.json
+++ b/exercises/practice/crypto-square/.meta/config.json
@@ -22,7 +22,7 @@
       "test/crypto_square_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Implement the classic method for composing secret messages called a square code.",
diff --git a/exercises/practice/crypto-square/.meta/src/example.clj b/exercises/practice/crypto-square/.meta/example.clj
similarity index 100%
rename from exercises/practice/crypto-square/.meta/src/example.clj
rename to exercises/practice/crypto-square/.meta/example.clj
diff --git a/exercises/practice/diamond/.meta/config.json b/exercises/practice/diamond/.meta/config.json
index 22aff37..16d7e12 100644
--- a/exercises/practice/diamond/.meta/config.json
+++ b/exercises/practice/diamond/.meta/config.json
@@ -15,7 +15,7 @@
       "test/diamond_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Given a letter, print a diamond starting with 'A' with the supplied letter at the widest point.",
diff --git a/exercises/practice/diamond/.meta/src/example.clj b/exercises/practice/diamond/.meta/example.clj
similarity index 100%
rename from exercises/practice/diamond/.meta/src/example.clj
rename to exercises/practice/diamond/.meta/example.clj
diff --git a/exercises/practice/difference-of-squares/.meta/config.json b/exercises/practice/difference-of-squares/.meta/config.json
index acac3c6..109dcd4 100644
--- a/exercises/practice/difference-of-squares/.meta/config.json
+++ b/exercises/practice/difference-of-squares/.meta/config.json
@@ -21,7 +21,7 @@
       "test/difference_of_squares_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Find the difference between the square of the sum and the sum of the squares of the first N natural numbers.",
diff --git a/exercises/practice/difference-of-squares/.meta/src/example.clj b/exercises/practice/difference-of-squares/.meta/example.clj
similarity index 100%
rename from exercises/practice/difference-of-squares/.meta/src/example.clj
rename to exercises/practice/difference-of-squares/.meta/example.clj
diff --git a/exercises/practice/dominoes/.meta/config.json b/exercises/practice/dominoes/.meta/config.json
index f2060e5..e016c77 100644
--- a/exercises/practice/dominoes/.meta/config.json
+++ b/exercises/practice/dominoes/.meta/config.json
@@ -14,7 +14,7 @@
       "test/dominoes_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Make a chain of dominoes."
diff --git a/exercises/practice/dominoes/.meta/src/example.clj b/exercises/practice/dominoes/.meta/example.clj
similarity index 100%
rename from exercises/practice/dominoes/.meta/src/example.clj
rename to exercises/practice/dominoes/.meta/example.clj
diff --git a/exercises/practice/eliuds-eggs/.meta/config.json b/exercises/practice/eliuds-eggs/.meta/config.json
index b861900..f6f92fa 100644
--- a/exercises/practice/eliuds-eggs/.meta/config.json
+++ b/exercises/practice/eliuds-eggs/.meta/config.json
@@ -10,7 +10,7 @@
       "test/eliuds_eggs_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/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.",
diff --git a/exercises/practice/eliuds-eggs/.meta/src/example.clj b/exercises/practice/eliuds-eggs/.meta/example.clj
similarity index 100%
rename from exercises/practice/eliuds-eggs/.meta/src/example.clj
rename to exercises/practice/eliuds-eggs/.meta/example.clj
diff --git a/exercises/practice/etl/.meta/config.json b/exercises/practice/etl/.meta/config.json
index c3135dd..dd4912b 100644
--- a/exercises/practice/etl/.meta/config.json
+++ b/exercises/practice/etl/.meta/config.json
@@ -24,7 +24,7 @@
       "test/etl_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Change the data format for scoring a game to more easily add other languages.",
diff --git a/exercises/practice/etl/.meta/src/example.clj b/exercises/practice/etl/.meta/example.clj
similarity index 100%
rename from exercises/practice/etl/.meta/src/example.clj
rename to exercises/practice/etl/.meta/example.clj
diff --git a/exercises/practice/flatten-array/.meta/config.json b/exercises/practice/flatten-array/.meta/config.json
index ce766b7..5f7a1af 100644
--- a/exercises/practice/flatten-array/.meta/config.json
+++ b/exercises/practice/flatten-array/.meta/config.json
@@ -17,7 +17,7 @@
       "test/flatten_array_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Take a nested list and return a single list with all values except nil/null.",
diff --git a/exercises/practice/flatten-array/.meta/src/example.clj b/exercises/practice/flatten-array/.meta/example.clj
similarity index 100%
rename from exercises/practice/flatten-array/.meta/src/example.clj
rename to exercises/practice/flatten-array/.meta/example.clj
diff --git a/exercises/practice/gigasecond/.meta/config.json b/exercises/practice/gigasecond/.meta/config.json
index 8ca96a7..7b68a60 100644
--- a/exercises/practice/gigasecond/.meta/config.json
+++ b/exercises/practice/gigasecond/.meta/config.json
@@ -21,7 +21,7 @@
       "test/gigasecond_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Given a moment, determine the moment that would be after a gigasecond has passed.",
diff --git a/exercises/practice/gigasecond/.meta/src/example.clj b/exercises/practice/gigasecond/.meta/example.clj
similarity index 100%
rename from exercises/practice/gigasecond/.meta/src/example.clj
rename to exercises/practice/gigasecond/.meta/example.clj
diff --git a/exercises/practice/go-counting/.meta/config.json b/exercises/practice/go-counting/.meta/config.json
index bed2680..5656548 100644
--- a/exercises/practice/go-counting/.meta/config.json
+++ b/exercises/practice/go-counting/.meta/config.json
@@ -13,7 +13,7 @@
       "test/go_counting_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Count the scored points on a Go board."
diff --git a/exercises/practice/go-counting/.meta/src/example.clj b/exercises/practice/go-counting/.meta/example.clj
similarity index 100%
rename from exercises/practice/go-counting/.meta/src/example.clj
rename to exercises/practice/go-counting/.meta/example.clj
diff --git a/exercises/practice/grade-school/.meta/config.json b/exercises/practice/grade-school/.meta/config.json
index 3ba838e..a6fc70c 100644
--- a/exercises/practice/grade-school/.meta/config.json
+++ b/exercises/practice/grade-school/.meta/config.json
@@ -23,7 +23,7 @@
       "test/grade_school_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Given students' names along with the grade that they are in, create a roster for the school.",
diff --git a/exercises/practice/grade-school/.meta/src/example.clj b/exercises/practice/grade-school/.meta/example.clj
similarity index 100%
rename from exercises/practice/grade-school/.meta/src/example.clj
rename to exercises/practice/grade-school/.meta/example.clj
diff --git a/exercises/practice/grains/.meta/config.json b/exercises/practice/grains/.meta/config.json
index 549aafd..3ad3234 100644
--- a/exercises/practice/grains/.meta/config.json
+++ b/exercises/practice/grains/.meta/config.json
@@ -21,7 +21,7 @@
       "test/grains_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Calculate the number of grains of wheat on a chessboard given that the number on each square doubles.",
diff --git a/exercises/practice/grains/.meta/src/example.clj b/exercises/practice/grains/.meta/example.clj
similarity index 100%
rename from exercises/practice/grains/.meta/src/example.clj
rename to exercises/practice/grains/.meta/example.clj
diff --git a/exercises/practice/hamming/.meta/config.json b/exercises/practice/hamming/.meta/config.json
index 884ef51..896a329 100644
--- a/exercises/practice/hamming/.meta/config.json
+++ b/exercises/practice/hamming/.meta/config.json
@@ -16,7 +16,7 @@
       "test/hamming_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Calculate the Hamming difference between two DNA strands.",
diff --git a/exercises/practice/hamming/.meta/src/example.clj b/exercises/practice/hamming/.meta/example.clj
similarity index 100%
rename from exercises/practice/hamming/.meta/src/example.clj
rename to exercises/practice/hamming/.meta/example.clj
diff --git a/exercises/practice/hello-world/.meta/config.json b/exercises/practice/hello-world/.meta/config.json
index d8dc47c..99e9304 100644
--- a/exercises/practice/hello-world/.meta/config.json
+++ b/exercises/practice/hello-world/.meta/config.json
@@ -17,7 +17,7 @@
       "test/hello_world_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Exercism's classic introductory exercise. Just say \"Hello, World!\".",
diff --git a/exercises/practice/hello-world/.meta/src/example.clj b/exercises/practice/hello-world/.meta/example.clj
similarity index 100%
rename from exercises/practice/hello-world/.meta/src/example.clj
rename to exercises/practice/hello-world/.meta/example.clj
diff --git a/exercises/practice/hexadecimal/.meta/config.json b/exercises/practice/hexadecimal/.meta/config.json
index d49b96a..005160d 100644
--- a/exercises/practice/hexadecimal/.meta/config.json
+++ b/exercises/practice/hexadecimal/.meta/config.json
@@ -1,7 +1,5 @@
 {
-  "authors": [
-    "geofflane"
-  ],
+  "authors": ["geofflane"],
   "contributors": [
     "AndreaCrotti",
     "canweriotnow",
@@ -13,15 +11,9 @@
     "yurrriq"
   ],
   "files": {
-    "solution": [
-      "src/hexadecimal.clj"
-    ],
-    "test": [
-      "test/hexadecimal_test.clj"
-    ],
-    "example": [
-      ".meta/src/example.clj"
-    ]
+    "solution": ["src/hexadecimal.clj"],
+    "test": ["test/hexadecimal_test.clj"],
+    "example": [".meta/example.clj"]
   },
   "blurb": "Convert a hexadecimal number, represented as a string (e.g. \"10af8c\"), to its decimal equivalent using first principles (i.e. no, you may not use built-in or external libraries to accomplish the conversion).",
   "source": "All of Computer Science",
diff --git a/exercises/practice/hexadecimal/.meta/src/example.clj b/exercises/practice/hexadecimal/.meta/example.clj
similarity index 100%
rename from exercises/practice/hexadecimal/.meta/src/example.clj
rename to exercises/practice/hexadecimal/.meta/example.clj
diff --git a/exercises/practice/isbn-verifier/.meta/config.json b/exercises/practice/isbn-verifier/.meta/config.json
index bfdf821..afb7e59 100644
--- a/exercises/practice/isbn-verifier/.meta/config.json
+++ b/exercises/practice/isbn-verifier/.meta/config.json
@@ -14,7 +14,7 @@
       "test/isbn_verifier_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Check if a given string is a valid ISBN-10 number.",
diff --git a/exercises/practice/isbn-verifier/.meta/src/example.clj b/exercises/practice/isbn-verifier/.meta/example.clj
similarity index 100%
rename from exercises/practice/isbn-verifier/.meta/src/example.clj
rename to exercises/practice/isbn-verifier/.meta/example.clj
diff --git a/exercises/practice/isogram/.meta/config.json b/exercises/practice/isogram/.meta/config.json
index a4281a2..4197634 100644
--- a/exercises/practice/isogram/.meta/config.json
+++ b/exercises/practice/isogram/.meta/config.json
@@ -16,7 +16,7 @@
       "test/isogram_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Determine if a word or phrase is an isogram.",
diff --git a/exercises/practice/isogram/.meta/src/example.clj b/exercises/practice/isogram/.meta/example.clj
similarity index 100%
rename from exercises/practice/isogram/.meta/src/example.clj
rename to exercises/practice/isogram/.meta/example.clj
diff --git a/exercises/practice/kindergarten-garden/.meta/config.json b/exercises/practice/kindergarten-garden/.meta/config.json
index a018654..633c794 100644
--- a/exercises/practice/kindergarten-garden/.meta/config.json
+++ b/exercises/practice/kindergarten-garden/.meta/config.json
@@ -25,7 +25,7 @@
       "test/kindergarten_garden_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Given a diagram, determine which plants each child in the kindergarten class is responsible for.",
diff --git a/exercises/practice/kindergarten-garden/.meta/src/example.clj b/exercises/practice/kindergarten-garden/.meta/example.clj
similarity index 100%
rename from exercises/practice/kindergarten-garden/.meta/src/example.clj
rename to exercises/practice/kindergarten-garden/.meta/example.clj
diff --git a/exercises/practice/largest-series-product/.meta/config.json b/exercises/practice/largest-series-product/.meta/config.json
index f3acdb0..03bf57c 100644
--- a/exercises/practice/largest-series-product/.meta/config.json
+++ b/exercises/practice/largest-series-product/.meta/config.json
@@ -21,7 +21,7 @@
       "test/largest_series_product_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Given a string of digits, calculate the largest product for a contiguous substring of digits of length n.",
diff --git a/exercises/practice/largest-series-product/.meta/src/example.clj b/exercises/practice/largest-series-product/.meta/example.clj
similarity index 100%
rename from exercises/practice/largest-series-product/.meta/src/example.clj
rename to exercises/practice/largest-series-product/.meta/example.clj
diff --git a/exercises/practice/leap/.meta/config.json b/exercises/practice/leap/.meta/config.json
index 653c398..6f85325 100644
--- a/exercises/practice/leap/.meta/config.json
+++ b/exercises/practice/leap/.meta/config.json
@@ -25,7 +25,7 @@
       "test/leap_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Determine whether a given year is a leap year.",
diff --git a/exercises/practice/leap/.meta/src/example.clj b/exercises/practice/leap/.meta/example.clj
similarity index 100%
rename from exercises/practice/leap/.meta/src/example.clj
rename to exercises/practice/leap/.meta/example.clj
diff --git a/exercises/practice/list-ops/.meta/config.json b/exercises/practice/list-ops/.meta/config.json
index f1b2c91..1f037f0 100644
--- a/exercises/practice/list-ops/.meta/config.json
+++ b/exercises/practice/list-ops/.meta/config.json
@@ -14,7 +14,7 @@
       "test/list_ops_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Implement basic list operations."
diff --git a/exercises/practice/list-ops/.meta/src/example.clj b/exercises/practice/list-ops/.meta/example.clj
similarity index 100%
rename from exercises/practice/list-ops/.meta/src/example.clj
rename to exercises/practice/list-ops/.meta/example.clj
diff --git a/exercises/practice/list-ops/.meta/src/example_lists.clj b/exercises/practice/list-ops/.meta/extra/example-lists.clj
similarity index 100%
rename from exercises/practice/list-ops/.meta/src/example_lists.clj
rename to exercises/practice/list-ops/.meta/extra/example-lists.clj
diff --git a/exercises/practice/luhn/.meta/config.json b/exercises/practice/luhn/.meta/config.json
index 079a77a..58d7c02 100644
--- a/exercises/practice/luhn/.meta/config.json
+++ b/exercises/practice/luhn/.meta/config.json
@@ -17,7 +17,7 @@
       "test/luhn_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Given a number determine whether or not it is valid per the Luhn formula.",
diff --git a/exercises/practice/luhn/.meta/src/example.clj b/exercises/practice/luhn/.meta/example.clj
similarity index 100%
rename from exercises/practice/luhn/.meta/src/example.clj
rename to exercises/practice/luhn/.meta/example.clj
diff --git a/exercises/practice/matching-brackets/.meta/config.json b/exercises/practice/matching-brackets/.meta/config.json
index c88127a..0dde0a9 100644
--- a/exercises/practice/matching-brackets/.meta/config.json
+++ b/exercises/practice/matching-brackets/.meta/config.json
@@ -16,7 +16,7 @@
       "test/matching_brackets_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Make sure the brackets and braces all match.",
diff --git a/exercises/practice/matching-brackets/.meta/src/example.clj b/exercises/practice/matching-brackets/.meta/example.clj
similarity index 100%
rename from exercises/practice/matching-brackets/.meta/src/example.clj
rename to exercises/practice/matching-brackets/.meta/example.clj
diff --git a/exercises/practice/meetup/.meta/config.json b/exercises/practice/meetup/.meta/config.json
index c21c0b7..b484eed 100644
--- a/exercises/practice/meetup/.meta/config.json
+++ b/exercises/practice/meetup/.meta/config.json
@@ -22,7 +22,7 @@
       "test/meetup_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Calculate the date of meetups.",
diff --git a/exercises/practice/meetup/.meta/src/example.clj b/exercises/practice/meetup/.meta/example.clj
similarity index 100%
rename from exercises/practice/meetup/.meta/src/example.clj
rename to exercises/practice/meetup/.meta/example.clj
diff --git a/exercises/practice/minesweeper/.meta/config.json b/exercises/practice/minesweeper/.meta/config.json
index 0c8d816..2eb2f46 100644
--- a/exercises/practice/minesweeper/.meta/config.json
+++ b/exercises/practice/minesweeper/.meta/config.json
@@ -15,7 +15,7 @@
       "test/minesweeper_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Add the numbers to a minesweeper board."
diff --git a/exercises/practice/minesweeper/.meta/src/example.clj b/exercises/practice/minesweeper/.meta/example.clj
similarity index 100%
rename from exercises/practice/minesweeper/.meta/src/example.clj
rename to exercises/practice/minesweeper/.meta/example.clj
diff --git a/exercises/practice/nth-prime/.meta/config.json b/exercises/practice/nth-prime/.meta/config.json
index 733a84f..0bf9717 100644
--- a/exercises/practice/nth-prime/.meta/config.json
+++ b/exercises/practice/nth-prime/.meta/config.json
@@ -13,7 +13,7 @@
       "test/nth_prime_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Given a number n, determine what the nth prime is.",
diff --git a/exercises/practice/nth-prime/.meta/src/example.clj b/exercises/practice/nth-prime/.meta/example.clj
similarity index 100%
rename from exercises/practice/nth-prime/.meta/src/example.clj
rename to exercises/practice/nth-prime/.meta/example.clj
diff --git a/exercises/practice/nucleotide-count/.meta/config.json b/exercises/practice/nucleotide-count/.meta/config.json
index 95a376c..b3ebe64 100644
--- a/exercises/practice/nucleotide-count/.meta/config.json
+++ b/exercises/practice/nucleotide-count/.meta/config.json
@@ -26,7 +26,7 @@
       "test/nucleotide_count_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Given a DNA string, compute how many times each nucleotide occurs in the string.",
diff --git a/exercises/practice/nucleotide-count/.meta/src/example.clj b/exercises/practice/nucleotide-count/.meta/example.clj
similarity index 100%
rename from exercises/practice/nucleotide-count/.meta/src/example.clj
rename to exercises/practice/nucleotide-count/.meta/example.clj
diff --git a/exercises/practice/octal/.meta/config.json b/exercises/practice/octal/.meta/config.json
index 8849bec..47352f8 100644
--- a/exercises/practice/octal/.meta/config.json
+++ b/exercises/practice/octal/.meta/config.json
@@ -1,22 +1,10 @@
 {
-  "authors": [
-    "haus"
-  ],
-  "contributors": [
-    "AndreaCrotti",
-    "sjwarner-bp",
-    "yurrriq"
-  ],
+  "authors": ["haus"],
+  "contributors": ["AndreaCrotti", "sjwarner-bp", "yurrriq"],
   "files": {
-    "solution": [
-      "src/octal.clj"
-    ],
-    "test": [
-      "test/octal_test.clj"
-    ],
-    "example": [
-      ".meta/src/example.clj"
-    ]
+    "solution": ["src/octal.clj"],
+    "test": ["test/octal_test.clj"],
+    "example": [".meta/example.clj"]
   },
   "blurb": "Convert a octal number, represented as a string (e.g. '1735263'), to its decimal equivalent using first principles (i.e. no, you may not use built-in or external libraries to accomplish the conversion).",
   "source": "All of Computer Science",
diff --git a/exercises/practice/octal/.meta/src/example.clj b/exercises/practice/octal/.meta/example.clj
similarity index 100%
rename from exercises/practice/octal/.meta/src/example.clj
rename to exercises/practice/octal/.meta/example.clj
diff --git a/exercises/practice/pangram/.meta/config.json b/exercises/practice/pangram/.meta/config.json
index ee3c11a..b33b42e 100644
--- a/exercises/practice/pangram/.meta/config.json
+++ b/exercises/practice/pangram/.meta/config.json
@@ -17,7 +17,7 @@
       "test/pangram_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Determine if a sentence is a pangram.",
diff --git a/exercises/practice/pangram/.meta/src/example.clj b/exercises/practice/pangram/.meta/example.clj
similarity index 100%
rename from exercises/practice/pangram/.meta/src/example.clj
rename to exercises/practice/pangram/.meta/example.clj
diff --git a/exercises/practice/pascals-triangle/.meta/config.json b/exercises/practice/pascals-triangle/.meta/config.json
index e0f2690..d7c0081 100644
--- a/exercises/practice/pascals-triangle/.meta/config.json
+++ b/exercises/practice/pascals-triangle/.meta/config.json
@@ -16,7 +16,7 @@
       "test/pascals_triangle_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Compute Pascal's triangle up to a given number of rows.",
diff --git a/exercises/practice/pascals-triangle/.meta/src/example.clj b/exercises/practice/pascals-triangle/.meta/example.clj
similarity index 100%
rename from exercises/practice/pascals-triangle/.meta/src/example.clj
rename to exercises/practice/pascals-triangle/.meta/example.clj
diff --git a/exercises/practice/perfect-numbers/.meta/config.json b/exercises/practice/perfect-numbers/.meta/config.json
index 353bc55..ad9a06d 100644
--- a/exercises/practice/perfect-numbers/.meta/config.json
+++ b/exercises/practice/perfect-numbers/.meta/config.json
@@ -15,7 +15,7 @@
       "test/perfect_numbers_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Determine if a number is perfect, abundant, or deficient based on Nicomachus' (60 - 120 CE) classification scheme for positive integers.",
diff --git a/exercises/practice/perfect-numbers/.meta/src/example.clj b/exercises/practice/perfect-numbers/.meta/example.clj
similarity index 100%
rename from exercises/practice/perfect-numbers/.meta/src/example.clj
rename to exercises/practice/perfect-numbers/.meta/example.clj
diff --git a/exercises/practice/phone-number/.meta/config.json b/exercises/practice/phone-number/.meta/config.json
index 66c1d70..fe363f4 100644
--- a/exercises/practice/phone-number/.meta/config.json
+++ b/exercises/practice/phone-number/.meta/config.json
@@ -23,7 +23,7 @@
       "test/phone_number_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Clean up user-entered phone numbers so that they can be sent SMS messages.",
diff --git a/exercises/practice/phone-number/.meta/src/example.clj b/exercises/practice/phone-number/.meta/example.clj
similarity index 100%
rename from exercises/practice/phone-number/.meta/src/example.clj
rename to exercises/practice/phone-number/.meta/example.clj
diff --git a/exercises/practice/pig-latin/.meta/config.json b/exercises/practice/pig-latin/.meta/config.json
index 2133c3d..4568d4d 100644
--- a/exercises/practice/pig-latin/.meta/config.json
+++ b/exercises/practice/pig-latin/.meta/config.json
@@ -17,7 +17,7 @@
       "test/pig_latin_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Implement a program that translates from English to Pig Latin.",
diff --git a/exercises/practice/pig-latin/.meta/src/example.clj b/exercises/practice/pig-latin/.meta/example.clj
similarity index 100%
rename from exercises/practice/pig-latin/.meta/src/example.clj
rename to exercises/practice/pig-latin/.meta/example.clj
diff --git a/exercises/practice/poker/.meta/config.json b/exercises/practice/poker/.meta/config.json
index dc109d5..e82aaca 100644
--- a/exercises/practice/poker/.meta/config.json
+++ b/exercises/practice/poker/.meta/config.json
@@ -13,7 +13,7 @@
       "test/poker_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Pick the best hand(s) from a list of poker hands.",
diff --git a/exercises/practice/poker/.meta/src/example.clj b/exercises/practice/poker/.meta/example.clj
similarity index 100%
rename from exercises/practice/poker/.meta/src/example.clj
rename to exercises/practice/poker/.meta/example.clj
diff --git a/exercises/practice/pov/.meta/config.json b/exercises/practice/pov/.meta/config.json
index 4246267..3d91141 100644
--- a/exercises/practice/pov/.meta/config.json
+++ b/exercises/practice/pov/.meta/config.json
@@ -18,7 +18,7 @@
       "test/pov_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Reparent a graph on a selected node.",
diff --git a/exercises/practice/pov/.meta/src/example.clj b/exercises/practice/pov/.meta/example.clj
similarity index 100%
rename from exercises/practice/pov/.meta/src/example.clj
rename to exercises/practice/pov/.meta/example.clj
diff --git a/exercises/practice/prime-factors/.meta/config.json b/exercises/practice/prime-factors/.meta/config.json
index b284ab7..3c41783 100644
--- a/exercises/practice/prime-factors/.meta/config.json
+++ b/exercises/practice/prime-factors/.meta/config.json
@@ -20,7 +20,7 @@
       "test/prime_factors_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Compute the prime factors of a given natural number.",
diff --git a/exercises/practice/prime-factors/.meta/src/example.clj b/exercises/practice/prime-factors/.meta/example.clj
similarity index 100%
rename from exercises/practice/prime-factors/.meta/src/example.clj
rename to exercises/practice/prime-factors/.meta/example.clj
diff --git a/exercises/practice/protein-translation/.meta/config.json b/exercises/practice/protein-translation/.meta/config.json
index f3a859d..8368a10 100644
--- a/exercises/practice/protein-translation/.meta/config.json
+++ b/exercises/practice/protein-translation/.meta/config.json
@@ -15,7 +15,7 @@
       "test/protein_translation_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Translate RNA sequences into proteins.",
diff --git a/exercises/practice/protein-translation/.meta/src/example.clj b/exercises/practice/protein-translation/.meta/example.clj
similarity index 100%
rename from exercises/practice/protein-translation/.meta/src/example.clj
rename to exercises/practice/protein-translation/.meta/example.clj
diff --git a/exercises/practice/proverb/.meta/config.json b/exercises/practice/proverb/.meta/config.json
index 65e66b3..a074225 100644
--- a/exercises/practice/proverb/.meta/config.json
+++ b/exercises/practice/proverb/.meta/config.json
@@ -18,7 +18,7 @@
       "test/proverb_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "For want of a horseshoe nail, a kingdom was lost, or so the saying goes. Output the full text of this proverbial rhyme.",
diff --git a/exercises/practice/proverb/.meta/src/example.clj b/exercises/practice/proverb/.meta/example.clj
similarity index 100%
rename from exercises/practice/proverb/.meta/src/example.clj
rename to exercises/practice/proverb/.meta/example.clj
diff --git a/exercises/practice/pythagorean-triplet/.meta/config.json b/exercises/practice/pythagorean-triplet/.meta/config.json
index 3dbb467..d64cb9a 100644
--- a/exercises/practice/pythagorean-triplet/.meta/config.json
+++ b/exercises/practice/pythagorean-triplet/.meta/config.json
@@ -10,7 +10,7 @@
       "test/pythagorean_triplet_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Given an integer N, find all Pythagorean triplets for which a + b + c = N.",
diff --git a/exercises/practice/pythagorean-triplet/.meta/src/example.clj b/exercises/practice/pythagorean-triplet/.meta/example.clj
similarity index 100%
rename from exercises/practice/pythagorean-triplet/.meta/src/example.clj
rename to exercises/practice/pythagorean-triplet/.meta/example.clj
diff --git a/exercises/practice/queen-attack/.meta/config.json b/exercises/practice/queen-attack/.meta/config.json
index 7254c58..a3269e4 100644
--- a/exercises/practice/queen-attack/.meta/config.json
+++ b/exercises/practice/queen-attack/.meta/config.json
@@ -21,7 +21,7 @@
       "test/queen_attack_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Given the position of two queens on a chess board, indicate whether or not they are positioned so that they can attack each other.",
diff --git a/exercises/practice/queen-attack/.meta/src/example.clj b/exercises/practice/queen-attack/.meta/example.clj
similarity index 100%
rename from exercises/practice/queen-attack/.meta/src/example.clj
rename to exercises/practice/queen-attack/.meta/example.clj
diff --git a/exercises/practice/raindrops/.meta/config.json b/exercises/practice/raindrops/.meta/config.json
index cf0ca32..ae25115 100644
--- a/exercises/practice/raindrops/.meta/config.json
+++ b/exercises/practice/raindrops/.meta/config.json
@@ -20,7 +20,7 @@
       "test/raindrops_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Convert a number into its corresponding raindrop sounds - Pling, Plang and Plong.",
diff --git a/exercises/practice/raindrops/.meta/src/example.clj b/exercises/practice/raindrops/.meta/example.clj
similarity index 100%
rename from exercises/practice/raindrops/.meta/src/example.clj
rename to exercises/practice/raindrops/.meta/example.clj
diff --git a/exercises/practice/reverse-string/.meta/config.json b/exercises/practice/reverse-string/.meta/config.json
index 63b57c5..654b25e 100644
--- a/exercises/practice/reverse-string/.meta/config.json
+++ b/exercises/practice/reverse-string/.meta/config.json
@@ -16,7 +16,7 @@
       "test/reverse_string_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Reverse a given string.",
diff --git a/exercises/practice/reverse-string/.meta/src/example.clj b/exercises/practice/reverse-string/.meta/example.clj
similarity index 100%
rename from exercises/practice/reverse-string/.meta/src/example.clj
rename to exercises/practice/reverse-string/.meta/example.clj
diff --git a/exercises/practice/rna-transcription/.meta/config.json b/exercises/practice/rna-transcription/.meta/config.json
index f0bad3b..8526c6a 100644
--- a/exercises/practice/rna-transcription/.meta/config.json
+++ b/exercises/practice/rna-transcription/.meta/config.json
@@ -29,7 +29,7 @@
       "test/rna_transcription_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Given a DNA strand, return its RNA Complement Transcription.",
diff --git a/exercises/practice/rna-transcription/.meta/src/example.clj b/exercises/practice/rna-transcription/.meta/example.clj
similarity index 100%
rename from exercises/practice/rna-transcription/.meta/src/example.clj
rename to exercises/practice/rna-transcription/.meta/example.clj
diff --git a/exercises/practice/robot-name/.meta/config.json b/exercises/practice/robot-name/.meta/config.json
index 3b039aa..aa69036 100644
--- a/exercises/practice/robot-name/.meta/config.json
+++ b/exercises/practice/robot-name/.meta/config.json
@@ -23,7 +23,7 @@
       "test/robot_name_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Manage robot factory settings.",
diff --git a/exercises/practice/robot-name/.meta/src/example.clj b/exercises/practice/robot-name/.meta/example.clj
similarity index 100%
rename from exercises/practice/robot-name/.meta/src/example.clj
rename to exercises/practice/robot-name/.meta/example.clj
diff --git a/exercises/practice/robot-simulator/.meta/config.json b/exercises/practice/robot-simulator/.meta/config.json
index 21cc58a..a70170f 100644
--- a/exercises/practice/robot-simulator/.meta/config.json
+++ b/exercises/practice/robot-simulator/.meta/config.json
@@ -21,7 +21,7 @@
       "test/robot_simulator_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Write a robot simulator.",
diff --git a/exercises/practice/robot-simulator/.meta/src/example.clj b/exercises/practice/robot-simulator/.meta/example.clj
similarity index 100%
rename from exercises/practice/robot-simulator/.meta/src/example.clj
rename to exercises/practice/robot-simulator/.meta/example.clj
diff --git a/exercises/practice/roman-numerals/.meta/config.json b/exercises/practice/roman-numerals/.meta/config.json
index ebaf454..d5be610 100644
--- a/exercises/practice/roman-numerals/.meta/config.json
+++ b/exercises/practice/roman-numerals/.meta/config.json
@@ -21,7 +21,7 @@
       "test/roman_numerals_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Convert modern Arabic numbers into Roman numerals.",
diff --git a/exercises/practice/roman-numerals/.meta/src/example.clj b/exercises/practice/roman-numerals/.meta/example.clj
similarity index 100%
rename from exercises/practice/roman-numerals/.meta/src/example.clj
rename to exercises/practice/roman-numerals/.meta/example.clj
diff --git a/exercises/practice/rotational-cipher/.meta/config.json b/exercises/practice/rotational-cipher/.meta/config.json
index 481713e..92522ff 100644
--- a/exercises/practice/rotational-cipher/.meta/config.json
+++ b/exercises/practice/rotational-cipher/.meta/config.json
@@ -17,7 +17,7 @@
       "test/rotational_cipher_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Create an implementation of the rotational cipher, also sometimes called the Caesar cipher.",
diff --git a/exercises/practice/rotational-cipher/.meta/src/example.clj b/exercises/practice/rotational-cipher/.meta/example.clj
similarity index 100%
rename from exercises/practice/rotational-cipher/.meta/src/example.clj
rename to exercises/practice/rotational-cipher/.meta/example.clj
diff --git a/exercises/practice/run-length-encoding/.meta/config.json b/exercises/practice/run-length-encoding/.meta/config.json
index 2c05eb2..3de64ff 100644
--- a/exercises/practice/run-length-encoding/.meta/config.json
+++ b/exercises/practice/run-length-encoding/.meta/config.json
@@ -15,7 +15,7 @@
       "test/run_length_encoding_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Implement run-length encoding and decoding.",
diff --git a/exercises/practice/run-length-encoding/.meta/src/example.clj b/exercises/practice/run-length-encoding/.meta/example.clj
similarity index 100%
rename from exercises/practice/run-length-encoding/.meta/src/example.clj
rename to exercises/practice/run-length-encoding/.meta/example.clj
diff --git a/exercises/practice/say/.meta/config.json b/exercises/practice/say/.meta/config.json
index 8d73c8c..0d9271a 100644
--- a/exercises/practice/say/.meta/config.json
+++ b/exercises/practice/say/.meta/config.json
@@ -15,7 +15,7 @@
       "test/say_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Given a number from 0 to 999,999,999,999, spell out that number in English.",
diff --git a/exercises/practice/say/.meta/src/example.clj b/exercises/practice/say/.meta/example.clj
similarity index 100%
rename from exercises/practice/say/.meta/src/example.clj
rename to exercises/practice/say/.meta/example.clj
diff --git a/exercises/practice/scrabble-score/.meta/config.json b/exercises/practice/scrabble-score/.meta/config.json
index 99ff2f8..e33ef38 100644
--- a/exercises/practice/scrabble-score/.meta/config.json
+++ b/exercises/practice/scrabble-score/.meta/config.json
@@ -23,7 +23,7 @@
       "test/scrabble_score_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Given a word, compute the Scrabble score for that word.",
diff --git a/exercises/practice/scrabble-score/.meta/src/example.clj b/exercises/practice/scrabble-score/.meta/example.clj
similarity index 100%
rename from exercises/practice/scrabble-score/.meta/src/example.clj
rename to exercises/practice/scrabble-score/.meta/example.clj
diff --git a/exercises/practice/secret-handshake/.meta/config.json b/exercises/practice/secret-handshake/.meta/config.json
index db8f4dd..ff142d7 100644
--- a/exercises/practice/secret-handshake/.meta/config.json
+++ b/exercises/practice/secret-handshake/.meta/config.json
@@ -13,7 +13,7 @@
       "test/secret_handshake_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Given a decimal number, convert it to the appropriate sequence of events for a secret handshake.",
diff --git a/exercises/practice/secret-handshake/.meta/src/example.clj b/exercises/practice/secret-handshake/.meta/example.clj
similarity index 100%
rename from exercises/practice/secret-handshake/.meta/src/example.clj
rename to exercises/practice/secret-handshake/.meta/example.clj
diff --git a/exercises/practice/series/.meta/config.json b/exercises/practice/series/.meta/config.json
index c17ab83..bb5a5e5 100644
--- a/exercises/practice/series/.meta/config.json
+++ b/exercises/practice/series/.meta/config.json
@@ -13,7 +13,7 @@
       "test/series_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Given a string of digits, output all the contiguous substrings of length `n` in that string.",
diff --git a/exercises/practice/series/.meta/src/example.clj b/exercises/practice/series/.meta/example.clj
similarity index 100%
rename from exercises/practice/series/.meta/src/example.clj
rename to exercises/practice/series/.meta/example.clj
diff --git a/exercises/practice/sieve/.meta/config.json b/exercises/practice/sieve/.meta/config.json
index 2a4ce8c..f6679c0 100644
--- a/exercises/practice/sieve/.meta/config.json
+++ b/exercises/practice/sieve/.meta/config.json
@@ -17,7 +17,7 @@
       "test/sieve_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Use the Sieve of Eratosthenes to find all the primes from 2 up to a given number.",
diff --git a/exercises/practice/sieve/.meta/src/example.clj b/exercises/practice/sieve/.meta/example.clj
similarity index 100%
rename from exercises/practice/sieve/.meta/src/example.clj
rename to exercises/practice/sieve/.meta/example.clj
diff --git a/exercises/practice/space-age/.meta/config.json b/exercises/practice/space-age/.meta/config.json
index 7294c9c..f50fd98 100644
--- a/exercises/practice/space-age/.meta/config.json
+++ b/exercises/practice/space-age/.meta/config.json
@@ -21,7 +21,7 @@
       "test/space_age_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Given an age in seconds, calculate how old someone is in terms of a given planet's solar years.",
diff --git a/exercises/practice/space-age/.meta/src/example.clj b/exercises/practice/space-age/.meta/example.clj
similarity index 100%
rename from exercises/practice/space-age/.meta/src/example.clj
rename to exercises/practice/space-age/.meta/example.clj
diff --git a/exercises/practice/spiral-matrix/.meta/config.json b/exercises/practice/spiral-matrix/.meta/config.json
index a8a87e2..6bd7fee 100644
--- a/exercises/practice/spiral-matrix/.meta/config.json
+++ b/exercises/practice/spiral-matrix/.meta/config.json
@@ -14,7 +14,7 @@
       "test/spiral_matrix_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Given the size, return a square matrix of numbers in spiral order.",
diff --git a/exercises/practice/spiral-matrix/.meta/src/example.clj b/exercises/practice/spiral-matrix/.meta/example.clj
similarity index 100%
rename from exercises/practice/spiral-matrix/.meta/src/example.clj
rename to exercises/practice/spiral-matrix/.meta/example.clj
diff --git a/exercises/practice/strain/.meta/config.json b/exercises/practice/strain/.meta/config.json
index 137f7b8..725fad8 100644
--- a/exercises/practice/strain/.meta/config.json
+++ b/exercises/practice/strain/.meta/config.json
@@ -15,7 +15,7 @@
       "test/strain_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Implement the `keep` and `discard` operation on collections.",
diff --git a/exercises/practice/strain/.meta/src/example.clj b/exercises/practice/strain/.meta/example.clj
similarity index 100%
rename from exercises/practice/strain/.meta/src/example.clj
rename to exercises/practice/strain/.meta/example.clj
diff --git a/exercises/practice/sublist/.meta/config.json b/exercises/practice/sublist/.meta/config.json
index 9d58c09..4d8ad2d 100644
--- a/exercises/practice/sublist/.meta/config.json
+++ b/exercises/practice/sublist/.meta/config.json
@@ -16,7 +16,7 @@
       "test/sublist_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Write a function to determine if a list is a sublist of another list."
diff --git a/exercises/practice/sublist/.meta/src/example.clj b/exercises/practice/sublist/.meta/example.clj
similarity index 100%
rename from exercises/practice/sublist/.meta/src/example.clj
rename to exercises/practice/sublist/.meta/example.clj
diff --git a/exercises/practice/sum-of-multiples/.meta/config.json b/exercises/practice/sum-of-multiples/.meta/config.json
index 818d25d..52ce35c 100644
--- a/exercises/practice/sum-of-multiples/.meta/config.json
+++ b/exercises/practice/sum-of-multiples/.meta/config.json
@@ -16,7 +16,7 @@
       "test/sum_of_multiples_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Given a number, find the sum of all the multiples of particular numbers up to but not including that number.",
diff --git a/exercises/practice/sum-of-multiples/.meta/src/example.clj b/exercises/practice/sum-of-multiples/.meta/example.clj
similarity index 100%
rename from exercises/practice/sum-of-multiples/.meta/src/example.clj
rename to exercises/practice/sum-of-multiples/.meta/example.clj
diff --git a/exercises/practice/triangle/.meta/config.json b/exercises/practice/triangle/.meta/config.json
index 9764dd5..c9262ab 100644
--- a/exercises/practice/triangle/.meta/config.json
+++ b/exercises/practice/triangle/.meta/config.json
@@ -24,7 +24,7 @@
       "test/triangle_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Determine if a triangle is equilateral, isosceles, or scalene.",
diff --git a/exercises/practice/triangle/.meta/src/example.clj b/exercises/practice/triangle/.meta/example.clj
similarity index 100%
rename from exercises/practice/triangle/.meta/src/example.clj
rename to exercises/practice/triangle/.meta/example.clj
diff --git a/exercises/practice/trinary/.meta/config.json b/exercises/practice/trinary/.meta/config.json
index cdc689a..29e5727 100644
--- a/exercises/practice/trinary/.meta/config.json
+++ b/exercises/practice/trinary/.meta/config.json
@@ -1,22 +1,10 @@
 {
-  "authors": [
-    "yurrriq"
-  ],
-  "contributors": [
-    "AndreaCrotti",
-    "haus",
-    "sjwarner-bp"
-  ],
+  "authors": ["yurrriq"],
+  "contributors": ["AndreaCrotti", "haus", "sjwarner-bp"],
   "files": {
-    "solution": [
-      "src/trinary.clj"
-    ],
-    "test": [
-      "test/trinary_test.clj"
-    ],
-    "example": [
-      ".meta/src/example.clj"
-    ]
+    "solution": ["src/trinary.clj"],
+    "test": ["test/trinary_test.clj"],
+    "example": [".meta/example.clj"]
   },
   "blurb": "Convert a trinary number, represented as a string (e.g. '102012'), to its decimal equivalent using first principles.",
   "source": "All of Computer Science",
diff --git a/exercises/practice/trinary/.meta/src/example.clj b/exercises/practice/trinary/.meta/example.clj
similarity index 100%
rename from exercises/practice/trinary/.meta/src/example.clj
rename to exercises/practice/trinary/.meta/example.clj
diff --git a/exercises/practice/two-fer/.meta/config.json b/exercises/practice/two-fer/.meta/config.json
index 8110c51..f04561c 100644
--- a/exercises/practice/two-fer/.meta/config.json
+++ b/exercises/practice/two-fer/.meta/config.json
@@ -15,7 +15,7 @@
       "test/two_fer_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Create a sentence of the form \"One for X, one for me.\".",
diff --git a/exercises/practice/two-fer/.meta/src/example.clj b/exercises/practice/two-fer/.meta/example.clj
similarity index 100%
rename from exercises/practice/two-fer/.meta/src/example.clj
rename to exercises/practice/two-fer/.meta/example.clj
diff --git a/exercises/practice/word-count/.meta/config.json b/exercises/practice/word-count/.meta/config.json
index 2854226..77061f1 100644
--- a/exercises/practice/word-count/.meta/config.json
+++ b/exercises/practice/word-count/.meta/config.json
@@ -26,7 +26,7 @@
       "test/word_count_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Given a phrase, count the occurrences of each word in that phrase.",
diff --git a/exercises/practice/word-count/.meta/src/example.clj b/exercises/practice/word-count/.meta/example.clj
similarity index 100%
rename from exercises/practice/word-count/.meta/src/example.clj
rename to exercises/practice/word-count/.meta/example.clj
diff --git a/exercises/practice/wordy/.meta/config.json b/exercises/practice/wordy/.meta/config.json
index 734b4d3..972ea28 100644
--- a/exercises/practice/wordy/.meta/config.json
+++ b/exercises/practice/wordy/.meta/config.json
@@ -16,7 +16,7 @@
       "test/wordy_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Parse and evaluate simple math word problems returning the answer as an integer.",
diff --git a/exercises/practice/wordy/.meta/src/example.clj b/exercises/practice/wordy/.meta/example.clj
similarity index 100%
rename from exercises/practice/wordy/.meta/src/example.clj
rename to exercises/practice/wordy/.meta/example.clj
diff --git a/exercises/practice/yacht/.meta/config.json b/exercises/practice/yacht/.meta/config.json
index c6ff390..22f050b 100644
--- a/exercises/practice/yacht/.meta/config.json
+++ b/exercises/practice/yacht/.meta/config.json
@@ -10,7 +10,7 @@
       "test/yacht_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Score a single throw of dice in the game Yacht.",
diff --git a/exercises/practice/yacht/.meta/src/example.clj b/exercises/practice/yacht/.meta/example.clj
similarity index 100%
rename from exercises/practice/yacht/.meta/src/example.clj
rename to exercises/practice/yacht/.meta/example.clj
diff --git a/exercises/practice/zipper/.meta/config.json b/exercises/practice/zipper/.meta/config.json
index 9a534de..e1509ef 100644
--- a/exercises/practice/zipper/.meta/config.json
+++ b/exercises/practice/zipper/.meta/config.json
@@ -10,7 +10,7 @@
       "test/zipper_test.clj"
     ],
     "example": [
-      ".meta/src/example.clj"
+      ".meta/example.clj"
     ]
   },
   "blurb": "Creating a zipper for a binary tree."


Test patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index c3247bc..c3866db 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -14,26 +14,26 @@ jobs:
     runs-on: ubuntu-22.04
     steps:
       - name: Checkout
-        uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b
+        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
         with:
           path: main
-          
+
       - name: Checkout test runner
-        uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b
+        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
         with:
           repository: exercism/clojure-test-runner
           path: clojure-test-runner
 
       - name: setup babashka
-        uses: turtlequeue/setup-babashka@2d4df498c7a578b4f3e906283f9af913590bdec7
+        uses: turtlequeue/setup-babashka@fda33428c8b62fb5bb9802ca7a2c750a6cc11b5a
         with:
           babashka-version: 0.8.1
-          
+
       - name: babashka script
         id: bb_script
         run: bb main/test.clj
-          
+
       # Print the output of the babashka script from the
-      # `bb_script` step 
+      # `bb_script` step
       - name: Get the script output
         run: echo "${{ steps.bb_script.outputs.bb_out }}"
diff --git a/_test/check_exercises.clj b/_test/check_exercises.clj
index 3355536..cb38ae2 100644
--- a/_test/check_exercises.clj
+++ b/_test/check_exercises.clj
@@ -10,6 +10,6 @@
           :let [slug             (exercise "slug")
                 path-to-exercise (partial str "exercises/practice/" slug "/")
                 exercise-tests   (symbol (str slug "-test"))]]
-    (load-file (path-to-exercise ".meta/src/example.clj"))
+    (load-file (path-to-exercise ".meta/example.clj"))
     (load-file (path-to-exercise "test/" (->snake_case slug) "_test.clj"))
     (is (successful? (run-tests exercise-tests)))))
diff --git a/exercises/practice/zipper/.meta/src/example.clj b/exercises/practice/zipper/.meta/example.clj
similarity index 100%
rename from exercises/practice/zipper/.meta/src/example.clj
rename to exercises/practice/zipper/.meta/example.clj
diff --git a/test.clj b/test.clj
index e924bfe..8b30fd7 100755
--- a/test.clj
+++ b/test.clj
@@ -33,7 +33,7 @@
         type (if practice? "practice" "concept")
         dir (str root "exercises/" type "/" slug "/")
         example (if practice?
-                  (str dir ".meta/src/example.clj")
+                  (str dir ".meta/example.clj")
                   (str dir ".meta/exemplar.clj"))
         src (str dir "src/" (->snake_case slug) ".clj")]
     (shell/sh "cp" example src)
@@ -45,8 +45,10 @@
                "status"))))
 
 (defn test-exercises! []
-  (for [exercise (into practice-exercises concept-exercises)]
-    {(keyword exercise) (test-exercise exercise)}))
+  (let [exercises (or (seq (take 1 *command-line-args*))
+                      (into practice-exercises concept-exercises))]
+    (for [exercise exercises]
+      {(keyword exercise) (test-exercise exercise)})))
 
 (let [results (test-exercises!)
       fails (filter #(false? (first (vals %))) results)]