Loop around an array - c#

Let's say I have an Array:
arr[3]={0,1,2};
and I am generating a Random value:
int r = Random.Range(0,4);
And in my code just after that I want to use:
print(arr[r-1]+arr[r]+arr[r+1]);
In this case it will only work if arr[r] is 1, because if r=0 then r-1 will be -1 , what can I do so if I increment the last index, it goes back to a certain point?
So that if r=2, so arr[r]=2, arr[r+1]=0 , and arr[r+4] is also 0 because it did an extra loop.
I know I could use ifs, if r=0 then r-1=3 but it's less than ideal.
Thanks

Here's something that I think you can work with:
var random = new Random();
var arr = new [] { 0, 1, 2 };
for (var i = 0; i < 20; i++)
{
int r = random.Next(1, 1 + arr.Length);
Console.WriteLine(String.Join(", ", (r - 1) % 3, r % 3, (r + 1) % 3));
}
That produces:
1, 2, 0
2, 0, 1
2, 0, 1
1, 2, 0
2, 0, 1
2, 0, 1
1, 2, 0
1, 2, 0
2, 0, 1
1, 2, 0
1, 2, 0
1, 2, 0
2, 0, 1
1, 2, 0
1, 2, 0
1, 2, 0
0, 1, 2
1, 2, 0
1, 2, 0
0, 1, 2

You can try modulus %. I'm not too sure if the operation will always return a positive value, but you can always do r = random.range(3,7);, and then use r-1 % 3 etc.

Related

My sudoku solving program always returning unsolved grid

My program uses backtracking for solving sudoku puzzles. Below is my full code of the class. In this puzzle I am expecting two results. In the solve() function there I print the grid just to verify it works, which works and all fields are correctly used. The problems begin, where I need my program to save the grid at that point into the solvedGrids list. Where I then just in the solveSudoku() function (which is run from Main()) just print every grid in the list, but it returns the unsolved grid. I don't know why it does that, because where I first print the grid it does it correctly. (print() and print2() are the same, the print2() looks better). But when I try to add it in a list all progress goes to a loss. Below will also be an example of what I get after running the program and the Program.cs file
Solver.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace SudokuConsole
{
public class Solver
{
private int[][] grid;
private int[][] grid2;
private List<int[][]> solvedGrids;
public Solver()
{
grid = new int[9][];
grid[0] = new int[] { 5, 3, 0, 0, 7, 0, 0, 0, 0 };
grid[1] = new int[] { 6, 0, 0, 1, 9, 5, 0, 0, 0 };
grid[2] = new int[] { 0, 9, 8, 0, 0, 0, 0, 6, 0 };
grid[3] = new int[] { 8, 0, 0, 0, 6, 0, 0, 0, 3 };
grid[4] = new int[] { 4, 0, 0, 8, 0, 3, 0, 0, 1 };
grid[5] = new int[] { 7, 0, 0, 0, 2, 0, 0, 0, 6 };
grid[6] = new int[] { 0, 6, 0, 0, 0, 0, 2, 8, 0 };
grid[7] = new int[] { 0, 0, 0, 4, 1, 9, 0, 0, 5 };
//grid[8] = new int[] { 0, 0, 0, 0, 8, 0, 0, 7, 9 };
grid[8] = new int[] { 0, 0, 0, 0, 8, 0, 0, 0, 0 };
solvedGrids = new List<int[][]>();
}
public void print()
{
Console.Write("[");
for (int x = 0; x < grid.Length; x++)
{
Console.Write("[");
for (int y = 0; y < grid[x].Length; y++)
{
Console.Write(grid[x][y]);
if (y + 1 < grid[x].Length)
Console.Write(", ");
}
Console.Write("]");
if (x + 1 < grid.Length)
Console.Write(", ");
}
Console.Write("]\n");
}
public void print2(int[][] grid2)
{
Console.Write("[");
for (int x = 0; x < grid2.Length; x++)
{
if (x != 0)
Console.Write(" ");
Console.Write("[");
for (int y = 0; y < grid2[x].Length; y++)
{
Console.Write(grid2[x][y]);
if (y + 1 < grid2[x].Length)
Console.Write(" ");
}
Console.Write("]");
if (x + 1 < grid2.Length)
Console.Write("\n");
}
Console.Write("]\n");
}
public bool possible(int y, int x, int n)
{
for (int i = 0; i < 9; i++)
{
if (grid[y][i] == n)
return false;
}
for (int i = 0; i < 9; i++)
{
if (grid[i][x] == n)
return false;
}
double x0d = x / 3;
double y0d = y / 3;
int x0 = (Convert.ToInt32(Math.Floor(x0d))) * 3;
int y0 = (Convert.ToInt32(Math.Floor(y0d))) * 3;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
if (grid[y0 + i][x0 + j] == n)
return false;
}
}
return true;
}
public void solve()
{
for (int y = 0; y < 9; y++)
{
for (int x = 0; x < 9; x++)
{
if (grid[y][x] == 0)
{
for (int n = 1; n < 10; n++)
{
if (possible(y, x, n))
{
grid[y][x] = n;
solve();
grid[y][x] = 0;
}
}
return;
}
}
}
print(); //Here I print, just to see that it works.
solvedGrids.Add(grid); //Adding the solved grid to the list
}
public void solveSudoku()
{
solve();
foreach (int[][] x in solvedGrids)
{
print2(x); //Printing out the solved grid.
}
}
}
}
Program.cs
using System;
namespace SudokuConsole
{
internal class Program
{
static void Main(string[] args)
{
Solver solver = new Solver();
solver.solveSudoku();
}
}
}
And here is what I get:
[[5, 3, 4, 6, 7, 8, 1, 9, 2], [6, 7, 2, 1, 9, 5, 3, 4, 8], [1, 9, 8, 3, 4, 2, 5, 6, 7], [8, 5, 9, 7, 6, 1, 4, 2, 3], [4, 2, 6, 8, 5, 3, 9, 7, 1], [7, 1, 3, 9, 2, 4, 8, 5, 6], [9, 6, 1, 5, 3, 7, 2, 8, 4], [2, 8, 7, 4, 1, 9, 6, 3, 5], [3, 4, 5, 2, 8, 6, 7, 1, 9]]
[[5, 3, 4, 6, 7, 8, 9, 1, 2], [6, 7, 2, 1, 9, 5, 3, 4, 8], [1, 9, 8, 3, 4, 2, 5, 6, 7], [8, 5, 9, 7, 6, 1, 4, 2, 3], [4, 2, 6, 8, 5, 3, 7, 9, 1], [7, 1, 3, 9, 2, 4, 8, 5, 6], [9, 6, 1, 5, 3, 7, 2, 8, 4], [2, 8, 7, 4, 1, 9, 6, 3, 5], [3, 4, 5, 2, 8, 6, 1, 7, 9]]
[[5 3 0 0 7 0 0 0 0]
[6 0 0 1 9 5 0 0 0]
[0 9 8 0 0 0 0 6 0]
[8 0 0 0 6 0 0 0 3]
[4 0 0 8 0 3 0 0 1]
[7 0 0 0 2 0 0 0 6]
[0 6 0 0 0 0 2 8 0]
[0 0 0 4 1 9 0 0 5]
[0 0 0 0 8 0 0 0 0]]
[[5 3 0 0 7 0 0 0 0]
[6 0 0 1 9 5 0 0 0]
[0 9 8 0 0 0 0 6 0]
[8 0 0 0 6 0 0 0 3]
[4 0 0 8 0 3 0 0 1]
[7 0 0 0 2 0 0 0 6]
[0 6 0 0 0 0 2 8 0]
[0 0 0 4 1 9 0 0 5]
[0 0 0 0 8 0 0 0 0]]

