Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <pre><code>.......E &lt;-end ........ ........ ........ ........ ........ ........ S....... &lt;-start </code></pre> <p>Unfortunately you can't use "any standard path finding algorithm" because your paths might not be shortest-paths. You'd have to specifically use a naive search which considered all paths (depth-first or breadth-first, for example).</p> <p>However, because you don't care <em>how</em> you got to a tile, you can use a technique called <em>dynamic programming</em>. For every location (i,j), the number of ways to get there in <em>n</em> moves (let's call it <em>ways<sub>i,j</sub>(n)</em>) is:</p> <p><em>ways<sub>i,j</sub>(n) = ways<sub>i-1,j</sub>(n-1) + ways<sub>i+1,j</sub>(n-1) + ways<sub>i,j-1</sub>(n-1) + ways<sub>i,j+1</sub>(n-1) + ways<sub>i+1,j+1</sub>(n-1) + ways<sub>i-1,j+1</sub>(n-1) + ways<sub>i+1,j-1</sub>(n-1) + ways<sub>i-1,j-1</sub>(n-1)</em></p> <p>That is, the king can move from any of the adjacent squares in 1 move:</p> <p><em>ways<sub>i,j</sub>(n) = sum<sub>neighbors(i,j)</sub>(ways<sub>neighbor</sub>(n-1))</em></p> <p>Thus you'd do, for example in python:</p> <pre><code>SIZE = 8 cache = {} def ways(pos, n): r,c = pos # row,column if not (0&lt;=r&lt;SIZE and 0&lt;=c&lt;SIZE): # off edge of board: no ways to get here return 0 elif n==0: # starting position: only one way to get here return 1 if (r,c)==(0,0) else 0 else: args = (pos,n) if not args in cache: cache[args] = ways((r-1,c), n-1) + ways((r+1,c), n-1) + ways((r,c-1), n-1) + ways((r,c+1), n-1) + ways((r-1,c-1), n-1) + ways((r+1,c-1), n-1) + ways((r+1,c-1), n-1) + ways((r+1,c+1), n-1) return cache[args] </code></pre> <p>Demo:</p> <pre><code>&gt;&gt;&gt; ways((7,7), 15) 1074445298 </code></pre> <p>The above technique is called memoization, and is simpler to write than dynamic programming, because you don't need to really think about the order in which you do things. You can see the cache grow as we perform a series of larger and larger queries:</p> <pre><code>&gt;&gt;&gt; cache {} &gt;&gt;&gt; ways((1,0), 1) 1 &gt;&gt;&gt; cache {((1, 0), 1): 1} &gt;&gt;&gt; ways((1,1), 2) 2 &gt;&gt;&gt; cache {((0, 1), 1): 1, ((1, 2), 1): 0, ((1, 0), 1): 1, ((0, 0), 1): 0, ((2, 0), 1): 0, ((2, 1), 1): 0, ((1, 1), 2): 2, ((2, 2), 1): 0} &gt;&gt;&gt; ways((2,1), 3) 5 &gt;&gt;&gt; cache {((1, 2), 1): 0, ((2, 3), 1): 0, ((2, 0), 2): 1, ((1, 1), 1): 1, ((3, 1), 1): 0, ((4, 0), 1): 0, ((1, 0), 1): 1, ((3, 0), 1): 0, ((0, 0), 1): 0, ((2, 0), 1): 0, ((2, 1), 1): 0, ((4, 1), 1): 0, ((2, 2), 2): 1, ((3, 3), 1): 0, ((0, 1), 1): 1, ((3, 0), 2): 0, ((3, 2), 2): 0, ((3, 2), 1): 0, ((1, 0), 2): 1, ((4, 2), 1): 0, ((4, 3), 1): 0, ((3, 1), 2): 0, ((1, 1), 2): 2, ((2, 2), 1): 0, ((2, 1), 3): 5} </code></pre> <p>(In python, can also use a <code>@cached</code> or <code>@memoized</code> decorator to avoid having to write the entire code in the last <code>else:</code> block. Other languages have other ways to automatically perform memoization.)</p> <p>The above was a top-down approach. It can sometimes produce very large stacks (your stack will grow with <code>n</code>). If you want to be super-efficient to avoid unnecessary work, you can do a bottom-up approach, where you simulate all positions the king could be, for 1 step, 2 steps, 3 steps, ...:</p> <pre><code>SIZE = 8 def ways(n): grid = [[0 for row in range(8)] for col in range(8)] grid[0][0] = 1 def inGrid(r,c): return all(0&lt;=coord&lt;SIZE for coord in (r,c)) def adjacentSum(pos, grid): r,c = pos total = 0 for neighbor in [(1,0),(1,1),(0,1),(-1,1),(-1,0),(-1,-1),(0,-1),(1,-1)]: delta_r,delta_c = neighbor (r2,c2) = (r+delta_r,c+delta_c) if inGrid(r2,c2): total += grid[r2][c2] return total for _ in range(n): grid = [[adjacentSum((r,c), grid) for r in range(8)] for c in range(8)] # careful: grid must be replaced atomically, not element-by-element from pprint import pprint pprint(grid) return grid </code></pre> <p>Demo:</p> <pre><code>&gt;&gt;&gt; ways(0) [[1, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]] &gt;&gt;&gt; ways(1) [[0, 1, 0, 0, 0, 0, 0, 0], [1, 1, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]] &gt;&gt;&gt; ways(2) [[3, 2, 2, 0, 0, 0, 0, 0], [2, 2, 2, 0, 0, 0, 0, 0], [2, 2, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]] &gt;&gt;&gt; ways(3) [[6, 11, 6, 4, 0, 0, 0, 0], [11, 16, 9, 5, 0, 0, 0, 0], [6, 9, 6, 3, 0, 0, 0, 0], [4, 5, 3, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]] &gt;&gt;&gt; ways(4) [[38, 48, 45, 20, 9, 0, 0, 0], [48, 64, 60, 28, 12, 0, 0, 0], [45, 60, 51, 24, 9, 0, 0, 0], [20, 28, 24, 12, 4, 0, 0, 0], [9, 12, 9, 4, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0]] </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload