From 21143512ce0463b34d01debb417b20b116032805 Mon Sep 17 00:00:00 2001
From: Erik Schierboom <erik_schierboom@hotmail.com>
Date: Sat, 7 Dec 2024 21:32:26 +0100
Subject: [PATCH] Add `word-search` exercise

---
 config.json                                   |   8 +
 .../word-search/.docs/instructions.md         |  24 ++
 .../practice/word-search/.meta/config.json    |  17 ++
 .../practice/word-search/.meta/example.ua     |  24 ++
 .../practice/word-search/.meta/tests.toml     |  82 ++++++
 exercises/practice/word-search/tests.ua       | 264 ++++++++++++++++++
 exercises/practice/word-search/word-search.ua |   3 +
 7 files changed, 422 insertions(+)
 create mode 100644 exercises/practice/word-search/.docs/instructions.md
 create mode 100644 exercises/practice/word-search/.meta/config.json
 create mode 100644 exercises/practice/word-search/.meta/example.ua
 create mode 100644 exercises/practice/word-search/.meta/tests.toml
 create mode 100644 exercises/practice/word-search/tests.ua
 create mode 100644 exercises/practice/word-search/word-search.ua

diff --git a/config.json b/config.json
index e86a11d..e350b81 100644
--- a/config.json
+++ b/config.json
@@ -570,6 +570,14 @@
         "prerequisites": [],
         "difficulty": 6
       },
