I believe an example is now in order:
If you start with a set of numbers:
1,2,3
Then shuffle them:
3,1,2
You then have an array shuffled in a single dimension, but if you have a two dimensional array where your set of numbers:
1,2,3
is repeated for each row:
1,2,3
1,2,3
1,2,3
A possible suffling of this two dimensional array could look like this:
3,1,2
1,2,3
2,3,1
The numbers are now shuffled so that each row and column is different from every other row and column and - here is the most important part - no member of the set is repeated in a row or column.
One possible way to progammatically generate a Latin Square is to use this trick - Use the first row not only as data but as the rule on how to place the values for all the rest of the rows.
I believe another example is now in order:
If you start with our shuffled set of numbers:
3,1,2
Now look at the data and say:
In the first row the 2 is in the 3rd column.
In the second row the 2 is in the 1st column.
In the third row the 2 is in the 2nd column.
3rd column, 1st column, 2nd column - thats our first row! 3,1,2!
Now rotate the first row by taking the first value and placing at the end - 1,2,3 - and do the same thing to the original data. So, lets look at the data and say:
In the first row the 3 is in the 1st column.
In the second row the 3 is in the 2nd column.
In the third row the 3 is in the 3rd column.
Rotate one last time - 2,3,1 - and do the same thing to the original data. So, lets look at the data and say one last time:
In the first row the 1 is in the 2nd column.
In the second row the 1 is in the 3rd column.
In the third row the 1 is in the 1st column.
So using the rules above we generated:
3,1,2
2,3,1
1,2,3
Here is a 9x9 array shuffled using the above trick:
3,2,6,5,9,4,1,7,8
5,6,7,8,4,2,3,1,9
8,7,1,9,2,6,5,3,4
9,1,3,4,6,7,8,5,2
4,3,5,2,7,1,9,8,6
2,5,8,6,1,3,4,9,7
6,8,9,7,3,5,2,4,1
7,9,4,1,5,8,6,2,3
1,4,2,3,8,9,7,6,5
And, here is the code that can generate Latin Squares using the above trick:
using System;
using System.Collections;
class LatinSquare
{
static void Main()
{
var LatinSquare = new int[9, 9];
var Pattern = new int[] {1,2,3,4,5,6,7,8,9};
Pattern = Shuffle(Pattern);
//Use the first row as a pattern for the rest
//of the Latin Square
for (int i = 0; i < 9; i++)
{
{LatinSquare[i,0] = Pattern[i];
}
for (int x = 0; x < 9; x++)
{
for (int y = 1; y < 9; y++)
{
LatinSquare[Pattern[y] - 1, y] =
LatinSquare[LatinSquare[x, 0] - 1, 0];
}
Pattern = RotatePattern(Pattern);
}
PrintLatinSquare(LatinSquare);
Console.Read();
}
private static T[] Shuffle(T[] OriginalArray)
{
var matrix = new SortedList();
var r = new Random();
for (int x = 0; x <= OriginalArray.GetUpperBound(0); x++)
{
int i = r.Next();
if (!matrix.ContainsKey(i))
{
matrix.Add(i, OriginalArray[x]);
}
}
var OutputArray = new T[OriginalArray.Length];
var counter = 0;
foreach (DictionaryEntry entry in matrix)
{
OutputArray[counter++] = (T)entry.Value;
}
return OutputArray;
}
private static int[] RotatePattern(int[] Pattern)
{
int temp = Pattern[0];
;for (int y = 0; y < 9 - 1; y++)
{
Pattern[y] = Pattern[y + 1];
}
Pattern[9 - 1] = temp;
return Pattern;
}
private static void PrintLatinSquare(int[,] LatinSquare)
{
//Print out the Latin Square
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
Console.Write(LatinSquare[j, i].ToString().PadLeft(3));
}
Console.WriteLine();
}
}
}
The code also available here!
No comments:
Post a Comment