I'm trying to solve a maths problem programmatically. I have a 6x5 grid, with a few predefined numbers, and I have to find the rest of the numbers with the condition of all rows and columns should total 34.
//Grid
static int[][] sq;
static void Main(string[] args)
{
sq = new int[6][];
for (int i = 0; i < sq.Length; i++)
{
sq[i] = new int[5] { -250, -250, -250, -250, -250, };
}
SetDefaults();
Print();
Console.WriteLine("Press enter to quit...");
Console.ReadLine();
}
static void SetDefaults()
{
sq[0][0] = 7;
sq[0][1] = 6;
sq[0][2] = 8;
sq[2][2] = 9;
sq[2][3] = 8;
sq[2][4] = 5;
sq[3][1] = 9;
sq[3][3] = 7;
sq[3][4] = 5;
sq[4][0] = 4;
sq[4][1] = 4;
sq[4][4] = 9;
sq[5][0] = 8;
sq[5][2] = 3;
sq[5][3] = 6;
sq[5][4] = 8;
}
static void Print()
{
Console.WriteLine();
for (int i = 0; i<sq.Length; i++)
{
for (int ii = 0; ii < sq[i].Length; ii++)
{
Console.Write("[" + sq[i][ii] + "\t]");
}
Console.WriteLine();
}
Console.WriteLine();
}
I think one method is try all the possibilities, with a range of 500 numbers, from -250 to 250, or an incremental range (-1,1, then -2,2, etc), but I don't know how to do this programmatically and much less efficiently.
I have a 6x5 grid
The number of columns and rows is different?
Then, no matter what's in the grid, there is no solution at all to make all sums equal. Consequently there is nothing to code.
Not putting too much effort in it, but if you are really thinking of enumerating something, you could (but shouldn't) try this naive and unoptimized approach (for a range of integers between 0 and 15):
for (int a = 0; a < 16; a++) {
for (int b = 0; b < 16; b++) {
for (int c = 0; c < 16; c++) {
for (int d = 0; d < 16; d++) {
for (int e = 0; e < 16; e++) {
for (int f = 0; f < 16; f++) {
for (int g = 0; g < 16; g++) {
for (int h = 0; h < 16; h++) {
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
for (int k = 0; k < 16; k++) {
for (int l = 0; l < 16; l++) {
for (int m = 0; m < 16; m++) {
for (int n = 0; n < 16; n++) {
// test all columns and rows:
// test if 7 + 8 + 9 + a + b == 34
// test if c + d + e + f + g == 34
...
}}}}}}}}}}}}}}
Certainly possible to optimize a lot, like:
for (int a = 0; a < 16; a++) {
var b = 34 - 7 - 8 - 9 - a;
for (int c = 0; c < 16; c++) {
for (int d = 0; d < 16; d++) {
for (int e = 0; e < 16; e++) {
for (int f = 0; f < 16; f++) {
var g = 34 - c - d - e - f;
for (int h = 0; h < 16; h++) {
var i = 34 - 9 - 8 - 5 - h;
for (int j = 0; j < 16; j++) {
var k = 34 - 9 - 7 - 5 - j;
for (int l = 0; l < 16; l++) {
var m = 34 - 4 - 4 - 9 - l;
var n = 34 - 8 - 3 - 6 - 8;
// test all columns only:
// test if 7 + c + h + 4 + 8 == 34
...
}}}}}}}}
But in the end, best optimization is to return "no solution" directly.
Related
How can I write recursive function for this for loops I am making sum of this array elements.
int[,,,] exampleArray = new int[1,2,3,4];
int sum = 0;
for (int i = 0; i < 1; i++)
{
for (int j = 0; j < 2; j++)
{
for (int k = 0; k < 3; k++)
{
for (int l = 0; l < 4; l++)
{
sum += exampleArray[i, j, k, l];
}
}
}
}
Console.WriteLine(sum);
it is actually quite simple, just need a way to represent all 4 indexes as single variable:
static int recursiveSum(int[,,,] a, int index = 0)
{
int ti = index;
int l = ti % a.GetLength(3); ti /= a.GetLength(3);
int k = ti % a.GetLength(2); ti /= a.GetLength(2);
int j = ti % a.GetLength(1); ti /= a.GetLength(1);
int i = ti % a.GetLength(0); ti /= a.GetLength(0);
if (ti > 0) {
return 0;
}
return a[i, j, k, l] + recursiveSum(a, index + 1);
}
static void Main(string[] args)
{
int[,,,] exampleArray = new int[1, 2, 3, 4];
int sum = recursiveSum(exampleArray);
Console.WriteLine(sum);
}
I'm trying to solve homework for school, it concerns KMP algorithm. Here is my compute prefix function, it is suppose to output a prefix table, however all it does is every time it returns all 0s. Could help me understand what am I doing wrong? Thanks!
static int[] computePrefixFunction(string P)
{
int m = P.Length;
int[] pi = new int[m];
pi[1] = 0;
int k = 0;
for (int j = 2; j < m; j++)
{
while (k > 0 && P[k + 1] != P[j])
{
k = pi[k];
}
if (P[k+1] == P[j])
{ k = k + 1; };
pi[j] = k;
}
for (int i = 0; i < pi.Length; i++)
{
Console.WriteLine(pi[i]);
}
return pi;
}
You a have messed up indexes offsets. Here is fixed version:
static int[] computePrefixFunction(string P)
{
int m = P.Length;
int[] pi = new int[m];
int k = 0;
for (int j = 1; j < m; j++)
{
k = pi[j - 1];
while (k > 0 && P[k] != P[j])
k = pi[k-1];
if (P[k] == P[j])
k = k + 1;
pi[j] = k;
}
return pi;
}
Live demo: https://dotnetfiddle.net/YQknMp
I have a problem with NSGA. When I have 100 pop, 2 objectives, sigma_share=0.01, epsilon=0.22 and run N times with NSGA then the assigned_fitness values are not negative.
When I have above 200 pop, 2 objectives, sigma_share=0.01, epsilon=0.22 and run with N=5 or N=6 times, then the assigned_fitness and shared_fitness are negative values.
How do I fix this?
public void Compute_Assigned_fitness()
{
//Np is 200, epsilon=0.22
double Fmin = this.Np + epsilon;
double fmin_temp=Fmin;
for (int i = 0; i < Front_id.Count; i++)
{
for (int j = 0; j < Front_id[i].Front_item.Count; j++)
{
Front_id[i].Front_item[j].Assigned_fitness = Fmin - epsilon;
double niche = 0;
for (int k = 0; k < Front_id[i].Front_item.Count; k++)
{
double d = Front_id[i].Front_item[j].distances_to(Front_id[i].Front_item[k]);
if (d <= sigma_share)
{
double shd = 1 - (d / sigma_share) * (d / sigma_share);
niche += shd;
}
Front_id[i].Front_item[j].Niche = niche;
}
Front_id[i].Front_item[j].Shared_fitness = Front_id[i].Front_item[j].Assigned_fitness / niche;
niche = 0;
if (fmin_temp > Front_id[i].Front_item[j].Shared_fitness)
fmin_temp = Front_id[i].Front_item[j].Shared_fitness;
}
Fmin = fmin_temp;
}
for (int i = 0; i < Front_id.Count; i++)
{
for (int j = 0; j < Front_id[i].Front_item.Count; j++)
{
P.Add(Front_id[i].Front_item[j]);
}
}
}
enter code here
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace testing_random
{
class Program
{
static void Main(string[] args)
{
int n = 4;
int[,] a = new int[n,n];//declaring the matrix
Random o = new Random();
a[0,0] = o.Next(n);
for (int i = 1; i < n; i++)//filling the first line
{
int d = 1;
while (d != 0)
{
a[i,0] = o.Next(n);
d = 0;
for (int j = 0; j < i; j++)
if (a[i,0] == a[j,0])
d++;
}
}
for (int i = 1; i < n; i++)//filing the first column
{
int d = 1;
while (d != 0)
{
a[0, i] = o.Next(n);
d = 0;
for (int j = 0; j < i; j++)
if (a[0, i] == a[0, j])
d++;
}
}
for (int k = 1; k < n; k++)//filling the rest of the matrix
for (int i = 1; i < n; i++)
{
int d = 1;
while (d != 0)
{
a[i, k] = o.Next(n);
d = 0;
for (int j = 0; j < i; j++)
if (a[i, k] == a[j, k])
d++;
for (int j = 0; j < k; j++)
if (a[i, k] == a[i, j])
d++;
}
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
Console.Write("{0} ", a[i, j]);
Console.WriteLine();
}
Console.ReadLine();
}
}
}
The output should be a matrix of 4*4 where each column and each line contains each number once.
The problem is when i run the code, not every time i get an output, i think the problem is not every set of first line and column can give a matrix as required the i get into an unending loop.
what i want to do is limit the running time of the application to 100 ms per example,so if the matrix is not filled,the program restarts
What piece of code am i missing?
replace the while( d != 0 ) with a loop which counts up to a certain very large maximum number of iterations. (Try 1000, 100000, whatever.)
Are you trying to randomly insert numbers between 1-4 in the first line of the array? If so there is a much easier way to do it.
You can generate the 4 numbers to be inserted into the array and then just look through the first line of the array and set each value.
Random rnd = new Random();
var randomNumbers = Enumerable.Range(1, 4).OrderBy(i => rnd.Next()).ToArray();
for (int i = 0; i < n; i++)
{
a[i, 0] = randomNumbers[i];
}
I have an 1-dimensional array with random elements, got through a m*n grid. I want to find out the row total and column total, present in it.
Here is how the 1 dimensional array is:
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
I want to treat it like :
01 02 03 04 05
06 07 08 09 10
11 12 13 14 15
16 17 18 19 20
Now i want to find the reo total and column total.
Row total is done as follows:
for (int i = 0; i < totalRows; i++)
{
for (int j = 0; j < totalColumns; j++)
{
rowTotal[i] += numbers[temp + j];
}
temp += totalColumns;
}
I am trying to do the same with Column.
Here is the code:
for (int i = 0; i < totalColumns; i++)
{
tempk = 0;
for (int j = 0; j < totalRows; j++)
{
blockTotal[i] += numbers[i+j+tempk];
tempk += totalColumns;
}
}
Am not able to get the column total, as intended. Please Help.
You can get both in the same loop
for (int i = 0; i < totalRows; i++)
{
for (int j = 0; j < totalColumns; j++)
{
rowTotal[i] += numbers[i * totalColumns + j];
blockTotal[j] += numbers[i * totalColumns + j];
}
}
The easiest thing to do is to write a little method that translates a "logical" (row, col) address to an index:
int numberAt(int row, int col)
{
return numbers[row * totalColumns + col];
}
int[] colTotals = new int[totalColumns];
int[] rowTotals = new int[totalRows];
for (int row = 0; row < totalRows; ++row)
{
for (int col = 0; col < totalColumns; ++col)
{
int number = numberAt(row, col);
rowTotals[row] += number;
colTotals[col] += number;
}
}
Edit in response to question in comments below:
Here's a complete compilable example that demonstrates it working on a non-square array:
using System;
using System.Collections.Generic;
using System.Linq;
namespace Demo
{
class Program
{
// Array will 4x3 (rows x cols):
//
// 1 2 3 | 6
// 4 5 6 | 15
// 7 8 9 | 24
// 10 11 12 | 33
// ---------
// 22 26 30
int[] numbers = Enumerable.Range(1, 12).ToArray();
int totalColumns = 3;
int totalRows = 4;
int numberAt(int row, int col)
{
return numbers[row * totalColumns + col];
}
void test()
{
int[] colTotals = new int[totalColumns];
int[] rowTotals = new int[totalRows];
for (int row = 0; row < totalRows; ++row)
{
for (int col = 0; col < totalColumns; ++col)
{
int number = numberAt(row, col);
rowTotals[row] += number;
colTotals[col] += number;
}
}
Console.WriteLine("Row totals");
foreach (int rowTotal in rowTotals)
Console.Write(rowTotal + " ");
Console.WriteLine("\nCol totals");
foreach (int colTotal in colTotals)
Console.Write(colTotal + " ");
Console.WriteLine();
}
static void Main()
{
new Program().test();
}
}
}
Total by rows
for(int r = 0; r < totalRows; r++)
{
for(int c = 0; c < totalColumns; c++)
{
rowTotal[r] += numbers[r * totalColumns + c];
}
}
Total by columns
for(int c = 0; c < totalColumns; c++)
{
for(int r = 0; r < totalRows; r++)
{
colTotal[c] += numbers[r * totalColumns + c];
}
}