I'm learning how to program, I have used other languages before mainly for web, but c# is a bit hard to understand at least for me, and msdn site is so complex or I don't know to use it properly. Trying to build program that solve sudoku puzzles, I run into problem when I try to display two dimensional array in a method, getting 2 errors:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main()
{
int[,] board = new int[9, 9] {{7, 2, 5, 8, 0, 4, 9, 1, 3},
{0, 0, 0, 0, 3, 0, 0, 0, 4},
{0, 0, 0, 0, 0, 1, 8, 2, 6},
{0, 0, 9, 0, 0, 0, 0, 0, 7},
{0, 1, 0, 6, 2, 8, 0, 4, 0},
{2, 0, 0, 0, 0, 0, 5, 0, 0},
{3, 6, 8, 4, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 7, 0, 0, 0, 8},
{0, 0, 0, 0, 0, 2, 6, 9, 5}};
DisplayBoard(board);
List<int> missing = new List<int>();
List<int> present = new List<int>();
int temp = 0;
for (int i = 0; i < 1; i++)
{
for (int j = 0; j < 9; j++)
{
//Console.Write(board[i, j]);
if (board[i, j] == 0)
{
missing.Add(j);
}
else
{
present.Add(board[i, j]);
}
if (present.Count == 8)
{
for (int x = 0; x < present.Count; x++)
{
if (!present.Contains(x))
{
temp = x;
}
}
board[i, missing[0]] = temp;
}
}
//missing.ForEach(Console.WriteLine);
}
DisplayBoard(board);
}
static void DisplayBoard(int[,])
{
for (int i = 0; i < 1; i++)
{
for (int j = 0; j < 9; j++)
{
Console.Write(board[i, j]);
}
}
}
}
You didn't give name to the parameter of DisplayBoard method
static void DisplayBoard(int[,] board)
{
for (int i = 0; i < 1; i++)
{
for (int j = 0; j < 9; j++)
{
Console.Write(board[i, j]);
}
}
}
Related
I want to solve a binary Linear Problem in C# using Microsoft Solver Foundation. I don't know why I get wrong answer. The Objective Value should be 41.1 but I get 213. The value of 5 variables should be 1 and the other ones should be 0. But I get many many variables with wrong values.
The sum of each row of the matrix should be <= 1. That are my constraints, and as you see in Constraint_arr I get the right constraints.
Thanks for any help.
Define decision variables:
SolverContext context = SolverContext.GetContext();
Model model = context.CreateModel();
Decision[,] x = new Decision[name_column.Length, 7];
for (int i = 0; i < name_column.Length; i++)
{
for (int j = 0; j < 7; j++)
{
x[i, j] = new Decision(Domain.IntegerRange(0,1), "x" + i + j);
}
}
for (int i = 0; i < name_column.Length; i++)
{
for (int j = 0; j < 7; j++)
{
model.AddDecisions(x[i, j]);
}
}
Create Constraint and add it to model:
Term[] Constraint_arr = new Term[name_column.Length];
Term tempC;
int jj;
for (int i = 0; i < name_column.Length; i++)
{
tempC = 0;
for (jj= 0; jj < 7; jj++)
{
if(vars_Matrix[i,jj] == 1)
{
tempC += x[i,jj];
}
}
Constraint_arr[i] = tempC;
model.AddConstraints("constraint" + i, Constraint_arr[i] <= 1);
}
Create Objective Function:
Term objective_Func = 0;
Term tempZ;
for (int i = 0; i < name_column.Length; i++)
{
tempZ = 0;
for (int j = 0; j < 7; j++)
{
tempZ += x[i, j] * ratio[i];
}
objective_Func+= tempZ;
}
model.AddGoal("Goal", GoalKind.Maximize, objective_Func);
print the answer:
Solution solution = context.Solve(new SimplexDirective());
Report report = solution.GetReport();
for (int i = 0; i < name_column.Length; i++)
{
for (int j = 0; j < 7; j++)
{
Console.Write(x[i, j]);
}
Console.WriteLine();
}
Console.Write("{0}", report);
Console.ReadLine();
The following MiniZinc model arrives at 14 as maximum value for the objective:
set of int: rows = 1..5;
set of int: cols = 1..7;
array[rows, cols] of 0..1: vars_Matrix = [|0, 0, 1, 0, 1, 1, 1
|0, 0, 1, 1, 0, 1, 1
|0, 0, 1, 0, 0, 0, 0
|0, 0, 1, 1, 0, 1, 1
|0, 0, 0, 0, 1, 0, 0|];
array[cols] of var 0..1: c;
var int: obj;
% constraint
% obj = sum(i in rows)(
% sum(j in cols) (
% c[i] * vars_Matrix[i, j]
% )
% );
constraint
obj = sum([ sum([ c[i] * vars_Matrix[i, j] | j in cols ]) | i in rows ]);
solve maximize(obj);
Output
c = array1d(1..7, [1, 1, 1, 1, 1, 1, 1]);
obj = 14;
The same result is obtained from the following Z3py model:
from z3 import *
s = Optimize()
Rows = range(5);
Cols = range(7);
vars_Matrix = [[0, 0, 1, 0, 1, 1, 1],
[0, 0, 1, 1, 0, 1, 1],
[0, 0, 1, 0, 0, 0, 0],
[0, 0, 1, 1, 0, 1, 1],
[0, 0, 0, 0, 1, 0, 0]]
c = [Int("c" + str(i+1)) for i in Rows]
obj = Int("obj")
for i in Rows:
s.add(c[i] >= 0, c[i] <= 1)
s.add(obj == Sum( [ Sum( [ c[i] * vars_Matrix[i][j] for j in Cols ] ) for i in Rows ] ))
s.maximize(obj)
if sat == s.check():
print(s.model())
else:
print("No solution. Sorry!")
The following picture is retrieved from Wikipedia:
I haven't understood this part:
I have two questions here:
Where did they obtain [8,4,1,2] from and what did they want to tell us by that?
Take a look at cell [0, 0] whose value is 13. If I go clockwise along with its contouring values, I obtain the binary string 0010 which is 2. How does the 1st cell-value become 13?
.
enum What
{
lines, surface, both
}
class Program
{
public static void Print(int[,] data, int xn, int yn)
{
for (int j = 0; j < yn; j++)
{
for (int i = 0; i < xn; i++)
{
Console.Write(data[i,j] + ", ");
}
Console.WriteLine();
}
}
public static int[,] normalize(int[,] data, int xn, int yn)
{
for (int j = 0; j < yn; j++)
{
for (int i = 0; i < xn; i++)
{
if (data[i, j] > 1)
{
data[i, j] = 0;
}
else
{
data[i, j] = 1;
}
}
}
return data;
}
public static int[,] marching_square(int x, int y, int[,] data, int isovalue, What what)
{
int xn = x;
int yn = y;
data = normalize(data, xn, yn);
int[,] bitMask = new int[xn - 1, yn - 1];
for (int j = 0; j < yn - 1; j++)
{
for (int i = 0; i < xn - 1; i++)
{
StringBuilder sb = new StringBuilder();
sb.Append(data[i, j]);
sb.Append(data[i, j + 1]);
sb.Append(data[i + 1, j]);
sb.Append(data[i + 1, j + 1]);
bitMask[i, j] = Convert.ToInt32(sb.ToString(), 2);
}
}
return bitMask;
}
static void Main(string[] args)
{
int[,] data = new int[,] {
{ 1,1,1,1,1 },
{ 1,2,3,2,1 },
{ 1,3,3,3,1 },
{ 1,2,3,2,1 },
{ 1,1,1,1,1 }
};
Print(data, 5,5);
int[,] bitMask = marching_square(5,5,data, 0, What.lines);
Print(bitMask, 4, 4);
}
}
Output:
1, 1, 1, 1, 1,
1, 2, 3, 2, 1,
1, 3, 3, 3, 1,
1, 2, 3, 2, 1,
1, 1, 1, 1, 1,
14, 10, 10, 11,
12, 0, 0, 3,
12, 0, 0, 3,
13, 5, 5, 7,
I inverted the bits. But, the output looks different.
How find template in array ?
Template
int[] = {X, X, X}; //(example 3,3,3)
, or template
int[,] temp2 =
{
{X, X, ?}
{?, X, X}
}
Example
int[,] temp2 =
{
{3, 3, 1}
{2, 3, 3}
}
For example, in such an array?
int[,] a = new int[,]
{
{ 1, 4, 5, 3, 4 },
{ 1, 2, 3, 1, 3 },
{ 1, 1, 2, 4, 4 },
{ 4, 4, 3, 3, 3 },
{ 3, 4, 4, 5, 5 }
};
Is there a faster way than searching each cell and its neighboring cells?
If you are looking for patterns inside a bigger array, probably checking cell by cell is the only way to do it. You could do some complex optimizations for skipping the ? values and speedup a little, but I don't think it would easily work.
A sample code that should do what you asked:
// null means anything is ok, X is 0, Y is 1, Z is 2...
int?[,] temp = new int?[,]
{
{0, 0, null},
{null, 0, 0}
};
int[,] a = new int[,]
{
{ 0, 1, 1, 2, 4, 4, 1 },
{ 0, 1, 4, 4, 3, 3, 3 },
{ 0, 2, 3, 4, 4, 5, 5 }
};
int row, col;
bool success = CheckPattern(temp, a, out row, out col);
Console.WriteLine("Success: {0}, row: {1}, col: {2}", success, row, col);
and then
private static bool CheckPattern(int?[,] temp, int[,] data, out int row, out int col)
{
int rowsT = temp.GetLength(0);
int colsT = temp.GetLength(1);
int rowsD = data.GetLength(0);
int colsD = data.GetLength(1);
// Find the "maximum" value of the template (how many different
// condition are there... If there is only "X" then 1, "X", "Y" then 2,
// "X", "Y", "Z" then 3...
int max = -1;
for (int i = 0; i < rowsT; i++)
{
for (int j = 0; j < rowsT; j++)
{
if (temp[i, j] != null)
{
max = Math.Max(temp[i, j].Value, max);
}
}
}
// We save in an array the "current" values of "X", "Y", "Z", ...
int?[] values = new int?[max + 1];
for (int i = 0; i < rowsD - rowsT + 1; i++)
{
for (int j = 0; j < colsD - colsT + 1; j++)
{
Array.Clear(values, 0, values.Length);
bool success = true;
// Check the template
for (int k = 0; k < rowsT; k++)
{
for (int r = 0; r < colsT; r++)
{
if (temp[k, r] != null)
{
int? curr = values[temp[k, r].Value];
if (curr == null)
{
// If this is the first time we check this
// condition, then any value is good
values[temp[k, r].Value] = data[i + k, j + r];
}
else if (curr.Value == data[i + k, j + r])
{
// For subsequent instances we check this
// condition, then the data must have the
// value found in the previous instance
}
else
{
success = false;
break;
}
}
}
if (!success)
{
break;
}
}
if (success)
{
row = i;
col = j;
return true;
}
}
}
row = 0;
col = 0;
return false;
}
This piece of code should work even for multiple conditions "X", "Y"...
Today I wanted to write a program that solves a sudoku.
When my approach didn't quite work I resorted to a solution found here: http://www.heimetli.ch/ffh/simplifiedsudoku.html
But for some reason, I keep getting a StackOverflow Exception.
This is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace Sudoku_Solver
{
class Program
{
static void Main(string[] args)
{
MainClass _mainClass = new MainClass();
_mainClass.printSudoku();
Console.ReadLine();
}
}
class MainClass
{
private const int FieldsVertical = 3, FieldsHorizontal = 3;
private const int RowsInField = 3, ColumnsInField = 3;
Thread _sudokuSolverThread;
private int[,] Sudoko = new int[(FieldsVertical * ColumnsInField), (FieldsHorizontal * RowsInField)]{
{ 4, 0, 2, 0, 3, 0, 0, 0, 0},
{ 7, 0, 8, 0, 4, 2, 0, 9, 0},
{ 0, 0, 0, 8, 0, 5, 4, 0, 0},
{ 0, 8, 0, 0, 0, 4, 2, 0, 9},
{ 0, 9, 4, 2, 0, 6, 8, 1, 0},
{ 6, 0, 1, 7, 0, 0, 0, 3, 0},
{ 0, 0, 9, 5, 0, 3, 0, 0, 0},
{ 0, 3, 0, 4, 6, 0, 7, 0, 2},
{ 0, 0, 0, 0, 2, 0, 9, 0, 3},
};
public MainClass(){ }
private void startSudokuSolver()
{
solveSudoku(0, 0);
}
private bool solveSudoku(int row, int col)
{
if (Sudoko[row, col] != 0)
{
return next(row, col++);
}
else
{
for (int i = 0; i < ColumnsInField * RowsInField; i++)
{
if (checkColumn(i, row) && checkField(i, row, col) && checkRow(i, col))
{
Sudoko[row, col] = i;
//Thread.Sleep(10);
return next(row, col++);
}
}
Sudoko[row, col] = 0;
return false;
}
}
private bool next(int row, int col)
{
if (row == 9)
{
return false;
}
else
{
if (col == 9)
{
return solveSudoku(row++, 0);
}
else
{
return solveSudoku(row, col);
}
}
}
public void printSudoku()
{
startSudokuSolver();
for (int i = 0; i < Sudoko.GetLength(0); i++)
{
for (int x = 0; x < Sudoko.GetLength(1); x++)
{
Console.Write(Sudoko[i, x] + " ");
}
Console.Write(Environment.NewLine);
}
}
private bool checkRow(int number, int col)
{
for (int row = 0; row < FieldsVertical * RowsInField; row++)
{
if (Sudoko[row, col] == number)
{
return false;
}
}
return true;
}
private bool checkColumn(int number, int row)
{
for (int column = 0; column < FieldsHorizontal * ColumnsInField; column++)
{
if (Sudoko[row, column] == number)
{
return false;
}
}
return true;
}
int _currentFieldRow;
int _currentFieldColumn;
private bool checkField(int number, int row, int col)
{
_currentFieldRow = (row / RowsInField) * RowsInField;
_currentFieldColumn = (col / ColumnsInField) * ColumnsInField;
for (int a = _currentFieldRow; a < _currentFieldRow + RowsInField; a++)
{
for (int b = _currentFieldColumn; b < _currentFieldColumn + ColumnsInField; b++)
{
if (Sudoko[a, b] == number)
{
return false;
}
}
}
return true;
}
}
}
E.g. here
return solveSudoku(row++, 0);
the original value of row is passed to the function solveSudoku (and after that row is incremented). Change it to row + 1.
The reason for the StackOverflowException is in the next() method. Change
return solveSudoku(row, col);
to
return solveSudoku(row, ++col);
This does at least solve the StackOverflowException. Anyway, you need to enhance the algorithm further as it does not solve the complete Sudoku yet.
I have a 2D array as follows:
long[,] arr = new long[4, 4] {{ 0, 0, 0, 0 },
{ 1, 1, 1, 1 },
{ 0, 0, 0, 0 },
{ 1, 1, 1, 1 }};
I want to print the values of this array in matrix format like:
0 0 0 0
1 1 1 1
0 0 0 0
1 1 1 1
How can I do this?
You can do it like this (with a slightly modified array to show it works for non-square arrays):
long[,] arr = new long[5, 4] { { 1, 2, 3, 4 }, { 1, 1, 1, 1 }, { 2, 2, 2, 2 }, { 3, 3, 3, 3 }, { 4, 4, 4, 4 } };
int rowLength = arr.GetLength(0);
int colLength = arr.GetLength(1);
for (int i = 0; i < rowLength; i++)
{
for (int j = 0; j < colLength; j++)
{
Console.Write(string.Format("{0} ", arr[i, j]));
}
Console.Write(Environment.NewLine + Environment.NewLine);
}
Console.ReadLine();
like so:
long[,] arr = new long[4, 4] { { 0, 0, 0, 0 }, { 1, 1, 1, 1 }, { 0, 0, 0, 0 }, { 1, 1, 1, 1 } };
var rowCount = arr.GetLength(0);
var colCount = arr.GetLength(1);
for (int row = 0; row < rowCount; row++)
{
for (int col = 0; col < colCount; col++)
Console.Write(String.Format("{0}\t", arr[row,col]));
Console.WriteLine();
}
I wrote extension method
public static string ToMatrixString<T>(this T[,] matrix, string delimiter = "\t")
{
var s = new StringBuilder();
for (var i = 0; i < matrix.GetLength(0); i++)
{
for (var j = 0; j < matrix.GetLength(1); j++)
{
s.Append(matrix[i, j]).Append(delimiter);
}
s.AppendLine();
}
return s.ToString();
}
To use just call the method
results.ToMatrixString();
Here is how to do it in Unity:
(Modified answer from #markmuetz so be sure to upvote his answer)
int[,] rawNodes = new int[,]
{
{ 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0, 0, 0, 0 }
};
private void Start()
{
int rowLength = rawNodes.GetLength(0);
int colLength = rawNodes.GetLength(1);
string arrayString = "";
for (int i = 0; i < rowLength; i++)
{
for (int j = 0; j < colLength; j++)
{
arrayString += string.Format("{0} ", rawNodes[i, j]);
}
arrayString += System.Environment.NewLine + System.Environment.NewLine;
}
Debug.Log(arrayString);
}
Your can do it like this in short hands.
int[,] values=new int[2,3]{{2,4,5},{4,5,2}};
for (int i = 0; i < values.GetLength(0); i++)
{
for (int k = 0; k < values.GetLength(1); k++) {
Console.Write(values[i,k]);
}
Console.WriteLine();
}
you can do like this also
long[,] arr = new long[4, 4] { { 0, 0, 0, 0 }, { 1, 1, 1, 1 }, { 0, 0, 0, 0 }, { 1, 1, 1, 1 }};
for (int i = 0; i < arr.GetLength(0); i++)
{
for (int j = 0; j < arr.GetLength(1); j++)
{
Console.Write(arr[i,j]+" ");
}
Console.WriteLine();
}
If using a square matrix:
int[,] mat = new int[,]{{ 1, 0, 0 },{ 0, 1, 0},{ 0, 0, 1}};
int i=1;
foreach(int e in mat){
Console.Write(i%Math.Sqrt(mat.Length)==0? $"{e}\n" : e);
i+=1;
}