In a square matrix of even dimension s
there are s/4(s/2+1)
types of squares which can be reflected seven different ways around the matrix. For example, a 10 x 10 matrix has the unique squares colored in the figure below:
These 15 squares can be reflected around the horizontal, vertical and diagonal axes of the matrix in 7 different ways.
Assuming there are unique values assigned to each type of such element of an n x n array where n is an even number, what is the most efficient way to populate the matrix (in C or Java)? In other words, given a list of 15 values in any structure you wish, you need to populate the rest of the 10 x 10 array with the 15 values by reflections. What is the fastest algorithm to do this?
As an example, here is my first try at this (note that it uses one-based arrays):
public static int[][] valueSquare = new int[11][11];
public static int[][] valueSquareType = {
{ 0, 40, 2, 12, 15, 20 },
{ 0, 2, 1, 4, 8, 12 },
{ 0, 12, 4, 25, 20, 15 },
{ 0, 15, 8, 20, 22, 18 },
{ 0, 20, 12, 15, 18, 0 },
};
static {
for( int x = 1; x <= 5; x++ ) for( int y = 1; y <= 5; y++ ) valueSquare[ 11 - x ][ y ] = valueSquareType[x][y];
for( int x = 1; x <= 5; x++ ) for( int y = 1; y <= 5; y++ ) valueSquare[ 11 - x ][ 11 - y ] = valueSquareType[x][y];
for( int x = 1; x <= 5; x++ ) for( int y = 1; y <= 5; y++ ) valueSquare[ x ][ 11 - y ] = valueSquareType[x][y];
}
One objection to this is that it has a redundant starter array which is reflected 3 ways, instead of a minimal starter array reflected 7 ways. Ideally, I would like a starter array, with just the 15 key values. Also, the looping in my try may not be the fastest approach.
Assuming this is what you mean:
Given the black area in the upper left, then we just need to iterate all elements (i, j)
in that area and compute their location in the other areas after mirroring (diagonals overlap so I marked them as gray, but the formulas consider them too and you can apply them to the given diagonal elements too):
Assuming 0-indexing
(i, j) -> (i, n - j - 1) # red area
-> (j, n - i - 1) # yellow area
-> (j, i) # teal area
-> (n - i - 1, j) # green area
-> (n - i - 1, n - j - 1) # blue area
-> (n - j - 1, n - i - 1) # pink area
-> (n - j - 1, i) # orange area
So iterate each given black element and copy it to the 7 positions in the other areas. Example:
#include <iostream>
using namespace std;
int v[6][6] = {
{ 0, 3, 2, 12, 15, 20 },
{ 0, 2, 1, 4, 8, 12 },
{ 0, 12, 4, 25, 20, 15 },
{ 0, 15, 8, 20, 22, 18 },
{ 0, 20, 12, 15, 18, 0 },
};
int main()
{
int n = 6;
// iterate given black area:
for (int i = 0; i < n / 2; ++i)
{
for (int j = i; j < n / 2; ++j)
{
v[i][n - j - 1] = v[i][j]; // copy to red
v[j][n - i - 1] = v[i][j]; // copy to yellow
v[j][i] = v[i][j]; // copy to teal
v[n - i - 1][j] = v[i][j]; // copy to green
v[n - i - 1][n - j - 1] = v[i][j]; // copy to blue
v[n - j - 1][n - i - 1] = v[i][j]; // copy to pink
v[n - j - 1][i] = v[i][j]; // copy to orange;
}
}
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
cout << v[i][j] << " ";
}
cout << endl;
}
return 0;
}
Output:
0 3 2 2 3 0
3 2 1 1 2 3
2 1 4 4 1 2
2 1 4 4 1 2
3 2 1 1 2 3
0 3 2 2 3 0
Which seems to be what you're after.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With