board3 = [["d","c","e","b","d","e","d","a"],
["c","a","e","a","d","d","e","e"],
["a","c","r","d","b","i","c","b"],
["c","b","a","n","a","r","i","e"],
["a","e","d","e","r","i","d","e"],
["a","a","a","m","i","a","d","e"],
["b","d","n","b","b","b","k","o"],
["d","a","e","e","b","e","o","o"],
["b","b","c","a","b","b","p","a"],
["a","c","b","a","c","a","d","d"]]
class MatrixPookHrook:
def __init__(self, mtx):
self.mtx = self.prepare_matrix(mtx)
def prepare_matrix(self, mtx):
out, idx = {}, 0
for _l, lst in enumerate(mtx):
for _w, ltr in enumerate(lst):
out[idx], out[idx]['letter'] = {}, ltr
out[idx]['left'] = (lst[_w-1], idx-1) if _w else None
out[idx]['right'] = (lst[_w+1], idx+1) if _w != len(lst)-1 else None
out[idx]['up'] = (mtx[_l-1][_w], len(mtx[_l-1])*(_l-1)+_w) if _l else None
if _l != len(mtx)-1 and len(mtx[_l+1]) > _w:
out[idx]['down'] = (mtx[_l+1][_w], len(mtx[_l])*(_l+1)+_w)
else:
out[idx]['down'] = None
idx += 1
return out
def find_one_word(self, word, out=None):
# возвращает индексы матрицы, так если бы матрица была плоским списком
def rectal_search(word, ltr_idx, mtx_idx, res=[], fork=[]):
_tmp = self.mtx[mtx_idx]
if ltr_idx or _tmp['letter'] == word[ltr_idx]:
res.append(mtx_idx)
ltr_idx += 1
if ltr_idx == len(word):
return res
for r in ('left', 'right', 'up', 'down'):
if _tmp[r] and _tmp[r][0] == word[ltr_idx] and _tmp[r][1] not in res:
fork.append((ltr_idx, _tmp[r][1]))
if fork:
ltr_idx, mtx_idx = fork.pop()
res = res[:ltr_idx]
return rectal_search(word, ltr_idx, mtx_idx, res, fork)
for idx in self.mtx:
out = rectal_search(word, 0, idx)
if out:
return out
return None
def find_words(self, word_lst):
out = []
for w in words3:
if self.find_one_word(w):
out.append(w)
return out
words3 = ["ab","nariman", "poook", "ededa","d"]
mtx = MatrixPookHrook(board3)
#print(mtx.find_one_word("nariman"))
print(mtx.find_words(["ab","nariman", "poook", "ededa","d"]))
Ym9hcmQzID0gW1siZCIsImMiLCJlIiwiYiIsImQiLCJlIiwiZCIsImEiXSwKICAgICAgICAgIFsiYyIsImEiLCJlIiwiYSIsImQiLCJkIiwiZSIsImUiXSwKICAgICAgICAgIFsiYSIsImMiLCJyIiwiZCIsImIiLCJpIiwiYyIsImIiXSwKICAgICAgICAgIFsiYyIsImIiLCJhIiwibiIsImEiLCJyIiwiaSIsImUiXSwKICAgICAgICAgIFsiYSIsImUiLCJkIiwiZSIsInIiLCJpIiwiZCIsImUiXSwKICAgICAgICAgIFsiYSIsImEiLCJhIiwibSIsImkiLCJhIiwiZCIsImUiXSwKICAgICAgICAgIFsiYiIsImQiLCJuIiwiYiIsImIiLCJiIiwiayIsIm8iXSwKICAgICAgICAgIFsiZCIsImEiLCJlIiwiZSIsImIiLCJlIiwibyIsIm8iXSwKICAgICAgICAgIFsiYiIsImIiLCJjIiwiYSIsImIiLCJiIiwicCIsImEiXSwKICAgICAgICAgIFsiYSIsImMiLCJiIiwiYSIsImMiLCJhIiwiZCIsImQiXV0KCgpjbGFzcyBNYXRyaXhQb29rSHJvb2s6CiAgICBkZWYgX19pbml0X18oc2VsZiwgbXR4KToKICAgICAgICBzZWxmLm10eCA9IHNlbGYucHJlcGFyZV9tYXRyaXgobXR4KQogICAgICAgIAogICAgZGVmIHByZXBhcmVfbWF0cml4KHNlbGYsIG10eCk6CiAgICAgICAgb3V0LCBpZHggPSB7fSwgMAogICAgICAgIGZvciBfbCwgbHN0IGluIGVudW1lcmF0ZShtdHgpOgogICAgICAgICAgICBmb3IgX3csIGx0ciBpbiBlbnVtZXJhdGUobHN0KToKICAgICAgICAgICAgICAgIG91dFtpZHhdLCBvdXRbaWR4XVsnbGV0dGVyJ10gPSB7fSwgbHRyCiAgICAgICAgICAgICAgICBvdXRbaWR4XVsnbGVmdCddID0gKGxzdFtfdy0xXSwgaWR4LTEpIGlmIF93IGVsc2UgTm9uZQogICAgICAgICAgICAgICAgb3V0W2lkeF1bJ3JpZ2h0J10gPSAobHN0W193KzFdLCBpZHgrMSkgaWYgX3cgIT0gbGVuKGxzdCktMSBlbHNlIE5vbmUKICAgICAgICAgICAgICAgIG91dFtpZHhdWyd1cCddID0gKG10eFtfbC0xXVtfd10sIGxlbihtdHhbX2wtMV0pKihfbC0xKStfdykgaWYgX2wgZWxzZSBOb25lCiAgICAgICAgICAgICAgICBpZiBfbCAhPSBsZW4obXR4KS0xIGFuZCBsZW4obXR4W19sKzFdKSA+IF93OgogICAgICAgICAgICAgICAgICAgIG91dFtpZHhdWydkb3duJ10gPSAobXR4W19sKzFdW193XSwgbGVuKG10eFtfbF0pKihfbCsxKStfdykKICAgICAgICAgICAgICAgIGVsc2U6CiAgICAgICAgICAgICAgICAgICAgb3V0W2lkeF1bJ2Rvd24nXSA9IE5vbmUKICAgICAgICAgICAgICAgIGlkeCArPSAxCiAgICAgICAgcmV0dXJuIG91dAogICAgICAgIAogICAgZGVmIGZpbmRfb25lX3dvcmQoc2VsZiwgd29yZCwgb3V0PU5vbmUpOgogICAgICAgICMg0LLQvtC30LLRgNCw0YnQsNC10YIg0LjQvdC00LXQutGB0Ysg0LzQsNGC0YDQuNGG0YssINGC0LDQuiDQtdGB0LvQuCDQsdGLINC80LDRgtGA0LjRhtCwINCx0YvQu9CwINC/0LvQvtGB0LrQuNC8INGB0L/QuNGB0LrQvtC8CiAgICAgICAgZGVmIHJlY3RhbF9zZWFyY2god29yZCwgbHRyX2lkeCwgbXR4X2lkeCwgcmVzPVtdLCBmb3JrPVtdKToKICAgICAgICAgICAgX3RtcCA9IHNlbGYubXR4W210eF9pZHhdCiAgICAgICAgICAgIGlmIGx0cl9pZHggb3IgX3RtcFsnbGV0dGVyJ10gPT0gd29yZFtsdHJfaWR4XToKICAgICAgICAgICAgICAgIHJlcy5hcHBlbmQobXR4X2lkeCkKICAgICAgICAgICAgICAgIGx0cl9pZHggKz0gMQogICAgICAgICAgICAgICAgaWYgbHRyX2lkeCA9PSBsZW4od29yZCk6CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlcwogICAgICAgICAgICAgICAgZm9yIHIgaW4gKCdsZWZ0JywgJ3JpZ2h0JywgJ3VwJywgJ2Rvd24nKToKICAgICAgICAgICAgICAgICAgICBpZiBfdG1wW3JdIGFuZCBfdG1wW3JdWzBdID09IHdvcmRbbHRyX2lkeF0gYW5kIF90bXBbcl1bMV0gbm90IGluIHJlczoKICAgICAgICAgICAgICAgICAgICAgICAgZm9yay5hcHBlbmQoKGx0cl9pZHgsIF90bXBbcl1bMV0pKQogICAgICAgICAgICAgICAgaWYgZm9yazoKICAgICAgICAgICAgICAgICAgICBsdHJfaWR4LCBtdHhfaWR4ID0gZm9yay5wb3AoKQogICAgICAgICAgICAgICAgICAgIHJlcyA9IHJlc1s6bHRyX2lkeF0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVjdGFsX3NlYXJjaCh3b3JkLCBsdHJfaWR4LCBtdHhfaWR4LCByZXMsIGZvcmspCiAgICAgICAgICAgIAogICAgICAgIGZvciBpZHggaW4gc2VsZi5tdHg6CiAgICAgICAgICAgIG91dCA9IHJlY3RhbF9zZWFyY2god29yZCwgMCwgaWR4KQogICAgICAgICAgICBpZiBvdXQ6CiAgICAgICAgICAgICAgICByZXR1cm4gb3V0CiAgICAgICAgcmV0dXJuIE5vbmUKICAgICAgICAKICAgIGRlZiBmaW5kX3dvcmRzKHNlbGYsIHdvcmRfbHN0KToKICAgICAgICBvdXQgPSBbXQogICAgICAgIGZvciB3IGluIHdvcmRzMzoKICAgICAgICAgICAgaWYgc2VsZi5maW5kX29uZV93b3JkKHcpOgogICAgICAgICAgICAgICAgb3V0LmFwcGVuZCh3KQogICAgICAgIHJldHVybiBvdXQKCndvcmRzMyA9IFsiYWIiLCJuYXJpbWFuIiwgInBvb29rIiwgImVkZWRhIiwiZCJdCgptdHggPSBNYXRyaXhQb29rSHJvb2soYm9hcmQzKQojcHJpbnQobXR4LmZpbmRfb25lX3dvcmQoIm5hcmltYW4iKSkKcHJpbnQobXR4LmZpbmRfd29yZHMoWyJhYiIsIm5hcmltYW4iLCAicG9vb2siLCAiZWRlZGEiLCJkIl0pKQ==