The elements of this square grid are the first 25 positive integers. Choose five elements — no two from the same row or column — so that the largest of the five elements is as small as possible.

square number grid
A square grid containing integers that are all different.

Sidney Penner of Bronx Community College (CUNY, Bronx, New York) found the solution by crossing out all elements higher than 11. This eliminates all elements in row 2, except the element 8. Selecting element 8 means we have to forswear every other element in row 2 and column 4. Here, we have indexed the rows from top to bottom and the columns from left right, each time starting from zero.

select 8
Square grid where integer 8 has been selected. As a result, all other integers in row 2 and column 4 can be crossed out.

We mark selected elements with a gold background color and elements that can still be selected with a gray background color. The elements that can no longer be selected are crossed out by a thick red line and marked with a white background color. Now, there's only one element left in row 3 that is still open for selection and is not higher than 11. Again, selecting element 3 means that all other elements on row 3 and column 0 can be crossed out.

select 3
Square grid where integers 3 and 8 have been selected. The integers that can still be selected are marked with a gray background color.

If we continue in this way, we finally select the elements 1, 3, 6, 8 and 11.

select 1, 6 and 11
Square grid where integers 1, 3, 6, 8 and 11 have been selected. Two selected integers are never in the same row or in the same column.

No five elements can be found that are all on different rows and columns, with the largest element being less than 11.

Assignment

Define a class Grid that can be used to represent square grids. The elements of the grid must be integers that are all different. It must be possible to select elements in the grid that are all on different rows and on different columns. The rows of the grid are indexed from top to bottom and the columns from left to right, each time starting from zero.

When instantiating objects of the class Grid, a list (list) containing integers (int) that are all different must be passed. These integers are used to fill the cells of the grid from left to right and from top to bottom. As a result, the number of integers in the list must be a square number1. If the argument that is passed when instantiating an object of the class Grid does not meet the set conditions, an AssertionError must be raised with the message invalid elements. In addition, the class Grid must at least support the following methods:

If the row and column index that are passed to the methods number or is_crossed_out do not indicate a valid position of a cell in the grid, an AssertionError must be raised with the message invalid position.

If the integer that is passed to the methods position or select does not occur in the grid, an AssertionError must be raised with the message element not found.

Make sure that the built-in function str returns a string representation of the objects of the class Grid, where all rows of the grid are on separate lines. The columns of the grid must have a fixed width that equals the maximum width of the string representations of all integers in the grid, and the integers must be right aligned in the columns. Columns must be separated by a single space. Integers that have been crossed out (as defined by the method is_crossed_out) must be represented by a dash (-).

Example

>>> grid = Grid([2, 13, 16, 11, 23, 15, 1, 9, 7, 10, 14, 12, 21, 24, 8, 3, 25, 22, 18, 4, 20, 19, 6, 5, 17])
>>> print(grid)
 2 13 16 11 23
15  1  9  7 10
14 12 21 24  8
 3 25 22 18  4
20 19  6  5 17
>>> grid.element(2, 3)
24
>>> grid.element(4, 1)
19
>>> grid.element(5, -2)
Traceback (most recent call last):
AssertionError: invalid position
>>> grid.position(24)
(2, 3)
>>> grid.position(19)
(4, 1)
>>> grid.position(42)
Traceback (most recent call last):
AssertionError: element not found
>>> print(grid.select(1))
 2  - 16 11 23
 -  1  -  -  -
14  - 21 24  8
 3  - 22 18  4
20  -  6  5 17
>>> grid.select(1)
Traceback (most recent call last):
AssertionError: invalid selection
>>> print(grid.select(3).select(6))
 -  -  - 11 23
 -  1  -  -  -
 -  -  - 24  8
 3  -  -  -  -
 -  -  6  -  -
>>> grid.select(2)
Traceback (most recent call last):
AssertionError: invalid selection
>>> print(grid.select(8).select(11))
 -  -  - 11  -
 -  1  -  -  -
 -  -  -  -  8
 3  -  -  -  -
 -  -  6  -  -

>>> grid = Grid([2, 13, 16, 11, 23])
Traceback (most recent call last):
AssertionError: invalid elements
>>> grid = Grid([1, 2, 2, 1])
Traceback (most recent call last):
AssertionError: invalid elements

Epilogue

The puzzle from the introduction was published in 1976 by Leon Bankoff (Los Angeles, California, United States). He asked Jeanette Bickley from Webster Groves Senior High School (Webster Groves, Missouri, United States) to check if the largest element in Sidney Penner's solution indeed was the smallest possible element. She wrote the following BASIC2 program that she ran on her DEC PDP 11/703 computer. The program searches the given square grid for five elements (no two from the same row or column) and prints both the maximum and the five selected elements. It examines each possible remaining choice of five elements and prints only those selections that give a lower maximum element. As a result, the last line of the output shows the optimal selection: 11, 1, 8, 3, 6. This confirms Penner's solution.

5 T=0
10 MAT READ M(5,5)
20 DATA 2, 13, 16, 11, 23
30 DATA 15, 1, 9, 7, 10
40 DATA 14, 12, 21, 24, 8
50 DATA 3, 25, 22, 18, 4
60 DATA 20, 19, 6, 5, 17
70 FOR H=1 TO 5
80 A(1)=M(1,H)
90 FOR I=1 TO 5
100 IF I=H THEN 260
110 A(2) = M(2,I)
120 FOR J=1 TO 5
130 IF J=H OR J=I THEN 250
140 A(3)=M(3,J)
150 FOR K=1 TO 5
160 IF K=H OR K=I OR K=J THEN 240
170 A(4) = M(4,K)
180 FOR L = 1 TO 5
190 IF L=H OR L=I OR L=J OR L=K THEN 230
200 A(5) = M(5,L)
210 IF T=0 GO TO 500
220 GO SUB 600
230 NEXT L
240 NEXT K
250 NEXT J
260 NEXT I
270 NEXT H 
280 PRINT "THE REQUIRED ELEMENTS ARE IN THE LINE ABOVE."
290 END
500 B=A(1)
510 FOR C=2 TO 5
520 IF B>A(C) THEN 540
530 B=A(C)
540 NEXT C
560 T=1
570 GO TO 230
600 D=A(1)
610 FOR E=2 TO 5
620 IF B>A(E) THEN 640
630 D=A(E)
640 NEXT E
650 IF D>=B GO TO 680
660 PRINT D,M(1,H);M(2,I);M(3,J);M(4,K);M(5,L)
670 B=D
680 RETURN

READY

RUN
 18    2   1   8   18   6
 12    2   9   12   4   5
 11    11   1   8   3   6
THE REQUIRED ELEMENTS ARE IN THE LINE ABOVE

READY

Resources