grid, initially completely unpopulated. We can mark squares in this grid in at least ways, such as for a grid:
Consider an
Of these grids, precisely are continuous . That is, there exists a path, using edge adjacency (no corners/diagonals) from every black square to every other black square, and there is at least one black square.
Of all grids, are continuous.
How many grids are continuous?
This section requires Javascript.
You are seeing this because something didn't load right. We suggest you, (a) try
refreshing the page, (b) enabling javascript if it is disabled on your browser and,
finally, (c)
loading the
non-javascript version of this page
. We're sorry about the hassle.
This is an exceptionally difficult Dynamic Programming problem. Brute force works well enough for N ≤ 5 , but immediately becomes intractable afterwards. What's worse, searching on OEIS only gives the answer up to N = 7 , and links to no papers or formulas! How do you count continuous grids?
One such solution is to go column by column, multiplying results. Consider, for example, the graph below:
Imgur
Suppose we only know the number of ways there are to fill the blue squares, such that the middle column appears as it is. We only need that knowledge of the middle column's appearance, in this case, to compute how many ways there are to fill the green squares - then, we can just multiply that result by the number of ways there are to fill the blue squares.
This works in any case where the middle column is just one continuous segment of black squares. If we face a situation like the one below, we need more information:
Imgur
We need to know how the segments are connected, if at all, as that will govern how we can fill out the rest of the grid. It turns out this information, the connectivity of the segments, is really easy to normalize: Consider all the connected components in the blue squares, and list them in order of height (that is, the highest y-coordinate in the middle column that they touch). Using that order, assign an identifier to each connected component, and then simply label each segment in the middle column by that identifier.
This connectivity information is all we need to keep advancing. We can consider, for any possible 'middle' column, the set of all 2 N possible 'next' columns, and for each one, compute the new connectivity state. There are, approximately, 2 1 . 5 N connectivity states, (identifiers + middle-column state), so it would take about 2 2 . 5 N operations to compute the number of ways there are to transition to any connectivity state, from any prior connectivity state. For N = 1 0 , this is on the order of 2 2 5 , which is doable.
The empty case - when the middle column is empty - is a little ugly. We could add another bit to our connectivity state, to keep track of whether we've "already built" the blob or not. Or, we could add a little bit of complexity to our counting routine at the end instead.
Let C be the set of all possible connectivity states. Let M C , C be the matrix, which defines the number of ways there are to transition from any connectivity state c 1 to c 2 , storing 0 if there are none. We can compute the total number of continuous N × N grids in the following pseudo-code manner:
The 'sumValidEndingCStates' routine merely sums the values in the given map, for where the keys yield only one identifier in the connectivity state. (Meaning that we could stop adding columns then, and what we've built so far would be fully connected).
The full algorithm runs in time O ( 2 2 . 5 N + N ⋅ ∣ M C , C ∣ ) . It turns out that M C , C is, predictably, a relatively sparse matrix, with much fewer than 2 2 . 5 N elements, and so the major runtime of the algorithm is approximately O ( 2 2 . 5 N ) .
The above routine can be examined in the main method of the source code . It can be verified that the output of the code does in fact match the OEIS sequence up through N = 7 , as well.
And running it with N = 1 0 yields the enormous result:
2 8 4 3 7 4 3 1 8 5 4 5 8 3 0 3 2 9 4 8 7 3 0 9 7 8 5