<p>You are given an integer <code>n</code>. You have an <code>n x n</code> binary grid <code>grid</code> with all values initially <code>1</code>&#39;s except for some indices given in the array <code>mines</code>. The <code>i<sup>th</sup></code> element of the array <code>mines</code> is defined as <code>mines[i] = [x<sub>i</sub>, y<sub>i</sub>]</code> where <code>grid[x<sub>i</sub>][y<sub>i</sub>] == 0</code>.</p>

<p>Return <em>the order of the largest <strong>axis-aligned</strong> plus sign of </em>1<em>&#39;s contained in </em><code>grid</code>. If there is none, return <code>0</code>.</p>

<p>An <strong>axis-aligned plus sign</strong> of <code>1</code>&#39;s of order <code>k</code> has some center <code>grid[r][c] == 1</code> along with four arms of length <code>k - 1</code> going up, down, left, and right, and made of <code>1</code>&#39;s. Note that there could be <code>0</code>&#39;s or <code>1</code>&#39;s beyond the arms of the plus sign, only the relevant area of the plus sign is checked for <code>1</code>&#39;s.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2021/06/13/plus1-grid.jpg" style="width: 404px; height: 405px;" />
<pre>
<strong>Input:</strong> n = 5, mines = [[4,2]]
<strong>Output:</strong> 2
<strong>Explanation:</strong> In the above grid, the largest plus sign can only be of order 2. One of them is shown.
</pre>

<p><strong class="example">Example 2:</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2021/06/13/plus2-grid.jpg" style="width: 84px; height: 85px;" />
<pre>
<strong>Input:</strong> n = 1, mines = [[0,0]]
<strong>Output:</strong> 0
<strong>Explanation:</strong> There is no plus sign, so return 0.
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>1 &lt;= n &lt;= 500</code></li>
	<li><code>1 &lt;= mines.length &lt;= 5000</code></li>
	<li><code>0 &lt;= x<sub>i</sub>, y<sub>i</sub> &lt; n</code></li>
	<li>All the pairs <code>(x<sub>i</sub>, y<sub>i</sub>)</code> are <strong>unique</strong>.</li>
</ul>

class Solution:
    def orderOfLargestPlusSign(self, n: int, mines: List[List[int]]) -> int:
        # for each square, find the largest plus constructable.
        # iterate, find the max.
        # Start from center, radiate out, or maybe doesn't matter since 
        # dynamic programming anyway.
        
        # alternately: start with all possible solutions and prune based on mines
        # each n x n has 
        #   (a) one highest possible order if n is odd: n // 2 + 1
        #   (b) four highest possible order if n is even: n // 2 + 1
        # maintain index of counts of each order, decrement for each mine

        # i. dyn prog:

        mines = {tuple(m) for m in mines}

        memos = {
            "up": [[None for _ in range(n)] for _ in range(n)],
            "down": [[None for _ in range(n)] for _ in range(n)],
            "left": [[None for _ in range(n)] for _ in range(n)],
            "right": [[None for _ in range(n)] for _ in range(n)],
        }

        def armlen(x, y, dir_):
            if not((0 <= x < n) and (0 <= y < n)):
                # out of bounds
                return 0
            if memos[dir_][x][y] is not None:
                return memos[dir_][x][y]
            if (x, y) in mines:
                memos[dir_][x][y] = 0
                return armlen(x, y, dir_)
            memos[dir_][x][y] = 1
            match dir_:
                case "up":
                    if y != 0:
                        memos[dir_][x][y] += armlen(x, y - 1, dir_)
                case "down":
                    if y != (n - 1):
                        memos[dir_][x][y] += armlen(x, y + 1, dir_)
                case "left":
                    if x != 0:
                        memos[dir_][x][y] += armlen(x - 1, y, dir_)
                case "right":
                    if x != (n - 1):
                        memos[dir_][x][y] += armlen(x + 1, y, dir_)
            return armlen(x, y, dir_)

        max_order = 0
        
        for i in range(n):
            for j in range(n):
                if (i, j) in mines:
                    continue
                order = 1 + min(
                    armlen(i-1, j, 'left'),
                    armlen(i+1, j, 'right'),
                    armlen(i, j-1, 'up'),
                    armlen(i, j+1, 'down'),
                )
                max_order = max(max_order, order)
        
        return max_order
        
60473