Solve non square linear system with Math.net

I'm trying to solve a non square linear system with Math.net.
But I get an error Matrix dimensions must agree: 3x7.
Here is some example code:
using MathNet.Numerics.LinearAlgebra;
var mBuilder = Matrix<double>.Build;
var vBuilder = Vector<double>.Build;
var A = mBuilder.DenseOfArray(new double[,]
{
{ 3, 2, 1, 5, -1, 0, 0 },
{ 2, 1, 1, 2, 0, -1, 0 },
{ 5, 1, 3, 4, 0, 0, -1 }
});
var b = vBuilder.DenseOfArray(new double[] { -3, -5, -2 });
Vector<double> x;
x = A.Solve(b);
Cleary the system has a solution (e.g. X = {0, 0, 0, 0, 3, 5, 2}).
How can I solve such a system with Math.Net?
You can not use the Matrix.Solve function with a non-square matrix because there is no inverse and no unique solutions for a rectangular matrix. Google "inverse of rectangular matrix" for explanations galore. You can use pseudoinverse however, as shown below.
var mBuilder = Matrix<double>.Build;
var A = mBuilder.DenseOfArray(new double[,]
{
{ 3, 2, 1, 5, -1, 0, 0 },
{ 2, 1, 1, 2, 0, -1, 0 },
{ 5, 1, 3, 4, 0, 0, -1 }
});
Matrix<double> b = Matrix<double>.Build.Dense(3, 1);
b[0, 0] = -3.0;
b[1, 0] = -5.0;
b[2, 0] = -2.0;
var p = A.PseudoInverse();
var x = p * b;
// verify
var o = A * x;

Copy part of 3-d array to 2-d array

