Skip to content

Commit

Permalink
Add Word Search exercise (#1223)
Browse files Browse the repository at this point in the history
  • Loading branch information
tofische authored Apr 10, 2024
1 parent 63ef025 commit 45c6c83
Show file tree
Hide file tree
Showing 10 changed files with 546 additions and 0 deletions.
11 changes: 11 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,17 @@
"strings"
]
},
{
"slug": "word-search",
"name": "Word Search",
"uuid": "6d406931-7173-4fc0-b897-798227d09b5e",
"practices": [],
"prerequisites": [],
"difficulty": 5,
"topics": [
"strings"
]
},
{
"slug": "wordy",
"name": "Wordy",
Expand Down
24 changes: 24 additions & 0 deletions exercises/practice/word-search/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -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.
21 changes: 21 additions & 0 deletions exercises/practice/word-search/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"authors": [
"tofische"
],
"files": {
"solution": [
"src/WordSearch.hs",
"package.yaml"
],
"test": [
"test/Tests.hs"
],
"example": [
".meta/examples/success-standard/src/WordSearch.hs"
],
"invalidator": [
"stack.yaml"
]
},
"blurb": "Create a program to solve a word search puzzle."
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: word-search

dependencies:
- base

library:
exposed-modules: WordSearch
source-dirs: src

tests:
test:
main: Tests.hs
source-dirs: test
dependencies:
- word-search
- hspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
module WordSearch (search, CharPos(..), WordPos(..)) where

import Data.Maybe (listToMaybe)

data CharPos = CharPos{col::Int, row::Int} deriving (Eq, Show)
data WordPos = WordPos{start::CharPos, end::CharPos} deriving (Eq, Show)

search :: [String] -> [String] -> [(String, Maybe WordPos)]
search grid wordList = map (search' grid) wordList

search' :: [String] -> String -> (String, Maybe WordPos)
search' grid word = (word, listToMaybe hits)
where
lastRow = length grid - 1
lastCol = length (head grid) - 1
lastIdx = length word - 1
hits = [WordPos{start=CharPos{col=startCol+1, row=startRow+1}, end=CharPos{col=endCol+1, row=endRow+1}} |
startCol <- [0 .. lastCol],
dirCol <- [- 1, 0, 1],
let endCol = startCol + lastIdx*dirCol,
endCol >= 0 && endCol <= lastCol,
startRow <- [0 .. lastRow],
dirRow <- [- 1, 0, 1],
let endRow = startRow + lastIdx*dirRow,
endRow >= 0 && endRow <= lastRow,
let gridWord = [
(grid!!r)!!c | idx <- [0 .. lastIdx],
let c = startCol + idx*dirCol,
let r = startRow + idx*dirRow
],
and $ zipWith (==) word gridWord
]
82 changes: 82 additions & 0 deletions exercises/practice/word-search/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -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"
21 changes: 21 additions & 0 deletions exercises/practice/word-search/package.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: word-search
version: 1.0.0.0

dependencies:
- base

library:
exposed-modules: WordSearch
source-dirs: src
ghc-options: -Wall
# dependencies:
# - foo # List here the packages you
# - bar # want to use in your solution.

tests:
test:
main: Tests.hs
source-dirs: test
dependencies:
- word-search
- hspec
7 changes: 7 additions & 0 deletions exercises/practice/word-search/src/WordSearch.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module WordSearch (search, CharPos(..), WordPos(..)) where

data CharPos = CharPos{col::Int, row::Int} deriving (Eq, Show)
data WordPos = WordPos{start::CharPos, end::CharPos} deriving (Eq, Show)

search :: [String] -> [String] -> [(String, Maybe WordPos)]
search grid wordList = error "You need to implement this function."
1 change: 1 addition & 0 deletions exercises/practice/word-search/stack.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
resolver: lts-20.18
Loading

0 comments on commit 45c6c83

Please sign in to comment.