+      {
+        "slug": "word-search",
+        "name": "Word Search",
+        "uuid": "58ffd8d4-1d81-423f-9a06-df1806e8c48a",
+        "practices": [],
+        "prerequisites": [],
+        "difficulty": 6
+      },
       {
         "slug": "knapsack",
         "name": "Knapsack",
diff --git a/exercises/practice/word-search/.docs/instructions.md b/exercises/practice/word-search/.docs/instructions.md
new file mode 100644
index 0000000..e2d08aa
--- /dev/null
+++ b/exercises/practice/word-search/.docs/instructions.md
@@ -0,0 +1,24 @@
+# Instructions
+
+In word search puzzles you get a square of letters and have to find specific words in them.
+
+For example:
+
+```text
+jefblpepre
+camdcimgtc
+oivokprjsm
+pbwasqroua
+rixilelhrs
+wolcqlirpc
+screeaumgr
+alxhpburyi
+jalaycalmp
+clojurermt
+```
+
+There are several programming languages hidden in the above square.
+
+Words can be hidden in all kinds of directions: left-to-right, right-to-left, vertical and diagonal.
+
+Given a puzzle and a list of words return the location of the first and last letter of each word.
diff --git a/exercises/practice/word-search/.meta/config.json b/exercises/practice/word-search/.meta/config.json
new file mode 100644
index 0000000..832754a
--- /dev/null
+++ b/exercises/practice/word-search/.meta/config.json
@@ -0,0 +1,17 @@
+{
+  "authors": [
+    "erikschierboom"
+  ],
+  "files": {
+    "solution": [
+      "word-search.ua"
+    ],
+    "test": [
+      "tests.ua"
+    ],
+    "example": [
+      ".meta/example.ua"
+    ]
+  },
+  "blurb": "Create a program to solve a word search puzzle."
+}
diff --git a/exercises/practice/word-search/.meta/example.ua b/exercises/practice/word-search/.meta/example.ua
new file mode 100644
index 0000000..e1f3304
--- /dev/null
+++ b/exercises/practice/word-search/.meta/example.ua
@@ -0,0 +1,24 @@
+Grid  ← $ camdcimgtc
+        $ jcfblpepre
+        $ clojurermr
+        $ aodcdefghu
+        $ ajdcdefghj
+        $ audcdefgho
+        $ erujolcghl
+        $ aedcdefghc
+Words ← {"clojure"}
+
+Parse     ← ⊜∘≠@\n.
+Location  ← +1⊟⊃⊢⊣?
+Locations ← ⊜Location:°⊡
+
+Parse Grid
+♭₂Locations⦷"clojure"
+# ⇌♭₂Locations⦷⇌"clojure"
+# ♭₂Locations⦷⍉¤"clojure"
+# ⇌♭₂Locations⦷⍉¤⇌"clojure"
+
+# ⦷ ⬚@\W⤸0_0"aeg"
+# ⦷ ⍉⇌⬚@\W⤸0_0"aeg"
+# ⦷ ⍉⇌⍉⇌⬚@\W⤸0_0"aeg"
+# ⦷ ⍉⇌⍉⇌⍉⇌⬚@\W⤸0_0"aeg"
diff --git a/exercises/practice/word-search/.meta/tests.toml b/exercises/practice/word-search/.meta/tests.toml
new file mode 100644
index 0000000..3f98113
--- /dev/null
+++ b/exercises/practice/word-search/.meta/tests.toml
@@ -0,0 +1,82 @@
+# This is an auto-generated file.
+#
+# Regenerating this file via `configlet sync` will:
+# - Recreate every `description` key/value pair
+# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
+# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
+# - Preserve any other key/value pair
+#
+# As user-added comments (using the # character) will be removed when this file
+# is regenerated, comments can be added via a `comment` key.
+
+[b4057815-0d01-41f0-9119-6a91f54b2a0a]
+description = "Should accept an initial game grid and a target search word"
+
+[6b22bcc5-6cbf-4674-931b-d2edbff73132]
+description = "Should locate one word written left to right"
+
+[ff462410-434b-442d-9bc3-3360c75f34a8]
+description = "Should locate the same word written left to right in a different position"
+
+[a02febae-6347-443e-b99c-ab0afb0b8fca]
+description = "Should locate a different left to right word"
+
+[e42e9987-6304-4e13-8232-fa07d5280130]
+description = "Should locate that different left to right word in a different position"
+
+[9bff3cee-49b9-4775-bdfb-d55b43a70b2f]
+description = "Should locate a left to right word in two line grid"
+
+[851a35fb-f499-4ec1-9581-395a87903a22]
+description = "Should locate a left to right word in three line grid"
+
+[2f3dcf84-ba7d-4b75-8b8d-a3672b32c035]
+description = "Should locate a left to right word in ten line grid"
+
+[006d4856-f365-4e84-a18c-7d129ce9eefb]
+description = "Should locate that left to right word in a different position in a ten line grid"
+
+[eff7ac9f-ff11-443e-9747-40850c12ab60]
+description = "Should locate a different left to right word in a ten line grid"
+
+[dea39f86-8c67-4164-8884-13bfc48bd13b]
+description = "Should locate multiple words"
+
+[29e6a6a5-f80c-48a6-8e68-05bbbe187a09]
+description = "Should locate a single word written right to left"
+
+[3cf34428-b43f-48b6-b332-ea0b8836011d]
+description = "Should locate multiple words written in different horizontal directions"
+
+[2c8cd344-a02f-464b-93b6-8bf1bd890003]
+description = "Should locate words written top to bottom"
+
+[9ee1e43d-e59d-4c32-9a5f-6a22d4a1550f]
+description = "Should locate words written bottom to top"
+
+[6a21a676-f59e-4238-8e88-9f81015afae9]
+description = "Should locate words written top left to bottom right"
+
+[c9125189-1861-4b0d-a14e-ba5dab29ca7c]
+description = "Should locate words written bottom right to top left"
+
+[b19e2149-7fc5-41ec-a8a9-9bc6c6c38c40]
+description = "Should locate words written bottom left to top right"
+
+[69e1d994-a6d7-4e24-9b5a-db76751c2ef8]
+description = "Should locate words written top right to bottom left"
+
+[695531db-69eb-463f-8bad-8de3bf5ef198]
+description = "Should fail to locate a word that is not in the puzzle"
+
+[fda5b937-6774-4a52-8f89-f64ed833b175]
+description = "Should fail to locate words that are not on horizontal, vertical, or diagonal lines"
+
+[5b6198eb-2847-4e2f-8efe-65045df16bd3]
+description = "Should not concatenate different lines to find a horizontal word"
+
+[eba44139-a34f-4a92-98e1-bd5f259e5769]
+description = "Should not wrap around horizontally to find a word"
+
+[cd1f0fa8-76af-4167-b105-935f78364dac]
+description = "Should not wrap around vertically to find a word"
diff --git a/exercises/practice/word-search/tests.ua b/exercises/practice/word-search/tests.ua
new file mode 100644
index 0000000..842b27a
--- /dev/null
+++ b/exercises/practice/word-search/tests.ua
@@ -0,0 +1,264 @@
+~ "word-search.ua" ~ Search
+
+# Should accept an initial game grid and a target search word
+Grid     ← $ jefblpepre
+Words    ← {"clojure"}
+Expected ← map {"clojure"} □[]
+⍤⤙≍ Expected Search Words Grid
+
+# Should locate one word written left to right
+Grid     ← $ clojurermt
+Words    ← {"clojure"}
+Expected ← map {"clojure"} □[[1_1 1_7]]
+⍤⤙≍ Expected Search Words Grid
+
+# Should locate the same word written left to right in a different position
+Grid     ← $ mtclojurer
+Words    ← {"clojure"}
+Expected ← map {"clojure"} □[[1_3 1_9]]
+⍤⤙≍ Expected Search Words Grid
+
+# Should locate a different left to right word
+Grid     ← $ coffeelplx
+Words    ← {"coffee"}
+Expected ← map {"coffee"} □[[1_1 1_6]]
+⍤⤙≍ Expected Search Words Grid
+
+# Should locate that different left to right word in a different position
+Grid     ← $ xcoffeezlp
+Words    ← {"coffee"}
+Expected ← map {"coffee"} □[[1_2 1_7]]
+⍤⤙≍ Expected Search Words Grid
+
+# Should locate a left to right word in two line grid
+Grid     ← $ jefblpepre
+           $ tclojurerm
+Words    ← {"clojure"}
+Expected ← map {"clojure"} □[[2_2 2_8]]
+⍤⤙≍ Expected Search Words Grid
+
+# Should locate a left to right word in three line grid
+Grid     ← $ camdcimgtc
+           $ jefblpepre
+           $ clojurermt
+Words    ← {"clojure"}
+Expected ← map {"clojure"} □[[3_1 3_7]]
+⍤⤙≍ Expected Search Words Grid
+
+# Should locate a left to right word in ten line grid
+Grid     ← $ jefblpepre
+           $ camdcimgtc
+           $ oivokprjsm
+           $ pbwasqroua
+           $ rixilelhrs
+           $ wolcqlirpc
+           $ screeaumgr
+           $ alxhpburyi
+           $ jalaycalmp
+           $ clojurermt
+Words    ← {"clojure"}
+Expected ← map {"clojure"} □[[10_1 10_7]]
+⍤⤙≍ Expected Search Words Grid
+
+# Should locate that left to right word in a different position in a ten line grid
+Grid     ← $ jefblpepre
+           $ camdcimgtc
+           $ oivokprjsm
+           $ pbwasqroua
+           $ rixilelhrs
+           $ wolcqlirpc
+           $ screeaumgr
+           $ alxhpburyi
+           $ clojurermt
+           $ jalaycalmp"}
+Words    ← {"clojure"}
+Expected ← map {"clojure"} □[[9_1 9_7]]
+⍤⤙≍ Expected Search Words Grid
+
+# Should locate a different left to right word in a ten line grid
+Grid     ← $ jefblpepre
+           $ camdcimgtc
+           $ oivokprjsm
+           $ pbwasqroua
+           $ rixilelhrs
+           $ wolcqlirpc
+           $ fortranftw
+           $ alxhpburyi
+           $ clojurermt
+           $ jalaycalmp"}
+Words    ← {"fortran"}
+Expected ← map {"fortran"} □[[7_1 7_7]]
+⍤⤙≍ Expected Search Words Grid
+
+# Should locate multiple words
+Grid     ← $ jefblpepre
+           $ camdcimgtc
+           $ oivokprjsm
+           $ pbwasqroua
+           $ rixilelhrs
+           $ wolcqlirpc
+           $ fortranftw
+           $ alxhpburyi
+           $ jalaycalmp
+           $ clojurermt
+Words    ← {"fortran" "clojure"}
+Expected ← map {"clojure" "fortran"} [[10_1 10_7] [7_1 7_7]]
+⍤⤙≍ Expected Search Words Grid
+
+# Should locate a single word written right to left
+Grid     ← $ rixilelhrs
+Words    ← {"elixir"}
+Expected ← map {"elixir"} □[[1_6 1_1]]
+⍤⤙≍ Expected Search Words Grid
+
+# Should locate multiple words written in different horizontal directions
+Grid     ← $ jefblpepre
+           $ camdcimgtc
+           $ oivokprjsm
+           $ pbwasqroua
+           $ rixilelhrs
+           $ wolcqlirpc
+           $ screeaumgr
+           $ alxhpburyi
+           $ jalaycalmp
+           $ clojurermt
+Words    ← {"elixir" "clojure"}
+Expected ← map {"clojure" "elixir"} □[[10_1 10_7] [5_6 5_1]]
+⍤⤙≍ Expected Search Words Grid
+
+# Should locate words written top to bottom
+Grid     ← $ jefblpepre
+           $ camdcimgtc
+           $ oivokprjsm
+           $ pbwasqroua
+           $ rixilelhrs
+           $ wolcqlirpc
+           $ screeaumgr
+           $ alxhpburyi
+           $ jalaycalmp
+           $ clojurermt
+Words    ← {"clojure" "elixir" "ecmascript"}
+Expected ← map {"clojure" "elixir" "ecmascript"} □[[10_1 10_7] [5_6 5_1] [1_10 10_10]]
+⍤⤙≍ Expected Search Words Grid
+
+# Should locate words written bottom to top
+Grid     ← $ jefblpepre
+           $ camdcimgtc
+           $ oivokprjsm
+           $ pbwasqroua
+           $ rixilelhrs
+           $ wolcqlirpc
+           $ screeaumgr
+           $ alxhpburyi
+           $ jalaycalmp
+           $ clojurermt
+Words    ← {"clojure" "elixir" "ecmascript" "rust"}
+Expected ← map {"clojure" "elixir" "ecmascript" "rust"} □[[10_1 10_7] [5_6 5_1] [1_10 10_10] [5_9 2_9]]
+⍤⤙≍ Expected Search Words Grid
+
+# Should locate words written top left to bottom right
+Grid     ← $ jefblpepre
+           $ camdcimgtc
+           $ oivokprjsm
+           $ pbwasqroua
+           $ rixilelhrs
+           $ wolcqlirpc
+           $ screeaumgr
+           $ alxhpburyi
+           $ jalaycalmp
+           $ clojurermt
+Words    ← {"clojure" "elixir" "ecmascript" "rust" "java"}
+Expected ← map {"clojure" "elixir" "ecmascript" "rust" "java"} □[[10_1 10_7] [5_6 5_1] [1_10 10_10] [5_9 2_9] [1_1 4_4]]
+⍤⤙≍ Expected Search Words Grid
+
+# Should locate words written bottom right to top left
+Grid     ← $ jefblpepre
+           $ camdcimgtc
+           $ oivokprjsm
+           $ pbwasqroua
+           $ rixilelhrs
+           $ wolcqlirpc
+           $ screeaumgr
+           $ alxhpburyi
+           $ jalaycalmp
+           $ clojurermt
+Words    ← {"clojure" "elixir" "ecmascript" "rust" "java" "lua"}
+Expected ← map {"clojure" "elixir" "ecmascript" "rust" "java" "lua"} □[[10_1 10_7] [5_6 5_1] [1_10 10_10] [5_9 2_9] [1_1 4_4] [9_8 7_6]]
+⍤⤙≍ Expected Search Words Grid
+
+# Should locate words written bottom left to top right
+Grid     ← $ jefblpepre
+           $ camdcimgtc
+           $ oivokprjsm
+           $ pbwasqroua
+           $ rixilelhrs
+           $ wolcqlirpc
+           $ screeaumgr
+           $ alxhpburyi
+           $ jalaycalmp
+           $ clojurermt
+Words    ← {"clojure" "elixir" "ecmascript" "rust" "java" "lua" "lisp"}
+Expected ← map {"clojure" "elixir" "ecmascript" "rust" "java" "lua" "lisp"} □[[10_1 10_7] [5_6 5_1] [1_10 10_10] [5_9 2_9] [1_1 4_4] [9_8 7_6] [6_3 3_6]]
+⍤⤙≍ Expected Search Words Grid
+
+# Should locate words written top right to bottom left
+Grid     ← $ jefblpepre
+           $ camdcimgtc
+           $ oivokprjsm
+           $ pbwasqroua
+           $ rixilelhrs
+           $ wolcqlirpc
+           $ screeaumgr
+           $ alxhpburyi
+           $ jalaycalmp
+           $ clojurermt
+Words    ← {"clojure" "elixir" "ecmascript" "rust" "java" "lua" "lisp" "ruby"}
+Expected ← map {"clojure" "elixir" "ecmascript" "rust" "java" "lua" "lisp" "ruby"} □[[10_1 10_7] [5_6 5_1] [1_10 10_10] [5_9 2_9] [1_1 4_4] [9_8 7_6] [6_3 3_6] [6_8 9_5]]
+⍤⤙≍ Expected Search Words Grid
+
+# Should fail to locate a word that is not in the puzzle
+Grid     ← $ jefblpepre
+           $ camdcimgtc
+           $ oivokprjsm
+           $ pbwasqroua
+           $ rixilelhrs
+           $ wolcqlirpc
+           $ screeaumgr
+           $ alxhpburyi
+           $ jalaycalmp
+           $ clojurermt
+Words    ← {"clojure" "elixir" "ecmascript" "rust" "java" "lua" "lisp" "ruby" "haskell"}
+Expected ← map {"clojure" "elixir" "ecmascript" "rust" "java" "lua" "lisp" "ruby" "haskell"} □[[10_1 10_7] [5_6 5_1] [1_10 10_10] [5_9 2_9] [1_1 4_4] [9_8 7_6] [6_3 3_6] [6_8 9_5] []]
+⍤⤙≍ Expected Search Words Grid
+
+# Should fail to locate words that are not on horizontal, vertical, or diagonal lines
+Grid     ← $ abc
+           $ def
+Words    ← {"aef" "ced" "abf" "cbd"}
+Expected ← map {"aef" "ced" "abf" "cbd"} □[...↯0_2_2[]]
+⍤⤙≍ Expected Search Words Grid
+
+# Should not concatenate different lines to find a horizontal word
+Grid     ← $ abceli
+           $ xirdfg
+Words    ← {"elixir"}
+Expected ← map {"elixir"} □[↯0_2_2[]]
+⍤⤙≍ Expected Search Words Grid
+
+# Should not wrap around horizontally to find a word
+Grid     ← $ silabcdefp
+Words    ← {"lisp"}
+Expected ← map {"lisp"} □[↯0_2_2[]]
+⍤⤙≍ Expected Search Words Grid
+
+# Should not wrap around vertically to find a word
+Grid     ← $ s
+           $ u
+           $ r
+           $ a
+           $ b
+           $ c
+           $ t"}
+Words    ← {"rust"}
+Expected ← map {"rust"} □[↯0_2_2[]]
+⍤⤙≍ Expected Search Words Grid
diff --git a/exercises/practice/word-search/word-search.ua b/exercises/practice/word-search/word-search.ua
new file mode 100644
index 0000000..7353f1c
--- /dev/null
+++ b/exercises/practice/word-search/word-search.ua
@@ -0,0 +1,3 @@
+# Search for words in a grid
+# Findings ? Grid Words
+Search ← |2 ⊙⋅(⍤ "Please implement Search" 0)