I have a problem with my C# project.
Suppose I have a textbox1 as follow (n rows x n columns):
0 1 0 1 0 1 0 1
0 0 0 0 0 0 0 0
0 0 0 1 0 0 0 0
1 0 0 0 0 0 0 1
0 0 0 0 0 0 0 0
Now I want to transfer data from this text box into an existed 2d Matrix that will store data in Integer Type.
I tried this but it seem to not works:
private void GETNUMERICDATA()
{
string txt = textbox1.text;
txt = txt.Replace(" ", string.Empty);
for (int k = 0; k < 32; k++)
{
for (int l = 0; l < 32; l++)
{
for (int i = 0; i < txt.Length; i++)
{
char chr = txt[i];
if (chr == '0')
{
Matrix[k, l] = (int)char.GetNumericValue('0');
}
else
{
if (chr == '1')
Matrix[k, l] = (int)char.GetNumericValue('1');
}
}
}
}
}
How do I do it?
The problem is the third loop over the input. You loop through the whole input every time. The result is, that after all loops have finished, the array will contain only the last value of your input. Try this:
private void GETNUMERICDATA()
{
int currentPosition = 0;
string txt = textbox1.text;
txt = txt.Replace(" ", string.Empty);
for (int k = 0; k < 32 && currentPosition < txt.Length; k++)
{
for (int l = 0; l < 32 && currentPosition < txt.Length; l++)
{
char chr = txt[currentPosition];
if (chr == '0')
{
Matrix[k, l] = (int)char.GetNumericValue('0');
}
else if (chr == '1')
{
Matrix[k, l] = (int)char.GetNumericValue('1');
}
currentPosition++;
}
}
}
It's solved. Just modify in txt;
private void GETNUMERICDATA()
{
int currentPosition = 0;
string txt = textbox1.text;
txt = txt.Replace(" ", string.Empty);
txt = txt.Replace(Environment.Newline, string.Empty);
//Just add this code line
for (int k = 0; k < 32 && currentPosition < txt.Length; k++)
{
for (int l = 0; l < 32 && currentPosition < txt.Length; l++)
{
char chr = txt[currentPosition];
if (chr == '0')
{
Matrix[k, l] = 0;
}
else if (chr == '1')
{
Matrix[k, l] = 1;
}
currentPosition++;
}
}
}
Thanks all for your helping! Have a nice day.
Related
I have a grid which, you can see in the image. Firstly, I needed to find how many different connections of letter 'u' are there. I used a youtube explanation video where they talked about Number Of Islands from LeetCode. Using +- same strategy I found that there's 2 different connections of letter 'u'. The first connection contains 22 letter 'u' and the second connection contains 14 letter 'u'. My Output shoud look like this 2 (Different connections, which I already found), 22(dont have this), 14(dont have this
InPut1 :
Input1 data
6 and 15 are dimensions.
OutPut1 :
2
22
14
InPut2 :
Input2 data
OutPut2 :
1
5
Now , I need to write an algorithm to calculate how many 'u' letters does each connection has. For example the first connection (In Input1 photo it's colored red) has 22 letter 'u' connected to each other. The second connection (In Input1 photo it's colored pink) has 14 letter 'u' connected to each other.
Also, I can't use linq.
In this code you can see that I already found that there are 2 different connections.
I also wrote a code to find how many letters 'u' does each connection contains method called : public static int CountLetterUInConnection(char[][] grid), but it doesn't work.
Maybe someone can spot my mistake and show me the right way? Or maybe I'm doing it all wrong and I need to redo it?
public partial class WebForm1 : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string path = "App_Data/Map.txt";
string[] lines = File.ReadAllLines(HttpContext.Current.Server.MapPath(path));
int Width = int.Parse(lines[0]);
int Height = int.Parse(lines[1]);
Label4.Text = "Width: " + Width.ToString();
Label5.Text = "Height: " + Height.ToString();
for (int i = 2; i < lines.Length; i++)
{
var newRow = new TableRow();
var newCell = new TableCell();
newCell.Text = lines[i];
newRow.Cells.Add(newCell);
Table1.Rows.Add(newRow);
}
}
protected void Button1_Click(object sender, EventArgs e)
{
string path = "App_Data/Map.txt";
string map = File.ReadAllText(HttpContext.Current.Server.MapPath(path));
char[][] grid = GetGridGFromMap(map);
int NumberOfMoles = TaskUtils.LettersIsU(grid);
int Count = TaskUtils.CountLetterUInConnection(grid);
// Label1.Text = "Cave count: " + NumberOfMoles.ToString();
Label1.Text = Count.ToString();
}
protected void TextBox1_TextChanged(object sender, EventArgs e)
{
}
protected void TextBox2_TextChanged(object sender, EventArgs e)
{
}
private char[][] GetGridGFromMap(string map)
{
string[] lines = map.Split('\n');
char[][] grid = new char[lines.Length][];
for(int i =0; i < lines.Length; i++)
{
grid[i] = lines[i].ToCharArray();
}
return grid;
}
}
class TaskUtils
{
public static int LettersIsU(char[][] grid)
{
int count = 0;
for (int i = 0; i < grid.Length; i++)
{
for (int j = 0; j < grid[i].Length; j++)
{
if (grid[i][j] == 'u')
{
count++;
SetCountedLetters(grid, i, j);
}
}
}
return count;
}
private static void SetCountedLetters(char[][] grid, int i, int j)
{
if (i < 0 || i >= grid.Length || j < 0 || j >= grid[i].Length || grid[i][j] == 'z')
return;
grid[i][j] = 'z';
SetCountedLetters(grid, i + 1, j);
SetCountedLetters(grid, i - 1, j);
SetCountedLetters(grid, i, j + 1);
SetCountedLetters(grid, i, j - 1);
}
public static int CountLetterUInConnection(char[][] grid)
{
int count = 0;
for (int i = 0; i < grid.Length; i++)
{
for (int j = 0; j < grid[i].Length; j++)
{
if (grid[i][j] == 'u')
{
count++;
if ((i - 1 >= 0 && grid[i - 1][j] == 'u') || (i + 1 < grid.Length && grid[i + 1][j] == 'u')
|| (j - 1 >= 0 && grid[i][j - 1] == 'u') || (j + 1 < grid[i].Length && grid[i][j + 1] == 'u'))
{
count++;
}
}
}
}
return count;
}
}`
If this were me, I'd refactor your int LettersIsU(char[][] grid) to become int[] LettersIsU(char[][] grid) whereby the length of the array is the number of contiguous groups found and each value in the array is the count in each group.
I'd do something like this:
public static int[] LettersIsU(char[][] grid)
{
int[][] found = new int[grid.Length][];
Dictionary<int, int> count = new();
void SetCountedLetters(char[][] grid, int i, int j)
{
if (i < 0 || i >= grid.Length || j < 0 || j >= grid[i].Length || found[i][j] != 0 || grid[i][j] != 'u')
return;
found[i][j] = count.Count;
count[count.Count] += 1;
SetCountedLetters(grid, i + 1, j);
SetCountedLetters(grid, i - 1, j);
SetCountedLetters(grid, i, j + 1);
SetCountedLetters(grid, i, j - 1);
}
for (int i = 0; i < grid.Length; i++)
found[i] = new int[grid[i].Length];
for (int i = 0; i < grid.Length; i++)
for (int j = 0; j < grid[i].Length; j++)
if (grid[i][j] == 'u' && found[i][j] == 0)
{
count[count.Count + 1] = 0;
SetCountedLetters(grid, i, j);
}
int[] output = new int[count.Count];
for (int k = 0; k < count.Count; k++)
output[k] = count[k + 1];
return output;
}
There is a .txt file what I have to read, compress and make an output txt for the compressed txt. Could anyone tell me what should I fix in my code?
My code:
namespace Tomorites
{
class Compression
{
public void Compress(char[,] source)
{
for (int i = 0; i < source.GetLength(0); i++)
{
int white = 0;
int red = 0;
for (int j = 0; j < source.GetLength(1); j++)
{
if (source[i, j] == 'P')
{
if (source[i, j] > 0)
{
red++;
Console.Write(red + " P ");
}
}
else if(source[i,j]=='F')
{
if (source[i, j] > 0)
{
white++;
Console.Write(white + " F ");
}
}
}
Console.WriteLine();
}
}
}
}
My console output
Source txt file
The compressed txt file which has to be
You was pretty close, but messed one important thing: reset first char counter when second char appear or second char counter when first char appear.
Also source[i, j] > 0 condition do nothing for you.
So at result we may have:
Fill source array:
static void Main(string[] args)
{
// Declare array
char[,] source = new char[7, 10];
// Fill array as at example
for (int i = 0; i < source.GetLength(0); i++)
for (int j = 0; j < source.GetLength(1); j++)
source[i, j] = i == 3 || j == 3 ? 'F' : 'P';
// Print filled array to Console
Console.WriteLine("Source:\n" + new string('-', 10));
for (int i = 0; i < source.GetLength(0); i++)
{
for (int j = 0; j < source.GetLength(1); j++)
Console.Write(source[i, j] + " ");
Console.WriteLine();
}
// Just new line
Console.WriteLine();
// Now "compress"
Console.WriteLine("Compressed:\n" + new string('-', 10));
Compress(source);
Console.ReadKey();
}
Source output:
Compress source array:
static void Compress(char[,] source)
{
// Declare counters for P and F chars
int PCount = 0, FCount = 0;
for (int i = 0; i < source.GetLength(0); i++)
{
for (int j = 0; j < source.GetLength(1); j++)
{
if (source[i, j] == 'P')
{
// If char is P - then count P's up
PCount++;
// If there was F char counted before (> 0) - print it and reset counter
if (FCount > 0)
{
Console.Write(FCount + " F ");
FCount = 0;
}
}
else if (source[i, j] == 'F')
{
// If char is P - then count F's up
FCount++;
// If there was P char counted before (> 0) - print it and reset counter
if (PCount > 0)
{
Console.Write(PCount + " P ");
PCount = 0;
}
}
}
// Before go to next "row" - print remained P or F counts and again, reset counters
if (PCount > 0)
{
Console.Write(PCount + " P ");
PCount = 0;
}
else if (FCount > 0)
{
Console.Write(FCount + " F ");
FCount = 0;
}
// Go new "row"
Console.WriteLine();
}
}
Compressed output:
UPD.
My answer is just solution for a provided example source and example output. #Dmitry Bychenko's solution is universal, not dependent on any two specific characters so in general use I recommend his way.
You can try something like this (you can fiddle with the code):
public static string Compress(char[,] source) {
if (null == source || source.GetLength(0) <= 0 || source.GetLength(1) <= 0)
return "";
StringBuilder sb = new StringBuilder();
for (int row = 0; row < source.GetLength(0); ++row) {
if (sb.Length > 0)
sb.AppendLine();
int count = 0;
char prior = '\0';
bool left = true;
for (int col = 0; col < source.GetLength(1); ++col) {
if (count == 0 || prior == source[row, col])
count += 1;
else {
if (!left)
sb.Append(' ');
left = false;
sb.Append($"{count} {prior}");
count = 1;
}
prior = source[row, col];
}
if (!left)
sb.Append(' ');
sb.Append($"{count} {prior}");
}
return sb.ToString();
}
Demo:
char[,] test = new char[,] {
{'a', 'a', 'a', 'a'},
{'a', 'b', 'c', 'c'},
};
Console.WriteLine(Compress(test));
Outcome:
4 a
1 a 1 b 2 c
What I would like to do is as I take input from user, insert that input into the array in a sorted order, eg. user inputs 22,3,9,10,33
output would be: 3,9,10,22,33.
The code I have below is working except for the fact that for the last element being added is at the wrong index. This was a test for school(which is why the array is 50 elements big and theres a whole class with getters and setters & lack of error checking) and I'm trying to see where I'm going wrong, I've tried both insertion and selection sort which both produce this result. From my understanding, it should be forty five consecutive zeros and then my elements in ascending order.
eg) This is the output I get(wether i use selection or insertion sort after calling my print method
Sorted Array: 0 0 0 0 33 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 0 0 0 0 0 0 0 0 0 0 3 9 10 22
public class test
{
private int [] arr;
private int maxSize;
private int numItems;
public test(int maxSize)
{
this.maxSize = maxSize;
numItems = 0;
arr = new int[maxSize];
}
public bool addItem(int key)
{
if (numItems < maxSize)
{
selectionSort(key);
arr[numItems] = key;
numItems++;
return true;
}
return false;
}
public bool insertionSort(int key)
{
int n = arr.Length - 1;
for (int i = 1; i < n; i++)
{
key = arr[i];
int j = i - 1;
while(j>=0 && arr[j] > key)
{
arr[j+1] = arr[j];
j --;
}
arr[j + 1] = key;
}
return true;
}
public bool selectionSort(int key)
{
int n = arr.Length - 1;
for (int i = 0; i < n; i++)
{
key = i;
for(int j = i + 1; j < n; j++)
{
if (arr[j] < arr[key])
{
key = j;
}
}
int temp = arr[key];
arr[key] = arr[i];
arr[i] = temp;
}
return true;
}
static void Main(string[] args)
{
test x = new test(50);
int count = 0;
int element;
while (count < 5)
{
Console.WriteLine("Enter an element to add into the array");
element = Convert.ToInt32(Console.ReadLine());
x.addItem(element);
count++;
}}
I found two issues with your code and these were minor.
Update addItem function to move selectionSort below the assignment operation.
public bool addItem(int key)
{
if (numItems < maxSize)
{
arr[numItems] = key;
selectionSort(key); // below the arr[numItems] assignment.
numItems++;
return true;
}
return false;
}
and in the selectionSort method, change two things.
a. for loop for j should go all the way to n and
b. break when k=j;
public bool selectionSort(int key)
{
int n = arr.Length - 1;
for (int i = 0; i < n; i++)
{
key = i;
for (int j = i + 1; j <= n; j++) // <= n instead of < n
{
if (arr[j] < arr[key])
{
key = j;
break; // break here once you have k = j.
}
}
int temp = arr[key];
arr[key] = arr[i];
arr[i] = temp;
}
return true;
}
This should take care of your issues.
i think you are looking for insertion sort here is an example.
static void Main(string[] args)
{
int[] numbers = new int[10] {22,1,34,20,12,10,5,33,11,5};
Console.WriteLine("\nOriginal Array Elements :");
Show(numbers);
Console.WriteLine("\nSorted Array Elements :");
Show(InsertionSort(numbers));
Console.ReadKey();
}
static int[] InsertionSort(int[] inputArray)
{
for (int i = 0; i < inputArray.Length - 1; i++)
{
for (int j = i + 1; j > 0; j--)
{
if (inputArray[j - 1] > inputArray[j])
{
int temp = inputArray[j - 1];
inputArray[j - 1] = inputArray[j];
inputArray[j] = temp;
}
}
}
return inputArray;
}
public static void Show(int[] array)
{
foreach (int i in array)
{
Console.Write(i.ToString() + " ");
}
}
I have two bool[5,5] arrays which look like this:
1st:
1 1 1 1 1
0 1 0 0 0
0 0 1 1 0
0 0 0 0 0
0 1 0 1 0
2nd:
0 0 0 0 1
0 1 1 1 0
0 0 0 0 0
0 0 1 1 0
1 0 0 0 0
What I have to do is simple calculating distance between 1 from 1st array and 1 from the 2nd one. I had multiple tries to solve this problem, but I can't solve this.
The result should looks like this:
4+3+2+1+0
0+0+0+0+0
0+0+0+0+0
0+0+0+0+0
0+1+0+3+0
Let me name arrays: first[,] and second[,]
There are fiew conditions:
if (first[i,j] == true && second[i,j] == true) distance[i,j] = 0
if (first[i,j] == false) distance[i,j] = 0
if (first[i,j] == true) then I have to calculate distance between closest 1 from second[,] eg. There are 1 in first[1,4] and first[3,4] and there is 1 in second[0,4] (there was mistake), so it means that distance[3,4] = 3 - 0 (because of second array's dimensions).
This is main method to calculate:
` static public int findPicture()
{
int[,] m = new int[testBitmap.GetLength(0),
testBitmap.GetLength(1)];
foreach (var picture in pictures)
{
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++)
{
if (testBitmap[i,j] == true)
{
do
{
i = i + 1;
} while (picture.Value[i,j] != true);
m[i,j] += 1;
}
}
}
var total = 0;
for (int a = 0; a < 5; a++)
{
for (int b = 0; b < 5; b++)
{
total += m[a, b];
}
}
return total;
}
return -1;
}`
It was my closest version to solve.
I would be very greatful if you could give some advices to solve this trivial problem.
I'd do something like this:
static int[,] BuildDistanceArray(bool[,] array1, bool[,] array2)
{
if (array1.GetLength(0) != array2.GetLength(0) || array1.GetLength(1) != array2.GetLength(1))
throw new Exception("Array sizes must match.");
int[,] distance = new int[array1.GetLength(0), array1.GetLength(1)];
for (int i = 0; i < array1.GetLength(0); ++i)
{
for (int j = 0; j < array1.GetLength(1); ++j)
{
distance[i, j] = array1[i, j] ? GetDistance(array2, i, j) : 0;
}
}
return distance;
}
static int GetDistance(bool[,] array, int row, int column)
{
int maxColumn = array.GetLength(1);
int distance = 0;
bool again;
do
{
again = false;
if (column - distance >= 0)
{
if (array[row, column - distance])
return distance;
again = true;
}
if (column + distance < maxColumn)
{
if (array[row, column + distance])
return distance;
again = true;
}
distance++;
} while (again);
return 0;
}
It gives the results you're looking for and it works for any size array.
This function calculates distance between 2 rows converted to int32. It's written in java, so some minor transformation will be required.
int distance(int x, int y) {
int count = Integer.bitCount(x);
int totalDist = 0;
for (int offset = 0; offset < 5 && x != 0; offset++) {
x = x ^ (x & (y << offset) & 0b11111);
x = x ^ (x & (y >>> offset));
int nextCount = Integer.bitCount(x);
totalDist += (count - nextCount) * offset;
count = nextCount;
}
return totalDist;
}
I'm converting an Eight Queens solution from Java to C# just to get my head around C# a bit more. The problem is that I'm stuck with changing values on the board. I can change the value inside the function but it goes back to what it was immediately even when I'm using ref. At the moment I'm using a global variable rather than passing the board as an argument.
Here is the code:
public static int[,] solution;
static void Main()
{
int n = 8;
solution = new int[8,8];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
solution[i,j] = 0;
}
}
Solve(n);
Console.ReadKey();
}
public static void Solve(int n)
{
if (placeQueens(0, n))
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
Console.Write(" " + solution[i,j]);
}
Console.WriteLine();
}
}
else
{
Console.WriteLine("No possible solution");
}
}
public static bool placeQueens(int queen, int n)
{
if (queen == n)
{
return true;
}
for (int row = 0; row < n; row++)
{
if (canPlace(row, queen))
{
solution[row,queen] = 1;
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
Console.Write(" " + solution[i, j]);
}
Console.WriteLine();
}
//When I print the current board here the 1 is set
//When placeQueens is called again it is back to being 0
if (placeQueens(queen + 1, n))
{
return true;
}
solution[row,queen] = 0;
}
}
return false;
}
public static bool canPlace(int row, int col)
{ //Just checks that the position is legal}
What can I do to make the 1 stay as a one once I've changed it in placeQueen?
I changed the static variable to being passed in each method instead of being a static variable, and it works perfectly:
static void Main()
{
int n = 8;
var solution = new int[8, 8];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
solution[i, j] = 0;
}
}
Solve(solution, n);
}
public static void Solve(int[,] solution, int n)
{
if (placeQueens(solution, 0, n))
{
Console.WriteLine();
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
Console.Write(" " + solution[i, j]);
}
Console.WriteLine();
}
}
else
{
Console.WriteLine("No possible solution");
}
}
public static bool placeQueens(int[,] solution, int queen, int n)
{
if (queen == n)
{
return true;
}
for (int row = 0; row < n; row++)
{
if (canPlace(solution, row, queen))
{
solution[row, queen] = 1;
Console.WriteLine();
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
Console.Write(" " + solution[i, j]);
}
Console.WriteLine();
}
if (placeQueens(solution, queen + 1, n))
{
return true;
}
solution[row, queen] = 0;
}
}
return false;
}
public static bool canPlace(int[,] solution, int row, int col)
{
for (var dx = -1; dx <= 1; dx++)
{
for (var dy = -1; dy <= 1; dy++)
{
if (dx == 0 && dy == 0)
continue;
int r = row, c = col;
while (r >= 0 && r <= solution.GetUpperBound(0) && c >= 0 && c <= solution.GetUpperBound(1))
{
if (solution[r, c] == 1)
return false;
r += dy;
c += dx;
}
}
}
return true;
}
The last line it outputs is a correct solution:
1 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0
0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1
0 1 0 0 0 0 0 0
0 0 0 1 0 0 0 0
0 0 0 0 0 1 0 0
0 0 1 0 0 0 0 0