isKingsTour(board) [15 pts]
Background: in Chess, a King can move from any square to any adjacent square
in any of the 8 possible directions. A King's Tour is a series of legal King moves so that every square is visited exactly once.
For example, here is a valid Kings Tour:
And here is an invalid Kings Tour:
We can represent a Kings Tour in a 2d list where the numbers represent the order the squares are visited, going from 1 to N2. For example, consider these 2d lists:
[ [ 3, 2, 1 ], [ [ 1, 2, 3 ], [ [ 3, 2, 1 ],
[ 6, 4, 9 ], [ 7, 4, 8 ], [ 6, 4, 0 ],
[ 5, 7, 8 ] ] [ 6, 5, 9 ] ] [ 5, 7, 8 ] ]
The first is a legal Kings Tour but the second is not, because there is no way to legally move from the 7 to the 8, and the third is not, because it contains a 0 which is out of range. Also, this should work not just for 3x3 boards but for
any NxN board. For example, here is a legal Kings Tour in a 4x4 board:
[ [ 1, 14, 15, 16],
[ 13, 2, 7, 6],
[ 12, 8, 3, 5],
[ 11, 10, 9, 4]
]
With this in mind, write the function isKingsTour(board) that takes a 2d list of integers, which you may assume is NxN for some N>0, and returns True if it represents a legal Kings Tour and False otherwise.
Bonus/Optional: makeWordSearch(wordList, replaceEmpties) [2.5 pts]
Write the function makeWordSearch(wordList, replaceEmpties) that takes a possibly-empty list
of non-empty lowercase words and a boolean value replaceEmpties (that we will
explain later) and returns a wordSearch (a 2d list of lowercase letters)
that contains all the given words, according to the algorithm described here.
To start, if the wordList is empty, just return None. Otherwise, start
with a 0x0 board. Add each word in the order given to the board according
to the rules below, and return the resulting board.
First, if the word is longer than the number of rows in the board (which is guaranteed
to happen on the first word), then it cannot possibly fit on the board (right?).
In that case, add empty rows and empty columns to the board, keeping the board
square, so that the number of rows equals the length of the word.
Note that empty cells do not yet contain any letters.
Next, if possible,
add the word in the location and direction resulting in the
lowest cost, where the cost is the total number of
empty cells that must be filled in with a letter to add the word at the given location and direction.
If there is a tie, use the first location and direction with the lowest cost, where
you should sweep across row0 from left-to-right, then row1, and so on, and
where the directions should be ordered in the same way (up-left, up, up-right,
left, right, down-left, down, down-right).
It is possible that this process completes with no place to add the word.
In that case,
add one more row and one more column of empty cells to the board, keeping it
square, and then add the
word to the bottom row starting at column 0 and heading to the right.
Hint: you should carefully re-read the previous paragraph, as it may
not be too intuitive!
After you have added all the words, if the replaceEmpties parameter is
False, return the board as-is, with empty cells containing a dash ('-').
However, if replaceEmpties is True, then for each empty cell on the board,
replace it with the first lowercase letter that does not appear among
its non-empty neighbors. Do this sweeping the usual way, left-to-right
across row0, then row1, and so on.
You will surely want to add some well-chosen helper functions here. Also,
you may wish to carefully review a few test cases we are providing you,
prior to designing your solution:
def testMakeWordSearch():
print("Testing makeWordSearch()...", end="")
board = makeWordSearch([], False)
assert(board == None)
board = makeWordSearch(["ab"], False)
assert(board == [['a', 'b'], ['-', '-'] ])
board = makeWordSearch(["ab"], True)
assert(board == [['a', 'b'], ['c', 'd'] ])
board = makeWordSearch(["ab", "bc", "cd"], False)
assert(board == [['a', 'b'], ['c', 'd'] ])
board = makeWordSearch(["ab", "bc", "cd", "de"], False)
assert(board == [['a', 'b', '-'], ['c', 'd', '-'], ['d', 'e', '-']])
board = makeWordSearch(["ab", "bc", "cd", "de"], True)
assert(board == [['a', 'b', 'a'], ['c', 'd', 'c'], ['d', 'e', 'a']])
board = makeWordSearch(["abc"], False)
assert(board == [['a', 'b', 'c'], ['-', '-', '-'], ['-', '-', '-']])
board = makeWordSearch(["abc"], True)
assert(board == [['a', 'b', 'c'], ['c', 'd', 'a'], ['a', 'b', 'c']])
board = makeWordSearch(["abc", "adc", "bd", "bef", "gfc"], False)
assert(board == [['a', 'b', 'c'], ['d', 'e', '-'], ['c', 'f', 'g']])
board = makeWordSearch(["abc", "adc", "bd", "bef", "gfc"], True)
assert(board == [['a', 'b', 'c'], ['d', 'e', 'a'], ['c', 'f', 'g']])
print("Passed!")