1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
from functools import lru_cache # the left half of the palindrome pal = 'SELIMSTIREDNOW' lh = len(pal) # fill out the grid g = [' '] * (2 * lh + 1) for i in range(lh + 1): if not i: r = ' ' * (2 * lh + 1) else: ins = pal[:i - 1] + pal[:i][::-1] ps = ' ' * (lh - i + 1) r = ''.join((ps, ins, ps)) g[2 * lh - i] = g[i] = r # print it out for r in g: print(r) # count the total number of paths from the W to all the outer S values @lru_cache(maxsize=None) def count_paths(k, i, j, p): return (1 if k == 0 else sum(count_paths(k - 1, x, y, p) for x, y in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)) if g[x][y] == p[k - 1])) cnt = count_paths(lh - 1, lh, lh, pal) # if there are N paths from the W to the outer S's, the number of paths # covering the full palindrome will be N^2 print(f'{cnt ** 2:,} ways') |

Here an analytic solution:

The filled in grid is shown above. Only the outer S’s can start and end the palindrome since the other S’s don’t have adjacent E’s.

Instead of counting the paths for the complete palindrome, we can simplify the teaser by considering only paths from the central W to the outer S’s. If there are \(N\) such paths, we can then form the full palindrome by combining each of these paths with the \(N\) reverse paths back to the outer S’s, giving \(N^2\) paths in total.

Since the grid is is horizontally and vertically symmetric, we can further simplify the analysis by only considering its upper left quadrant. At each of the 13 steps from the central W to the outer S’s in this quadrant we can choose to move either up or left, which means that there are \(2^{13}\) paths in total. And since there are four quadrants, there are a total of \(4.2^{13}\) paths in the full grid. But the two horizontal and two vertical paths have been counted twice (since they are each in two quadrants) so we have to reduce the count by 4, giving \(4(2^{13} – 1)\) paths in total – 32764 paths.

As discussed earlier we have to square this result to find the number of paths for the full palindrome, giving a total of 1,073,479,696 paths.

]]>