Numbers in a Matrix

But I got stuck at generating a single valid table. I was expecting the program to display a valid matrix, but in order for the program to continue and not print

None

, I had to assign a

7

for a square that has no possibles. What should be fixed?

My code so far:

from pprint import pprint
import sys
import random

sys.setrecursionlimit(10000)

def getPossiblesForSquare(sqx,sqy,matrix):
'''Gets the possible entries of matrix[sqy][sqx].
Assumes it equals 0.'''
assert matrix[sqy][sqx]==0
# get the row that it is on
rowon=matrix[sqy]
# columns are a little trickier
colon=[matrix[row][sqx] for row in range(5)]

# find the possibilities!
possibles=list(range(1,7))

for item in list(set(rowon+colon)): # remove duplicates
if not (item == 0) and (item in possibles):
del possibles[possibles.index(item)]

random.shuffle(possibles)

return possibles

def getPossiblesForMatrix(matrix):
'''Gets all the possible squares for a matrix.'''
possiblesdict={}
for y in range(6):
for x in range(6):
if matrix[y][x]==0:
possiblesdict[(y,x)]=getPossiblesForSquare(x,y,MATRIX)
return possiblesdict

def flattenList(matrix):
result=[]
for i in matrix:
if not isinstance(i,list):
result+=[i]
else:
result+=flattenList(i)
return result

Why your script hangs:

Essentially your script encounters problems here:

for item in list(set(rowon + colon)): # remove duplicates
if not (item == 0) and (item in possibles):
del possibles[possibles.index(item)]

At the third iteration, for the third cell your if condition is evaluated as true for all possible values [1 to 6] (if you output the matrix you will see that the set() you are creating contains all elements), so you always return zero, re-check the values, return zero ad infinitum.

If you're looking to brute-force a solution out of this, you might want to update the sqx and sqy to go to a different cell when possibles is empty.

Another additional small mistake I located was:

# you are checking values 1-5 and not 1-6!
possibles = list(range(1, 6)) # should be range(7) [exclusive range]

Don't forget that range is exclusive, it doesn't include (excludes) the upper limit.

There exist of course, different ways to tackle this problem.

A possible -alternate- solution:

Read this for the general, alternate view of how to solve this. If you do not want to see a possible solution, skip the 'code' part.

The solution matrix (one of the possible ones) has this form (unless I am making a horrible mistake):

You must observe the symmetry present in the matrix. Specifically, every row and every column displays a 'flip and reverse' symmetry. For example, the first and last rows are connected by this equation :

row[0] = REV(flip(row[n]))

Similarly, all additional rows (or columns) have their corresponding counterpart:

row[1] = REV(flip(row[n-1]))

and so on.

So, for n=6 this essentially boils down to finding the (n / 2) -1 (because we already know the first and last row!) and afterwards flipping them (not the finger), reversing them and assigning them to their corresponding rows.

In order to find these values we can observe the matrix as a combination of smaller matrices:

and the other two rows can be made by finding the correct values for these two.

Observe the restrictions in hand:

In column [1][1] and [1][m-1] we cannot:

place a 2 or a 5

In columns [1][2] and [1][m-2] we cannot:

place the previous values ([2, 5]) along with ([3, 4]) so, we cannot have a value in[2,3,4,5]

For the inner columns we're left with the set set(1-6) - set(2-5) = [1, 6]
and since we get a normal row and a single inverted and flipped row for this, we can arbitrarily select a value and add it as a column value.

By using another list we can keep track of the values used and fill out the rest of the cells.

Coding this: (Spoilers)

Note: I did not use numpy for this. You can and should though. (Also, Python 2.7)

Also, I did not use recursion for this (you can try to, by finding the same matrix for bigger values of n [I believe it's a good fit for a recursive function].

First, in order to not type this all the time, you can create a n x n matrix as follows: (This isn't much of a spoiler.)

Additionally

By using this way of solving it the answer to the problem in hand becomes more easy. Viewing the matrix as a combination of these sub-matrices you can tell how many of these combinations might be possible.

As a closing note, it would be a good work-out to modify it a bit in order to allow it to find this array for an arbitrary (but even) number of n.