Search code examples
pythonrecursionmatrixlanguage-agnostic

How to generate a matrix with permutations where any 2x2 square has 4 non-identical values?


So let's say my matrix looks like this (always a square):

a1 a2 a3
b1 b2 b3
c1 c2 c3

I want so that elements in the square, (a1, a2, b1, b2), (a2, a3, b2, b3), etc were not similar — meaning : a1 != a2 != b1 != b2.

I have this code for recursively generating the matrix:

def generate(elements):
    if not elements:
        return (),
    final = []
    for items in generate(elements[:-1]):
        for item in elements[-1]:
            final.append(items + (item,))
    return final

def product(*args, repeat=1):
    pools = [list(pool) for pool in args] * repeat
    return list(generate(pools))

def main():
    D = 3
    combinations = product([0, 128, 196], repeat=D)
    matrices = product(combinations, repeat=D)
    return matrices

where elements is a list of integers (unknown number), let's say [0, 128, 196] and repeat is the size of the square matrix.

I want somewhere in the function to apply the rule, so that it will only generate matrices according to that rule that I mentioned.

So in the end the final result would be all the possible variations of 3x3 matrices but with that rule applied.

Would prefer to do it without importing pandas or anything like that.


Solution

  • solved it by adding a new function that checks each 2 lines. little bit slow but it works.

    def square_chec(row1, row2):
        if row1[-1] == row2[-1]:
            return False
        for num in range(len(row1)-1):
            if row2[num+1] == row1[num] or row2[num] == row1[num] or row1[num+1] == row2[num] or row2[num] == row1[num]:
                return False
        return True
    
    def generate(elements):
        if not elements:
            return (),
        final = []
        for items in generate(elements[:-1]):
            for item in elements[-1]:
                if items:
                    if items[-1] != item:
                        if type(item) == tuple:
                            if square_chec(items[-1], item):
                                final.append(items + (item,))
                        else:
                            final.append(items + (item,))
                else:
                    final.append(items + (item,))
        return final