-1

I have list:

words = ["ALI", "SIN", "ASI", "LIR", "IRI", "INI", "KAR"]

I want to check if they form matrix such as this:

sample

and return my solution as a list like:

solution = ["ALI", "SIN", "IRI"]

I have come up with this code:

words=["ALI", "SIN", "ASI", "LIR", "IRI", "INI", "KAR"]
solution =[]
failedsolutions = []

def Get_next_word():

    while True:
        for word in words:
            if (word in solution) == False:
                solution.append(word)
                if (solution in failedsolutions) == False:
                    return False
                else:
                    solution.pop(len(solution) - 1 )
        return True

def Check_word_order():
    checker = True
    for i in range(len(solution)):
        for j in range(len(words[0])):
            for word in words:
                if solution[i][j] == word[j]:
                    checker = False
                else:
                    checker = True
            if checker == False:
                return checker

def main():
    while True:
        Get_next_word()


        check = Check_word_order()

        if check is False:
            #Backtrack
            failedsolutions.append(solution)
            solution.pop(len(solution) - 1 )

    #    else:
    #        solution.append()

    print(solution)

main()

I am tired and no longer be able to debug my code. Help will be appreciated. Thank you ps: I advice not fixing my code if there is a better way to it all.

  • What specific pattern are you trying to create? It is not immediately clear from the example image. – Ajax1234 Dec 24 '17 at 04:21
  • 1
    It is probably not related to whatever issue you're having, but `(word in solution) == False` can be more idiomatically written `word not in solution`. You almost never need to compare a variable against a Boolean literal. – Blckknght Dec 24 '17 at 04:45
  • @Ajax1234 i try to put the words in rows while they form other words when looked from columns. Sorry for bad explanation –  Dec 24 '17 at 04:48
  • @tugkan please see my answer below – Ajax1234 Dec 24 '17 at 14:53

1 Answers1

1

You can use this simple recursive function which will analyze all possible groups:

import itertools
import copy
words = ["ALI", "SIN", "ASI", "LIR", "IRI", "INI", "KAR"]
def get_pairs(word_group, current_words, found):
   if not current_words:
     return found
   new_group = list(word_group)+[current_words[0]]
   if all(''.join(i) in words and ''.join(i) not in new_group for i in zip(*new_group)):
      return get_pairs(word_group, current_words[1:], new_group)
   return get_pairs(word_group, current_words[1:], found)


starting_pairs = [i for i in itertools.combinations(words, 2)]
final_listing = filter(lambda x:x, [get_pairs(i, copy.deepcopy(words), []) for i in starting_pairs])

Output:

[['ALI', 'SIN', 'IRI'], ['ASI', 'LIR', 'INI']]

Which yields all combinations of valid matrices.

Or, without using itertools:

def get_combos(word, new_words):
   if new_words[1:]:
     new_list = [(yield (word, i)) for i in new_words if i != word]
     for b in get_combos(new_words[0], new_words[1:]):
        yield b

starting_pairs = get_combos(words[0], words[1:])
final_listing = filter(lambda x:x, [get_pairs(i, copy.deepcopy(words), []) for i in starting_pairs])
Ajax1234
  • 69,937
  • 8
  • 61
  • 102
  • Thank you. In second match there is ALI in row and ALI in first column. That should not happend. Sorry I explained it poorly. Also can you explain final_listing filter part and what is the difference between "copy.deepcopy(words)" and creating a variable and seting it to the reference of words. Thank you again –  Dec 24 '17 at 19:06
  • @tugkan My apologies. It is fixed now. filter removes all empty lists which get_combos returns if no matrix is found for the current testing combination. copy.deepcopy(words) destroys the reference between words and the value passed to get_combos. That way, any mutations of `current_words` will not affect `words`. – Ajax1234 Dec 24 '17 at 19:33