void TestFigures()
{
var rnd = new Random();
int iterations = 1000;
for (int i = 0; i < iterations; i++)
{
var d1 = (int)Math.Floor(rnd.NextDouble() * rnd.NextDouble() * Math.Pow(10, rnd.Next(0, 5)));
var d2 = (int)Math.Floor(rnd.NextDouble() * rnd.NextDouble() * Math.Pow(10, rnd.Next(0, 5)));
double simple_multiply = d1 * d2;
double lattice_multiply = LatticeMultiplication(int.Parse(d1.ToString()), int.Parse(d2.ToString()));
Debug.Equals(simple_multiply, lattice_multiply);
}
}
private double LatticeMultiplication(int num1, int num2)
{
if (num1 == 0 && num2 == 0) return 0;
int[] num1Array = ConvertToIntArray(num1);
int[] num2Array = ConvertToIntArray(num2);
int num1arrSize = num1Array.Count();
int num2arrSize = num2Array.Count();
int[] accumulators = new int[num1arrSize + num2arrSize];
int i, j, accIndex = accumulators.Count() - 1;
for (i = 0; i < num2arrSize; i++)
{
for (j = 0; j < num1arrSize; j++)
{
int result = num1Array[j] * num2Array[i];
if (result > 9)
{
accumulators[accIndex] += result % 10;
int tenth = accumulators[accIndex];
if (tenth > 9)
{
accumulators[accIndex] = tenth % 10;
accumulators[accIndex - 1] += tenth / 10;
}
accumulators[accIndex - 1] += result / 10;
tenth = accumulators[accIndex - 1];
if (tenth > 9)
{
accumulators[accIndex - 1] = tenth % 10;
accumulators[accIndex - 2] += tenth / 10;
}
}
else
{
accumulators[accIndex] += result;
int tenth = accumulators[accIndex];
if (tenth > 9)
{
accumulators[accIndex] = tenth % 10;
accumulators[accIndex - 1] += tenth / 10;
}
}
accIndex--;
}
accIndex = accumulators.Count() - 2 - i;
}
return double.Parse(string.Join("", accumulators.Select(n => n.ToString()).ToArray()));
}
private int[] ConvertToIntArray(int num)
{
List<int> listOfInts = new List<int>();
while (num > 0)
{
listOfInts.Add(num % 10);
num = num / 10;
}
return listOfInts.ToArray();
}
// Main Multiplication Function
private int LatticeMultiplication(int num1, int num2)
{
// Create integer list for total number.
List<int> total = new List<int>();
if (num1 != 0 && num2 != 0) // Proceed if no zeroes.
{
// Convert numbers to linear arrays and then to a matrix.
int[] num1Array = ConvertToIntArray(num1);
int[] num2Array = ConvertToIntArray(num2);
string[,] mLattice = ConvertToMatrix(num1Array, num2Array); // String preserves zeroes.
// Set x/y coordinates.
int wall = num1Array.Count() - 1; // Right side of matrix.
int floor = num2Array.Count() - 1; // Bottom of matrix.
int ceiling = 0; // Top of matrix.
int door = 0; // Left side of matrix.
int xPos = floor;
int yPos = wall;
int tempX = floor;
int tempY = wall;
int sum = 0;
int carry = 0;
bool isFirst = false;
// Transverse bottom diagonals.
while (yPos > door - 1)
{
// Reset temporary values.
tempX = xPos;
tempY = yPos;
isFirst = false;
sum = carry;
while (tempX >= ceiling && tempY <= wall)
{
if (isFirst == false)
{
sum += GetValue(mLattice[tempX, tempY], 1); // Get first or second number.
isFirst = true; // Set alternate.
tempY++; // Set next diagonal position.
}
else
{
sum += GetValue(mLattice[tempX, tempY], 0);
isFirst = false;
tempX--;
}
}
// Check for tenths spot and add ones to total.
if (sum > 9)
{
carry = GetValue(sum.ToString(), 0);
total.Add(GetValue(sum.ToString(), 1));
}
else
{
total.Add(GetValue(sum.ToString(), 0));
}
// Move left to next diagonal.
yPos--;
}
// Reset values for left side diagonals.
xPos = floor;
yPos = door;
sum = 0;
// Transverse left diagonals.
while (xPos > ceiling - 1)
{
// Reset temporary values.
tempX = xPos;
tempY = yPos;
isFirst = true;
sum = carry;
while (tempX >= ceiling && tempY <= wall)
{
if (isFirst == false)
{
sum += GetValue(mLattice[tempX, tempY], 1);
isFirst = true;
tempY++;
}
else
{
sum += GetValue(mLattice[tempX, tempY], 0);
isFirst = false;
tempX--;
}
}
if (sum > 9)
{
carry = GetValue(sum.ToString(), 0);
total.Add(GetValue(sum.ToString(), 1));
}
else
{
carry = 0;
total.Add(GetValue(sum.ToString(), 0));
}
// Move up to next diagonal.
xPos--;
}
// Return a joined final value using LINQ.
return Convert.ToInt32(string.Join("", total.Select(n => n.ToString()).ToArray().Reverse()));
}
// Return if zer
return 0;
}
// Main Multiplication Subfunctions
// Convert integer numbers to a split array.
private int[] ConvertToIntArray(int num)
{
List<int> numArray = new List<int>();
// Add digits one by one by looking at mod result.
while(num > 0)
{
numArray.Add(num % 10);
num = num / 10;
}
// Reverse array.
numArray.Reverse();
return numArray.ToArray();
}
// Convert arrays to matrix.
private string[,] ConvertToMatrix(int[] num1Array, int[] num2Array)
{
// Establish given array sizes.
int arr1Size = num1Array.Count();
int arr2Size = num2Array.Count();
// Establish array length.
string[] multiplied = new string[arr1Size * arr2Size];
int index = 0;
// Create single array of multiplied numbers.
for (int i = 0; i < arr2Size; i++)
{
for (int j = 0; j < arr1Size; j++)
{
// Multiply numbers and format with a zero if a single digit.
multiplied[index] = (num2Array[i] * num1Array[j]).ToString("00");
index++;
}
}
// Create matrix.
string[,] matrix = new string[arr2Size, arr1Size];
// Add values to matrix.
for (int i = 0; i < multiplied.Count(); i++)
{
matrix[i / arr1Size, i % arr1Size] = multiplied[i];
}
return matrix;
}
private int GetValue(string m, int index)
{
return Convert.ToInt32(m.Substring(index, 1)); // Return number according to index.
}
If you are experiencing a similar issue, please ask a related question
Title | # Comments | Views | Activity |
---|---|---|---|
ASCX file or a newer alternative? | 1 | 36 | |
Firing an ASP.NET event on selection of a JQuery datepicker | 4 | 20 | |
How to design the database - Asp.net mvc code first entity framework | 1 | 40 | |
SQL Query Help Top 1 and Distinct? | 6 | 26 |
Join the community of 500,000 technology professionals and ask your questions.