I need to optimize a grid by taking the number of "elements" in it and minimizing it as much as possible. When I say element, I'm referring to a section within that grid. Here's essentially what "input" could look like in a visual sense:
The first solution that comes to mind would be a flood fill algorithm, however, I have one restriction: All of the elements must have 4 sides, thus, all elements must be rectangular.
My first, limited, approach simple involved looping through the input grid element by element and checking to see if the last newly created element was the same color and had the same alpha as the element that was supposed to be created then — if so, instead of creating the new element, it would just resize the last one to extend down 1 block further.
Here is a pseudo-code example of what I'm doing:
element output_array();
element last_element = null;
for (int x = 0; x < grid_width; x++) {
for (int y = 0; y < grid_height; y++) {
color current_input_color = input_grid(x, y);
if (last_element && last_element.x === x && last_element.color === current_input_color) {
last_element.span_y++;
} else {
last_element = create_element(
x, // element.x (the x coordinate of the elements top left most grid space)
y, // element.y (the y coordinate of the elements top left most grid space)
1, // element.span_x (the number of elements to span on the x axis)
1, // element.span_y (the number of elements to span on the y axis)
curent_input_color // element.color
);
output_array.append(last_element);
}
}
}
As a result, I get this (assuming I input the previous grid into it):
So in this particular instance I've decreased the number of elements from 64 to 20.
This is good, but my "input grids" aren't normally 8x8. An example of a more realistic grid as input results in 10201 elements prior to optimization (with my current method) and 957 after.
As this method obviously relies heavily on the structure of the grid itself, these numbers can vary a great deal. My hopes are to at least minimize the elements as best I can for any given input grid.
Right now I'm approaching it from one direction (optimizing it vertically), but I would also like to optimize it horizontally. A result of such an operation doesn't have to be perfect, but here is what I envision the most optimal end grid for the first input grid:
In this case, the number of elements is reduced from 20 to just 14 - which on my larger grids could be very helpful.
I just can't seem to think of a way to utilize a flood algorithm in a way that allows me to account for every elements space in the input grid and keep all resulting elements rectangular / 4 sided.
I figured I could probably brute force it, and while CPU utilization / speed isn't the biggest of concerns, I have to run this on very large grids with thousands upon thousands of elements so wasting resources trying to brute force something on such a grand scale just isn't realistic - I don't think.