A word square consists of a list of words written out in a square grid, such that the same words can be read both horizontally and vertically from the corresponding row and column in the grid. The number of words, which is equal to the number of letters in each word, is known as the order of the square. For example, this is an order 3 square:

woordvierkant orde 3

Large word squares are dramatically harder to make than small ones. To date, the largest anyone has managed to find are composed of 9-letter words:

woordvierkant orde 9

Finding a perfect $$10 \times 10$$ word square has been a central goal for wordplay fans for more than 100 years. The task was looking impossible when in 1972 Dmitri Borgmann found an unexpected resource in the African journal of David Livingstone, whose entry for Sept. 26, 1872, reads:

Through forest, along the side of a sedgy valley. Cross its head-water, which has rust of iron in it, then west and by south. The forest has very many tsetse. Zebras calling loudly, and Senegal long claw in our camp at dawn, with its cry, 'O-o-o-o-o-o-o-o-o-o.'

This is exactly what was needed. Given a pen, the yellow-bellied longclaw, Macronyx flavigaster, could have drawn for Livingstone a perfect $$10 \times 10$$ square:

woordvierkant orde 10

We ought to consult other species more often. Any longclaw could have given us this contribution — indeed, this is the only word square the bird is capable of making!

Macronyx flavigaster

Assignment

Because word squares are symmetric with respect to their main diagonal, they can be fully described by reading the letters on or below the main diaginal from left to right and from top to bottom. The order 3 word square that is given as an example in the introduction, can be described in this way as the 6-letter string BICTEN. In general, any order $$n$$ word square can be described as an $$\frac{n(n + 1)}{2}$$-letter string containing the letters on or below the main diagonal. Your task is to define a class WordSquare that can be used to represent word squares  in Python. This class must support at least the following methods:

In addition, it should be possible to use the built-in function print to output a string representation of each object that is an instance of the class WordSquare. In this string representation, the letters of the word square are written out row by row, as illustrated in the examples below.

Example

In the following interactive session, we assume that the text file words.txt1 is located in the current directory.

>>> square = WordSquare(3, 'bicten')
>>> square.letter(1, 0)
'I'
>>> square.letter(1, 1)
'C'
>>> square.letter(1, 2)
'E'
>>> square.word(1)
'ICE'
>>> print(square)
BIT
ICE
TEN
>>> square.valid('words.txt')
True

>>> square.letter(1, 3)
Traceback (most recent call last):
AssertionError: invalid index
>>> square.word(3)
Traceback (most recent call last):
AssertionError: invalid index

>>> square = WordSquare(3, 'ABCDE')
Traceback (most recent call last):
AssertionError: invalid square

>>> square = WordSquare(9, 'ACRHEXANABLINOLADDLEHSERINETINITIATOASCENDERS')
>>> square.word(1)
'CRENIDENS'
>>> square.word(7)    
'INITIATOR'
>>> print(square)
ACHALASIA
CRENIDENS
HEXANDRIC
ANABOLITE
LINOLENIN
ADDLEHEAD
SERINETTE
INITIATOR
ASCENDERS
>>> square.valid('words.txt')
True

>>> square = WordSquare(4, 'ABCDEFGHIJ')
>>> print(square)
ABDG
BCEH
DEFI
GHIJ
>>> square.valid('words.txt')
False

Resources