Repository: exercism/clojure
Pull request #219 (2018-04-17 22:15:50)

add dominoes


Patch:
diff --git a/config.json b/config.json
index eab68af..36e9d83 100644
--- a/config.json
+++ b/config.json
@@ -597,6 +597,14 @@
       "topics": null,
       "unlocked_by": null,
       "uuid": "7df7ff1c-74ab-4f4e-aaf0-257b6e1cbc18"
+    },
+    {
+      "core": false,
+      "difficulty": 1,
+      "slug": "dominoes",
+      "topics": null,
+      "unlocked_by": null,
+      "uuid": "db6162c0-adff-401e-9dd6-a0322ca10dcf"
     }
   ],
   "foregone": [],
diff --git a/exercises/dominoes/README.md b/exercises/dominoes/README.md
new file mode 100644
index 0000000..0d7c2b2
--- /dev/null
+++ b/exercises/dominoes/README.md
@@ -0,0 +1,16 @@
+Make a chain of dominoes.
+
+Compute a way to order a given set of dominoes in such a way that they form a
+correct domino chain (the dots on one half of a stone match the dots on the
+neighbouring half of an adjacent stone) and that dots on the halfs of the stones
+which don't have a neighbour (the first and last stone) match each other.
+
+For example given the stones `[2|1]`, `[2|3]` and `[1|3]` you should compute something
+like `[1|2] [2|3] [3|1]` or `[3|2] [2|1] [1|3]` or `[1|3] [3|2] [2|1]` etc, where the first and last numbers are the same.
+
+For stones `[1|2]`, `[4|1]` and `[2|3]` the resulting chain is not valid: `[4|1] [1|2] [2|3]`'s first and last numbers are not the same. 4 != 3
+
+Some test cases may use duplicate stones in a chain solution, assume that multiple Domino sets are being used.
+
+## Submitting Incomplete Solutions
+It's possible to submit an incomplete solution so you can see how others have completed the exercise.
diff --git a/exercises/dominoes/project.clj b/exercises/dominoes/project.clj
new file mode 100644
index 0000000..3012303
--- /dev/null
+++ b/exercises/dominoes/project.clj
@@ -0,0 +1,4 @@
+(defproject dominoes "0.1.0-SNAPSHOT"
+  :description "dominoes exercise."
+  :url "https://github.com/exercism/clojure/tree/master/exercises/dominoes"
+  :dependencies [[org.clojure/clojure "1.9.0"]])
diff --git a/exercises/dominoes/src/dominoes.clj b/exercises/dominoes/src/dominoes.clj
new file mode 100644
index 0000000..b4162f9
--- /dev/null
+++ b/exercises/dominoes/src/dominoes.clj
@@ -0,0 +1,3 @@
+(ns dominoes)
+
+(defn can-chain? [])
diff --git a/exercises/dominoes/src/example.clj b/exercises/dominoes/src/example.clj
new file mode 100644
index 0000000..d62ac5a
--- /dev/null
+++ b/exercises/dominoes/src/example.clj
@@ -0,0 +1,20 @@
+(ns dominoes)
+
+(defn rm [xs x]
+  (let [i (.indexOf xs x)]
+    (if (= -1 i) xs (vec (concat (take i xs) (drop (inc i) xs))))))
+
+(defn connects [[a b] [c d]]
+  (cond (= b c) [c d]
+        (= b d) [d c]
+        :else   nil))
+
+(defn backtrack [rem chain]
+  (or (and (empty? rem) (= (ffirst chain) (second (peek chain))))
+      (and (not (empty? rem))
+           (some #(let [c (connects (peek chain) %)]
+                    (and c (backtrack (rm rem %) (conj chain c))))
+                 rem))))
+
+(defn can-chain? [xs]
+  (or (empty? xs) (some #(backtrack (rm xs %) [%]) xs)))


Test patch:
diff --git a/exercises/dominoes/test/dominoes_test.clj b/exercises/dominoes/test/dominoes_test.clj
new file mode 100644
index 0000000..bb1b2ef
--- /dev/null
+++ b/exercises/dominoes/test/dominoes_test.clj
@@ -0,0 +1,39 @@
+(ns dominoes-test
+  (:require [clojure.test :refer [deftest is]]
+            [dominoes     :refer [can-chain?]]))
+
+(deftest empty-input-empty-output
+  (is (can-chain? [])))
+
+(deftest singleton-input-singleton-output
+  (is (can-chain? [[1 1]])))
+
+(deftest singleton-that-cant-be-chained
+  (is ((comp not can-chain?) [[1 2]])))
+
+(deftest three-elements
+  (is (can-chain?  [[1 2] [3 1] [2 3]])))
+
+(deftest can-reverse-dominoes
+  (is (can-chain? [[1 2] [1 3] [2 3]])))
+
+(deftest cant-be-chained
+  (is ((comp not can-chain?) [[1 2] [4 1] [2 3]])))
+
+(deftest disconnected-simple
+  (is ((comp not can-chain?) [[1 1] [2 2]])))
+
+(deftest disconnected-double-loop
+  (is ((comp not can-chain?) [[1 2] [2 1] [3 4] [4 3]])))
+
+(deftest disconnected-single-isolated
+  (is ((comp not can-chain?) [[1 2] [2 3] [3 1] [4 4]])))
+
+(deftest need-backtrack
+  (is (can-chain? [[1 2] [2 3] [3 1] [2 4] [2 4]])))
+
+(deftest separate-loops
+  (is (can-chain? [[1 2] [2 3] [3 1] [1 1] [2 2] [3 3]])))
+
+(deftest nine-elements
+  (is (can-chain? [[1 2] [5 3] [3 1] [1 2] [2 4] [1 6] [2 3] [3 4] [5 6]])))