Repository: exercism/clojure
Pull request #534 (2023-03-06 22:38:05)

Add Yacht exercise


Patch:
diff --git a/config.json b/config.json
index 22e3e9e..1ba1835 100644
--- a/config.json
+++ b/config.json
@@ -990,6 +990,17 @@
         "topics": [
           "conditionals"
         ]
+      },
+      {
+        "slug": "yacht",
+        "name": "Yacht",
+        "uuid": "459c8468-efc4-46a6-bbc0-9937167827a7",
+        "practices": [],
+        "prerequisites": ["strings", "vectors"],
+        "difficulty": 5,
+        "topics": [
+          "conditionals"
+        ]
       }
     ]
   },
diff --git a/exercises/practice/yacht/.docs/instructions.md b/exercises/practice/yacht/.docs/instructions.md
new file mode 100644
index 0000000..d6e119e
--- /dev/null
+++ b/exercises/practice/yacht/.docs/instructions.md
@@ -0,0 +1,35 @@
+# Description
+
+The dice game [Yacht][yacht] is from the same family as Poker Dice, Generala and particularly Yahtzee, of which it is a precursor.
+In the game, five dice are rolled and the result can be entered in any of twelve categories.
+The score of a throw of the dice depends on category chosen.
+
+## Scores in Yacht
+
+| Category | Score | Description | Example |
+| -------- | ----- | ----------- | ------- |
+| Ones | 1 × number of ones | Any combination | 1 1 1 4 5 scores 3 |
+| Twos | 2 × number of twos | Any combination | 2 2 3 4 5 scores 4 |
+| Threes | 3 × number of threes | Any combination | 3 3 3 3 3 scores 15 |
+| Fours | 4 × number of fours | Any combination | 1 2 3 3 5 scores 0 |
+| Fives | 5 × number of fives| Any combination | 5 1 5 2 5 scores 15 |
+| Sixes | 6 × number of sixes | Any combination | 2 3 4 5 6 scores 6 |
+| Full House | Total of the dice | Three of one number and two of another | 3 3 3 5 5 scores 19 |
+| Four of a Kind | Total of the four dice | At least four dice showing the same face | 4 4 4 4 6 scores 16 |
+| Little Straight |  30 points | 1-2-3-4-5 | 1 2 3 4 5 scores 30 |
+| Big Straight | 30 points | 2-3-4-5-6 | 2 3 4 5 6 scores 30 |
+| Choice | Sum of the dice | Any combination | 2 3 3 4 6 scores 18 |
+| Yacht | 50 points | All five dice showing the same face | 4 4 4 4 4 scores 50 |
+
+If the dice do not satisfy the requirements of a category, the score is zero.
+If, for example, *Four Of A Kind* is entered in the *Yacht* category, zero points are scored.
+A *Yacht* scores zero if entered in the *Full House* category.
+
+## Task
+
+Given a list of values for five dice and a category, your solution should return the score of the dice for that category.
+If the dice do not satisfy the requirements of the category your solution should return 0.
+You can assume that five values will always be presented, and the value of each will be between one and six inclusively.
+You should not assume that the dice are ordered.
+
+[yacht]: https://en.wikipedia.org/wiki/Yacht_(dice_game)
diff --git a/exercises/practice/yacht/.meta/config.json b/exercises/practice/yacht/.meta/config.json
new file mode 100644
index 0000000..85a212a
--- /dev/null
+++ b/exercises/practice/yacht/.meta/config.json
@@ -0,0 +1,21 @@
+{
+    "authors": [
+      "porkostomus"
+    ],
+    "contributors": [],
+    "files": {
+      "solution": [
+        "src/yacht.clj"
+      ],
+      "test": [
+        "test/yacht_test.clj"
+      ],
+      "example": [
+        ".meta/src/example.clj"
+      ]
+    },
+    "blurb": "Score a single throw of dice in the game Yacht",
+    "source": "James Kilfiger, using wikipedia",
+    "source_url": "https://en.wikipedia.org/wiki/Yacht_(dice_game)"
+  }
+  
\ No newline at end of file
diff --git a/exercises/practice/yacht/.meta/src/example.clj b/exercises/practice/yacht/.meta/src/example.clj
new file mode 100644
index 0000000..c4c1f5c
--- /dev/null
+++ b/exercises/practice/yacht/.meta/src/example.clj
@@ -0,0 +1,51 @@
+(ns yacht)
+
+(defn yacht [dices]
+  (if (= (count (set dices)) 1) 50 0))
+
+(defn dice-frequencies [dices]
+  (mapv #(if (nil? %) 0 %)
+        (map (fn [v] (get (frequencies dices) v))
+             (range 1 7))))
+
+(defn appearances [dices diceValue]
+  (get (dice-frequencies dices) (dec diceValue)))
+
+(defn getSumOfDices [dices]
+  (reduce + 0 dices))
+
+(defn four-of-kind [dices]
+  (let [counterArray (dice-frequencies dices)
+        scores (remove nil? (for [i (range 6)]
+                              (when (>= (get counterArray i) 4)
+                                (* 4 (inc i)))))]
+    (if (empty? scores) 0 (first scores))))
+
+(defn little-straight [dices]
+  (if (= (sort dices) [1 2 3 4 5]) 30 0))
+
+(defn big-straight [dices]
+  (if (= (sort dices) [2 3 4 5 6]) 30 0))
+
+(defn full-house [dices]
+  (let [counterArray (dice-frequencies dices)]
+    (if (and (contains? (set counterArray) 2)
+             (contains? (set counterArray) 3))
+      (reduce + dices)
+      0)))
+
+(defn score [dices category]
+  (case category
+    "yacht" (yacht dices)
+    "ones" (appearances dices 1)
+    "twos" (* 2 (appearances dices 2))
+    "threes" (* 3 (appearances dices 3))
+    "fours" (* 4 (appearances dices 4))
+    "fives" (* 5 (appearances dices 5))
+    "sixes" (* 6 (appearances dices 6))
+    "full house" (full-house dices)
+    "four of a kind" (four-of-kind dices)
+    "little straight" (little-straight dices)
+    "big straight" (big-straight dices)
+    "choice" (getSumOfDices dices)
+    0))
diff --git a/exercises/practice/yacht/deps.edn b/exercises/practice/yacht/deps.edn
new file mode 100644
index 0000000..561c3e2
--- /dev/null
+++ b/exercises/practice/yacht/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/yacht/project.clj b/exercises/practice/yacht/project.clj
new file mode 100644
index 0000000..12fc797
--- /dev/null
+++ b/exercises/practice/yacht/project.clj
@@ -0,0 +1,4 @@
+(defproject yacht "0.1.0-SNAPSHOT"
+  :description "yacht exercise."
+  :url "https://github.com/exercism/clojure/tree/master/exercises/yacht"
+  :dependencies [[org.clojure/clojure "1.10.0"]])
diff --git a/exercises/practice/yacht/src/yacht.clj b/exercises/practice/yacht/src/yacht.clj
new file mode 100644
index 0000000..ac872e9
--- /dev/null
+++ b/exercises/practice/yacht/src/yacht.clj
@@ -0,0 +1,4 @@
+(ns yacht)
+
+(defn score []
+  )


