# backtracking - only enter a promising spot, so I need to : - check before initial call - check before every recursive/fan-out call - check termination at the beginning of backtrack() - add to path/visited before fanout for-loop - remove from path/visited after fanout for-loop ```python= def soln(grid, word): m = len(grid) n = len(grid[0]) def inside(i, j): return (0 <= i < m and 0 <= j < n) def btrack (i, j, k): # Guaranteed this (i,j) matchs the letter # Termination: Record/return the result. Stop go further # If matched and already the last one -> full matched -> dump the path if k == len(word) - 1: ans_li.append(path + [(i, j)]) # Make a hard copy. return # Not yet full matched. # So, all guys in `path` and `visited` are always legal and promising path.append((i, j)) visited.add((i, j)) # fanout for newi, newj in [(i + 1, j), (i, j + 1)]: # only try on legal and promising spots if ((newi, newj) not in visited and inside(newi, newj) and grid[newi][newj] == word[k + 1]): # https://google.github.io/styleguide/pyguide.html#32-line-length btrack(newi, newj, k + 1) path.pop() visited.remove((i, j)) return ans_li = [] path = [] visited = set() for i in range(m): for j in range(n): # Always ensure btrack() is entering a promising spot # 1) inside: yes # 2) visited: no # 3) letter matched: yes if grid[i][j] == word[0]: btrack(i, j, 0) return ans_li grid1 = [ ['c', 'c', 't', 'n', 'a', 'x'], ['c', 'c', 'a', 't', 'n', 't'], ['a', 'c', 'n', 'n', 't', 't'], ['t', 'n', 'i', 'i', 'p', 'p'], ['a', 'o', 'o', 'o', 'a', 'a'], ['s', 'a', 'a', 'a', 'o', 'o'], ['k', 'a', 'i', 'o', 'k', 'i'], ] word1 = "catnip" word2 = "cccc" word3 = "s" word4 = "ant" word5 = "aoi" word6 = "ki" word7 = "aaoo" word8 = "ooo" word9 = "a" """ find_word_location(grid1, word1) => [ (1, 1), (1, 2), (1, 3), (2, 3), (3, 3), (3, 4) ] find_word_location(grid1, word2) => [(0, 0), (1, 0), (1, 1), (2, 1)] OR [(0, 0), (0, 1), (1, 1), (2, 1)] find_word_location(grid1, word3) => [(5, 0)] find_word_location(grid1, word4) => [(0, 4), (1, 4), (2, 4)] OR [(0, 4), (1, 4), (1, 5)] find_word_location(grid1, word5) => [(4, 5), (5, 5), (6, 5)] find_word_location(grid1, word6) => [(6, 4), (6, 5)] find_word_location(grid1, word7) => [(5, 2), (5, 3), (5, 4), (5, 5)] find_word_location(grid1, word8) => [(4, 1), (4, 2), (4, 3)] find_word_location(grid2, word9) => [(0, 0)] """ grid2 = [['a']] print(soln(grid1, word1)) print(soln(grid1, word2)) print(soln(grid1, word3)) print(soln(grid1, word4)) print(soln(grid1, word5)) print(soln(grid1, word6)) print(soln(grid1, word7)) print(soln(grid1, word8)) print(soln(grid2, word9)) print(soln(grid1, word9)) print(soln(grid1, "qwert")) ```