Skip to content

Commit

Permalink
Merge pull request #380 from behrtam/implement-word-search
Browse files Browse the repository at this point in the history
Add word-search exercise
  • Loading branch information
behrtam authored Feb 21, 2017
2 parents a942e33 + 4827317 commit 5e2df01
Show file tree
Hide file tree
Showing 4 changed files with 176 additions and 0 deletions.
8 changes: 8 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,14 @@
"difficulty": 1,
"topics": [
]
},
{
"slug": "word-search",
"difficulty": 6,
"topics": [
"strings",
"searching"
]
}
],
"deprecated": [
Expand Down
57 changes: 57 additions & 0 deletions exercises/word-search/example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import copy


class Point(object):
def __init__(self, x, y):
self.x = x
self.y = y

def __repr__(self):
return 'Point({}:{})'.format(self.x, self.y)

def __add__(self, other):
return Point(self.x + other.x, self.y + other.y)

def __sub__(self, other):
return Point(self.x - other.x, self.y - other.y)

def __eq__(self, other):
return self.x == other.x and self.y == other.y

def __ne__(self, other):
return not(self == other)


DIRECTIONS = (Point(1, 0), Point(1, -1), Point(1, 1), Point(-1, -1),
Point(0, -1), Point(0, 1), Point(-1, 1), Point(-1, 0))


class WordSearch(object):
def __init__(self, puzzle):
self.rows = puzzle.split()
self.width = len(self.rows[0])
self.height = len(self.rows)

def find_char(self, coordinate):
if coordinate.x < 0 or coordinate.x >= self.width:
return
if coordinate.y < 0 or coordinate.y >= self.height:
return
return self.rows[coordinate.y][coordinate.x]

def find(self, word, position, direction):
current = copy.copy(position)
for letter in word:
if self.find_char(current) != letter:
return
current += direction
return position, current - direction

def search(self, word):
positions = (Point(x, y) for x in range(self.width) for y in range(self.height))
for pos in positions:
for d in DIRECTIONS:
result = self.find(word, pos, d)
if result:
return result
return None
27 changes: 27 additions & 0 deletions exercises/word-search/word_search.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
class Point(object):
def __init__(self, x, y):
self.x = x
self.y = y

def __repr__(self):
return 'Point({}:{})'.format(self.x, self.y)

def __add__(self, other):
return Point(self.x + other.x, self.y + other.y)

def __sub__(self, other):
return Point(self.x - other.x, self.y - other.y)

def __eq__(self, other):
return self.x == other.x and self.y == other.y

def __ne__(self, other):
return not(self == other)


class WordSearch(object):
def __init__(self, puzzle):
pass

def search(self, word):
return None
84 changes: 84 additions & 0 deletions exercises/word-search/word_search_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import unittest

from word_search import WordSearch, Point


class WordSearchTests(unittest.TestCase):

@classmethod
def setUpClass(self):
puzzle = ('jefblpepre\n'
'camdcimgtc\n'
'oivokprjsm\n'
'pbwasqroua\n'
'rixilelhrs\n'
'wolcqlirpc\n'
'screeaumgr\n'
'alxhpburyi\n'
'jalaycalmp\n'
'clojurermt')
self.example = WordSearch(puzzle)

def test_horizontal_words_left_to_right(self):
self.assertEqual(
self.example.search('clojure'),
(Point(0, 9), Point(6, 9))
)

def test_horizontal_words_right_to_left(self):
self.assertEqual(
self.example.search('elixir'),
(Point(5, 4), Point(0, 4))
)

def test_vertical_words_top_to_bottom(self):
self.assertEqual(
self.example.search('ecmascript'),
(Point(9, 0), Point(9, 9))
)

def test_vertical_words_bottom_to_top(self):
self.assertEqual(
self.example.search('rust'),
(Point(8, 4), Point(8, 1))
)

def test_diagonal_words_top_left_to_bottom_right(self):
self.assertEqual(
self.example.search('java'),
(Point(0, 0), Point(3, 3))
)

def test_diagonal_upper_bottom_right_to_top_left(self):
self.assertEqual(
self.example.search('lua'),
(Point(7, 8), Point(5, 6))
)

def test_diagonal_upper_bottom_left_to_top_right(self):
self.assertEqual(
self.example.search('lisp'),
(Point(2, 5), Point(5, 2))
)

def test_diagonal_upper_top_right_to_bottom_left(self):
self.assertEqual(
self.example.search('ruby'),
(Point(7, 5), Point(4, 8))
)

def test_words_that_are_not_in_the_puzzle(self):
self.assertIsNone(self.example.search('haskell'))

def test_search_differently_sized_puzzles(self):
puzzle = ('qwertyuiopz\n'
'luamsicrexe\n'
'abcdefghijk')
self.assertEqual(
WordSearch(puzzle).search('exercism'),
(Point(10, 1), Point(3, 1))
)


if __name__ == '__main__':
unittest.main()

0 comments on commit 5e2df01

Please sign in to comment.