Test patch:
diff --git a/exercises/practice/yacht/test/yacht_test.clj b/exercises/practice/yacht/test/yacht_test.clj
new file mode 100644
index 0000000..76652bd
--- /dev/null
+++ b/exercises/practice/yacht/test/yacht_test.clj
@@ -0,0 +1,67 @@
+(ns yacht-test
+  (:require [clojure.test :refer [deftest testing is run-tests]]
+             yacht))
+
+(deftest score-test
+  (testing "Yacht"
+     (is (= 50 (yacht/score [5 5 5 5 5] "yacht"))))
+  (testing "Not Yacht"
+     (is (= 0 (yacht/score [1 3 3 2 5] "yacht"))))
+  (testing "Ones"
+     (is (= 3 (yacht/score [1 1 1 3 5] "ones"))))
+  (testing "Ones, out of order"
+     (is (= 3 (yacht/score [3 1 1 5 1] "ones"))))
+  (testing "No ones"
+     (is (= 0 (yacht/score [4 3 6 5 5] "ones"))))
+  (testing "Twos"
+     (is (= 2 (yacht/score [2 3 4 5 6] "twos"))))
+  (testing "Fours"
+     (is (= 8 (yacht/score [1 4 1 4 1] "fours"))))
+  (testing "Yacht counted as threes"
+     (is (= 15 (yacht/score [3 3 3 3 3] "threes"))))
+  (testing "Yacht of 3s counted as fives"
+     (is (= 0 (yacht/score [3 3 3 3 3] "fives"))))
+  (testing "Fives"
+     (is (= 10 (yacht/score [1 5 3 5 3] "fives"))))
+  (testing "Sixes"
+     (is (= 6 (yacht/score [2 3 4 5 6] "sixes"))))
+  (testing "Full house two small, three big"
+     (is (= 16 (yacht/score [2 2 4 4 4] "full house"))))
+  (testing "Full house three small, two big"
+     (is (= 19 (yacht/score [5 3 3 5 3] "full house"))))
+  (testing "Two pair is not a full house"
+     (is (= 0 (yacht/score [2 2 4 4 5] "full house"))))
+  (testing "Four of a kind is not a full house"
+     (is (= 0 (yacht/score [1 4 4 4 4] "full house"))))
+  (testing "Yacht is not a full house"
+     (is (= 0 (yacht/score [2 2 2 2 2] "full house"))))
+  (testing "Four of a Kind"
+     (is (= 24 (yacht/score [6 6 4 6 6] "four of a kind"))))
+  (testing "Yacht can be scored as Four of a Kind"
+     (is (= 12 (yacht/score [3 3 3 3 3] "four of a kind"))))
+  (testing "Full house is not Four of a Kind"
+     (is (= 0 (yacht/score [3 3 3 5 5] "four of a kind"))))
+  (testing "Little Straight"
+     (is (= 30 (yacht/score [3 5 4 1 2] "little straight"))))
+  (testing "Little Straight as Big Straight"
+     (is (= 0 (yacht/score [1 2 3 4 5] "big straight"))))
+  (testing "Four in order but not a little straight"
+     (is (= 0 (yacht/score [1 1 2 3 4] "little straight"))))
+  (testing "No pairs but not a little straight"
+     (is (= 0 (yacht/score [1 2 3 4 6] "little straight"))))
+  (testing "Minimum is 1, maximum is 5, but not a little straight"
+     (is (= 0 (yacht/score [1 1 3 4 5] "little straight"))))
+  (testing "Big Straight"
+     (is (= 30 (yacht/score [4 6 2 5 3] "big straight"))))
+  (testing "Big Straight as little straight"
+     (is (= 0 (yacht/score [6 5 4 3 2] "little straight"))))
+  (testing "No pairs but not a big straight"
+     (is (= 0 (yacht/score [6 5 4 3 1] "big straight"))))
+  (testing "Choice"
+     (is (= 23 (yacht/score [3 3 5 6 6] "choice"))))
+  (testing "Yacht as choice"
+     (is (= 10 (yacht/score [2 2 2 2 2] "choice")))))
+
+(comment
+  (run-tests)
+  )
\ No newline at end of file