Let's say I have a multidimensional array:
var arr = new double[2, 5, 5]
{
{
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 1, 1 }
},
{
{ 1, 1, 1, 1, 1 },
{ 1, 2, 2, 2, 1 },
{ 1, 2, 2, 2, 1 },
{ 1, 2, 2, 2, 1 },
{ 1, 1, 1, 1, 1 }
},
};
I want to copy 3 by 3 part of that array starting from index [1,1,1] till index [1,3,3] (all 2 values).
What is the most efficient way of doing so ? So far, I do it with a loop:
var arr2 = new int[3, 3];
int x_start = 1;
int y_start = 1;
for (int i = 0; i < arr2.GetLength(0); i++)
{
for (int j = 0; j < arr2.GetLength(1); j++)
{
arr2[i, j] = arr[1, x_start + i, y_start + j];
}
}
But I wonder if there is a more efficient way of doing it ?
poke already made the same point in their comment, but this is essentially the best way of doing this.
That’s the most efficient way to do it. You are using fast loops and only loop over those indexes you are interested in. - poke
You could possibly cache the two GetLength() calls in an integer, but I doubt that'd make any meaningful difference in performance.

How to create single dimensional, two dimensional,three dimensional as well as multi dimensional array using C#?

I am trying to keep all the combinations (5C1, 5C2, 5C3, 5C4, 5C5) of 1,2,3,4,5 into individual array. So I need to create dynamic array using for loop in c#.
Say for example,
Here n = 5 and r = 1 to 5.
if r = 1 then
My array will be single dimensional array, when r = 2 then it will be two dimensional array, when r = 3 then three dimensional, when r = 4 then four dimensional array and it will e continued up to end of 5.
My code is given below
string[] ShipArrayObj;
public frmResult( string[] ShipArray )
{
InitializeComponent();
ShipArrayObj = ShipArray;
}
private void frmResult_Load(object sender, EventArgs e)
{
string[] arr = ShipArrayObj;
int n = ShipArrayObj.Count();
for (int r = 1; r <= n; r++)
{
StoreCombination(arr, n, r);
richTextBox1.Text = richTextBox1.Text + "/";
}
}
void StoreCombination(string[] arr, int n, int r)
{
string[] data = new string[r];
createCombination (arr, data, 0, n - 1, 0, r);
}
private void createCombination(string[] arr, string[] data, int start, int end, int index, int r)
{
if (index == r)
{
int j = 0;
for (j = 0; j < r; j++)
richTextBox1.Text = richTextBox1.Text + data[j].ToString();//Where I want to set array to keep combination values
return;
}
int i = 0;
for (i = start; i <= end && end - i + 1 >= r - index; i++)
{
data[index] = arr[i];
CreateCombination(arr, data, i + 1, end, index + 1, r);
}
}
I am storing all the combination into a Rich Text Box, but want to keep into array. If anybody help me then I will be grateful to you.
If you're used to something like Java then multidimensional arrays are a little different in syntax in C#.
Here's a page describing how to do them in C#. Here's a snippet from said page:
// Two-dimensional array.
int[,] array2D = new int[,] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
// The same array with dimensions specified.
int[,] array2Da = new int[4, 2] { { 1, 2 }, { 3, 4 }, { 5, 6 }, { 7, 8 } };
// A similar array with string elements.
string[,] array2Db = new string[3, 2] { { "one", "two" }, { "three", "four" },
{ "five", "six" } };
// Three-dimensional array.
int[, ,] array3D = new int[,,] { { { 1, 2, 3 }, { 4, 5, 6 } },
{ { 7, 8, 9 }, { 10, 11, 12 } } };
// The same array with dimensions specified.
int[, ,] array3Da = new int[2, 2, 3] { { { 1, 2, 3 }, { 4, 5, 6 } },
{ { 7, 8, 9 }, { 10, 11, 12 } } };
If you're interested in different combinations of things with a fixed number of them, something like this should be all you need.
If you're interested in different combinations of things with a dynamic number of them, something like this should be all you need.
(Unless you're trying to optimize performance, it's better to be readable/expressive, generally speaking.)
You may need to consider whether or not order matters (un-ordered set vs. ordered list). I would assume it doesn't from your code (in which case sorting is good to eliminate "duplicates"), but I can't tell for sure.
Here's a good example that's easy to read and modify for variations and isn't so bad for small numbers:
// -1, 0, ..., 5
var choices = Enumerable.Range(-1, 6);
var possibleChoices =
from a in choices
from b in choices
from c in choices
from d in choices
from e in choices
select (IEnumerable<int>)new [] { a, b, c, d, e };
// Remove -1's because they represent not being in the choice.
possibleChoices =
possibleChoices.Select(c => c.Where(d => d >= 0));
// Remove choices that have non-unique digits.
possibleChoices =
possibleChoices.Where(c => c.Distinct().Count() == c.Count());
// Sort the choices to indicate order doesn't matter
possibleChoices =
possibleChoices.Select(c => c.OrderBy(d => d));
// Remove duplicates
possibleChoices =
possibleChoices.Select(c => new
{
Key = string.Join(",", c),
Choice = c
}).
GroupBy(c => c.Key).
Select(g => g.FirstOrDefault().Choice);
foreach (var choice in possibleChoices) {
Console.Out.WriteLine(string.Join(", ", choice));
}
Output:
0
1
2
3
4
0, 1
0, 2
0, 3
0, 4
1, 2
1, 3
1, 4
2, 3
2, 4
3, 4
0, 1, 2
0, 1, 3
0, 1, 4
0, 2, 3
0, 2, 4
0, 3, 4
1, 2, 3
1, 2, 4
1, 3, 4
2, 3, 4
0, 1, 2, 3
0, 1, 2, 4
0, 1, 3, 4
0, 2, 3, 4
1, 2, 3, 4
0, 1, 2, 3, 4
This is probably a little more dense to understand, hard-coded to this specific variation of combination and involves recursion but is a bit more generic/isn't hard-coded to 5 (and took 0.047s on dotnetfiddle.net instead of 0.094s). It's also completely lazy/IEnumerable.
public static void Main()
{
var possibleChoices = Choose(5);
foreach (var choice in possibleChoices) {
Console.Out.WriteLine(string.Join(", ", choice));
}
}
public static IEnumerable<IEnumerable<int>> Choose(int max)
{
var remaining = Enumerable.Range(0, max);
return ChooseRecursive(remaining, Enumerable.Empty<int>());
}
public static IEnumerable<IEnumerable<int>> ChooseRecursive(IEnumerable<int> remaining, IEnumerable<int> chosen)
{
yield return chosen;
foreach (var digit in remaining)
{
var choices = ChooseRecursive(
remaining.Where(d => d > digit),
chosen.Concat(new [] { digit })
);
foreach (var choice in choices)
{
yield return choice;
}
}
}
Output:
0
0, 1
0, 1, 2
0, 1, 2, 3
0, 1, 2, 3, 4
0, 1, 2, 4
0, 1, 3
0, 1, 3, 4
0, 1, 4
0, 2
0, 2, 3
0, 2, 3, 4
0, 2, 4
0, 3
0, 3, 4
0, 4
1
1, 2
1, 2, 3
1, 2, 3, 4
1, 2, 4
1, 3
1, 3, 4
1, 4
2
2, 3
2, 3, 4
2, 4
3
3, 4
4

