Related
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]]
I have a binary matrix 8x8 represented as an one-dimensional array
byte[] m = { 0, 1, 1, 1, 1, 0, 0, 1,
1, 1, 1, 1, 1, 0, 0, 1,
0, 1, 1, 1, 1, 0, 0, 1,
1, 1, 1, 1, 0, 0, 0, 1,
0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 1, 1, 1, 0, 0, 1,
1, 1, 1, 1, 1, 0, 0, 1,
1, 1, 1, 1, 1, 0, 0, 1 };
Is there a way how to save it in to binary file which would have total size of 8 bytes? Each 0 and 1 zero would be a 1 bit size.
You can use the following function to compress an array of 0s and 1s to an array of bytes:
IEnumerable<byte> Compress(byte[] a)
{
for (var i = 0; i < a.Length / 8f; i++)
{
var slice = a.Skip(i * 8).Take(8);
byte b = 0;
foreach (var s in slice)
{
b <<= 1;
if (s == 1)
b |= 1;
}
yield return b;
}
}
Then save to file using File.WriteAllBytes.
For example:
var result = Compress(m).ToArray();
File.WriteAllBytes(#"d:\test.bin", result);
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;
I am trying to create a two dimensional array of random 1 and 0. These will be used to switch on or off I/O lines on an Arduino. The number of arrays (height) to create will come from a textbox on the UI as will the number of items (width) in each array.
This means I do not know how many arrays I will have so what I want to do is have a loop in which I name each array e.g. a0 then a1 then a2 etc.
I have tried to name them but as you can see below have not been able to get it right. What do I need to do?
private int[][] build_data(int height, int width)
{
Random randNum = new Random();
int Min = 0, Max = 2;
var array_name = "a";
rch_txtbx.AppendText(height.ToString() + "\r");
rch_txtbx.AppendText(width.ToString() + "\r");
for (int j = 0; j <= height; j++) //create a0 to ax
{
array_name = "a" + j; //this creates the name I want
int[] a = new int[width]; //need to initialise each array in turn but how?
for (int i = 0; i <= width; i++) //create number of items in each array
{
a[i] = randNum.Next(Min, Max);
}
}
/* This is what I am trying to create arayys of random 0 and 1
int[] a1 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
int[] a2 = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
int[] a3 = { 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0 };
int[] a4 = { 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0 };
int[] a5 = { 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0 };
int[] a6 = { 0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0 };
int[] a7 = { 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0 };
int[] a8 = { 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0 };
int[] a9 = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0 };
int[] a10 = { 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0 };
int[] a11 = { 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0 };
int[] a12 = { 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 1, 1, 0 };
int[] a13 = { 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0 };
int[] a14 = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
*/
//get data ready to send back
int[][] arr = { a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14 };
return arr;
}
Instead of trying to dynamically create variables and then add them into the array just at the end of each outer loop iteration set the value of that array:
int[][] array = new int[height][];
for (int i = 0; i < height; i++)
{
int[] innerArray = new int[width];
for (int j = 0; j < width; j++)
innerArray[j] = r.Next(min, max);
array[i] = innerArray;
}
You can also replace the above for loops with Linq:
// Creates an enumerable with N
var array = Enumerable.Repeat(0, height) items
// For each item create an enumerable with M items
.Select(i => Enumerable.Repeat(0, width)
// Set the value of each inner item to a
// random number
.Select(j => r.Next(min,max))
// Convert to an array
.ToArray())
.ToArray();
You can use a multidimensional array:
int[,] random2dArray = new int[width, height];
for (int j = 0; j <= random2dArray.GetLength(0); j++)
{
for (int i = 0; i <= random2dArray.GetLength(1); i++)
{
random2dArray[j, i] = randNum.Next(Min, Max);
}
}
For more info you can look at MSDN.
According to the signature
private int[][] build_data(int height, int width)
you actually want to create an array of array int[][] (aka jagged array). You can do it quite direct:
// Simplest, but not thread-safe
private static Random s_Gen = new Random();
// static: there's no need in "this"
private static int[][] build_data(int height, int width) {
int[][] result = new int[height][];
for (int i = 0; i < result.Length; ++i) {
int[] line = new int[width];
for (int j = 0; j < line.Length; ++j)
line[j] = s_Gen.Next(2);
result[i] = line;
}
return result;
}
In case you want to have a collection of named arrays, I suggest using Dictionary<string, int[]> as a returned type:
private static Dictionary<string, int[]> build_named_data(int height, int width) {
Dictionary<string, int[]> result = new Dictionary<string, int[]>();
for (int i = 1; i <= height; ++i) {
int[] line = new int[width];
for (int j = 0; j < line.Length; ++j)
line[j] = s_Gen.Next(2);
result.Add($"a{i}", line);
}
return result;
}
....
var myData = build_named_data(15, 20);
int[] array = build_named_data["a3"];
I am not C# expert, and total LINQ beginner, having searched a bit in SO and Google without discovering how to do the following:
If I have, say, int[10,10] array, how can I get a 2D slice from it?
For example, if the values in the said array were dependent on their position (a[2,3] = 23, a[4,8] = 48, etc.), I'd like to perform the following pseudocode:
int[3,3] a_slice = slicer_method(a, 3, 6, 2, 5) // or anything equivalent to this
> [[ 32, 33, 34],
[ 42, 43, 44],
[ 52, 53, 54]]
It doesn't have specifically to use LINQ, but I've seen LINQ used in every similar operation I've come across lately.
#JaredPar is correct, there is no intrinsic way to do slices - that said, you can craft up an extension method to do so:
public static class Ext
{
public static T[] Slice<T>(this T[] source, int fromIdx, int toIdx)
{
T[] ret = new T[toIdx - fromIdx + 1];
for(int srcIdx=fromIdx, dstIdx = 0; srcIdx <= toIdx; srcIdx++)
{
ret[dstIdx++] = source[srcIdx];
}
return ret;
}
public static T[,] Slice<T>(this T[,] source, int fromIdxRank0, int toIdxRank0, int fromIdxRank1, int toIdxRank1)
{
T[,] ret = new T[toIdxRank0 - fromIdxRank0 + 1, toIdxRank1 - fromIdxRank1 + 1];
for(int srcIdxRank0=fromIdxRank0, dstIdxRank0 = 0; srcIdxRank0 <= toIdxRank0; srcIdxRank0++, dstIdxRank0++)
{
for(int srcIdxRank1=fromIdxRank1, dstIdxRank1 = 0; srcIdxRank1 <= toIdxRank1; srcIdxRank1++, dstIdxRank1++)
{
ret[dstIdxRank0, dstIdxRank1] = source[srcIdxRank0, srcIdxRank1];
}
}
return ret;
}
}
And a test:
void Main()
{
var singleArr = new int[]{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
singleArr.Slice(2, 4).Dump();
var doubleArr = new int[,]
{
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 },
};
doubleArr.Slice(2, 4, 2, 4).Dump();
}
There is no way to do this on the CLR because it doesn't support the notion of array slices. They best you can do is create a wrapper type over arrays that simulates slices
You can try something like this:
public T[,] Slice<T>(T[,] a, int x1, int y1, int x2, int y2)
{
var result = new T[x2 - x1, y2 - y1];
for (var i = x1; i < x2; i++)
{
for (var j = y1; j < y2; j++)
{
result[i - x1, j - y1] = a[i,j];
}
}
return result;
}
sample
public class MyArraySlice<T> where T:struct {
public MyArraySlice(T[,] array, int xMin, int xMax, int yMin, int yMax) {
Array = array;
XMin = xMin; XMax = xMax;
YMin = yMin; YMax = yMax;
}
public T this[int i, int j] { get {
if (XMin <= i && i < XMax && YMin <= j && j < YMax)
return Array[i+XMin, j+YMin];
throw new ArgumentOutOfRangeException();
}
}
T[,] Array;
int XMin;
int XMax;
int YMin;
int YMax;
}