Fastest algorithm to merge 2 arrays such that elements are interlocked at even intervals

Requirements:
Integer operations only (no floats)
Elements are interlocked at intervals as evenly as possible
Note:
"Intervals as evenly as possible" can be defined as having each length of intervals as close to one value as possible.
Micro-optimizations are welcome and desired.
Example inputs and outputs:
//Inputs
[ 1, 2, 3, 4, 5, 6, 7 ]
[ 10, 20, 30, 40 ]
//Correct output
[ 1, 10, 2, 20, 3, 30, 4, 5, 40, 6, 7]
//Wrong output ([5, 6, 7] is not an optimal interval)
[ 1, 10, 2, 20, 3, 30, 4, 40, 5, 6, 7]
-
//Inputs
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
[ 2, 2, 2 ]
//Correct output
[ 1, 1, 1, 3, 1, 1, 1, 3, 1, 1, 3, 1, 1]
//Wrong output (last [1] is not an optimal interval)
[ 1, 1, 1, 3, 1, 1, 1, 3, 1, 1, 1, 3, 1]
Here's my own implementation with as much optimization as I can think of for a managed language. In C++, it may be faster to use a triple XOR swap for the array pointers, but I'm not sure. It may be necessary to look at the JITed assembly to further optimize this particular code.
In the meantime, let's see if other people have better algorithms.
int[] InterlockMerge(int[] a1, int[] a2) {
var longSet = a1;
var shortSet = a2;
//Swap if a2 is longer
if (a1.Length < a2.Length){
longSet = a2;
shortSet = a1;
}
var ll = longSet.Length;
var ls = shortSet.Length;
var totalLength = ll + ls;
int[] res = new int[totalLength]; //The resulting set
int l = ll / (ls + 1); //Initial testing ratio (an int)
int li = 0; //index for longSet
int si = 0; //index for shortSet
for (int i = 0; i < totalLength; i++) {
if (l > 0) {
res[i] = longSet[li++];
l--;
continue;
}
res[i] = shortSet[si++];
l = (ll - li) / (ls - si + 1); //Recalculate the testing ratio
}
return res;
}

Categories

Resources