Simple Program Taking Extremely Long Time To Finish [closed] - c#

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
i am trying to create minesweeper in c# to do this i create an multidimensional array and then randomly pick positions using
Random rand = new Random;
the problem comes when trying to run the code, when i run it it takes an extremely long time to finish, i suspect it is because of the while loop and the if statements, if the rand.Next keeps getting the same values it could cause the loop to run for a long time. is there something im doing that is afftecting the pseudo randomness of my numbers. code below.
after returning to this questing a while later in an attempt to make it less horrendous it is clear that the reason for the program taking so long to run lies within the
while (counter < numberOfMines)
{
if (Minefield[randomNumber1, randomNumber2] == 9)
{
counter--;
}
else
{
Minefield[randomNumber1, randomNumber2] = 9;
counter++;
}
randomNumber1 = (rand.Next(4)) + 1;
randomNumber2 = (rand.Next(4)) + 1;
}
section of the code. The reason that it was taking so long is that i was treating the while loop like a for loop and taking away from the counter when it was failing to place a mine. this is incorrect and i should have just not added to it.
using System;
class MainClass
{
static void Main(string[] args)
{
int boardSize = 5;
int numberOfMines = 25;
GenerateMinefield(boardSize,numberOfMines);
Console.ReadKey();
}
static int[,] GenerateMinefield(int boardSize, int numberOfMines)
{
int[,] Minefield = new int[boardSize + 2, boardSize + 2];
for (int i = 0; i <= boardSize; i++)
{
for (int j = 0; j <= boardSize; j++)
{
Minefield[j, i] = 0;
}
}
Random rand = new Random();
int randomNumber1 = (rand.Next(4)) + 1;
int randomNumber2 = (rand.Next(4)) + 1;
int counter = 0;
while (counter < numberOfMines)
{
if (Minefield[randomNumber1, randomNumber2] == 9)
{
counter--;
}
else
{
Minefield[randomNumber1, randomNumber2] = 9;
counter++;
}
randomNumber1 = (rand.Next(4)) + 1;
randomNumber2 = (rand.Next(4)) + 1;
}
for (int i = 0; i <= boardSize; i++)
{
for (int j = 0; j <= boardSize; j++)
{
Console.Write(Minefield[j, i]);
}
Console.WriteLine(Minefield[boardSize, i]);
}
return Minefield;
}
}

Looks like your problem is in the counter--. You're not removing a mine, you're simply failing to place a mine, so counter should be unchanged.

If I understand correctly the while loop should look something like this:
while (counter < numberOfMines)
{
if (Minefield[randomNumber1, randomNumber2] != 9)
{
Minefield[randomNumber1, randomNumber2] = 9;
counter++;
}
randomNumber1 = (rand.Next(4)) + 1;
randomNumber2 = (rand.Next(4)) + 1;
}

It looks like you're trying to do the following:
Create a minefield board of size (N+2, N+2)
Fill the interior of the board (excluding the cells on the border) randomly with a specified number of mines.
It's possible to do this in linear time (i.e. O(N)) as follows:
Create a 1D array of bools with the same number of elements as the interior of the minefield, excluding the border cells.
Fill the start of array with a number of true values equal to the number of mines that you want.
Shuffle the array - now the "mines" are in random locations.
Go through the array and for every true value set the corresponding value in the minefield to 9.
It's slightly inefficient to create a temporary array almost the same size as the minefield, but this has the advantage that it will always run in linear time.
Putting this together:
static int[,] GenerateMinefield(int boardSize, int numberOfMines, Random rng)
{
if (numberOfMines > boardSize)
throw new InvalidOperationException($"{nameof(numberOfMines)} exceeds {nameof(boardSize)}");
int[,] minefield = new int[boardSize + 2, boardSize + 2]; // Already filled with zeros.
bool[] mines = new bool[(boardSize-2)*2];
for (int i = 0; i < numberOfMines; ++i) // Set the first 'numberOfMines' to 9.
mines[i] = true;
Shuffle(mines, rng); // Now the mines are in random locations.
for (int i = 1, n = 0; i < boardSize; i++)
{
for (int j = 1; j < boardSize; j++, n++)
{
if (mines[n])
minefield[j, i] = 9;
}
}
return minefield;
}
static void Shuffle<T>(IList<T> array, Random rng)
{
for (int n = array.Count; n > 1;)
{
int k = rng.Next(n);
--n;
T temp = array[n];
array[n] = array[k];
array[k] = temp;
}
}
(That's using a standard shuffle algorithm.)
There's a better but more subtle way of doing this that doesn't require a separate array of bools. You can use the following code:
static int[,] GenerateMinefield(int boardSize, int numberOfMines, Random rng)
{
if (numberOfMines > boardSize)
throw new InvalidOperationException($"{nameof(numberOfMines)} exceeds {nameof(boardSize)}");
int[,] minefield = new int[boardSize + 2, boardSize + 2]; // Already filled with zeros.
int available = boardSize*2;
for (int i = 1, n = 0; i < boardSize; i++)
{
for (int j = 1; j < boardSize; j++, n++)
{
if (rng.NextDouble() < numberOfMines / (double)available)
{
minefield[j, i] = 9;
--numberOfMines;
}
}
}
return minefield;
}
The drawback of this approach is that it is not obvious how it works! It's also not completely evenly distributed, but I suspect that wouldn't matter for this program. See here for further discussion.

Related

Improved Selection Sort Out of Bounds Error

I have a method that is an "Improved version of Selection Sort". However, the code is not running as " temp[x] = 0;" this line gives an out of bounds of the array error. I do not want to use an ArrayList. How would I change this line to be in bounds of the array?
public static void ImprovedSelectionSort(int[] Array)
{
Stopwatch timer = new Stopwatch();
timer.Start();
int[] temp = new int[Array.Length];
for (int x = 1; x <= Array.Length; x++)
{
//OtherList.Add(0); -- what I want to do
temp[x] = 0;
}
int n = Array.Length;
int i = 0;
while (i < n)
{
int rear = 0;
int curMax = Array[i];
temp[rear] = i;
int j = i + 1;
while (j < n)
{
if (curMax < Array[j])
{
curMax = Array[j];
rear = -1;
}
if (curMax == Array[j])
{
rear = rear + 1;
temp[rear] = j;
}
j++;
}
int front = 0;
int p = Array[temp[front]];
while (front <= rear)
{
int temporary = p;
Array[temp[front]] = Array[i];
Array[i] = temporary;
i++;
front += 1;
}
}
for (int x = 1; x <= Array.Length; x++)
This is most likely the issue. The last index in an array is the length minus 1 (so, a 52-card deck goes from 0..51). Changing the "x <= Array.Length" component to "x < Array.Length" should fix the issue.
Change the <= to < in the for loop. This is a common mistake among novice devs, and not something you should sweat. But it's a good thing to keep in mind for the future.

I want to print bubblesorted array with random numbers [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
I've created an array called place and filled all 100 indexes with random numbers from 1 to 100 and run a bubblesort on the array. When I want to print out in console, it gives nothing. It's all blank. Mind, I'm pretty new to C# and programming in general, so if you can tell me why this thing doesn't print my sorted array, I'd be grateful.
static void Main(string[] args)
{
Random random = new Random();
int[] place = new int[100];
int spot = random.Next(1, 101);
for (int i = 0; i < place.Length; i++)
{
spot = random.Next(1, 101);
place[i] = spot;
}
for (int i = 0; i <= place.Length; i++)
{
for (int j = 0; j < place.Length - 1; i++)
{
if (place[j] > place[j + 1])
{
int temp = place[j + 1];
place[j + 1] = place[j];
place[j] = temp;
}
}
Console.WriteLine(place[i]);
}
Console.ReadKey();
}
You have two typos:
for (int i = 0; i < place.Length; i++) // should be <, not <= (throws exception)
{
for (int j = 0; j < place.Length - 1; j++) // should be j++ instead of i++
{
if (place[j] > place[j + 1])
{
int temp = place[j + 1];
place[j + 1] = place[j];
place[j] = temp;
}
}
Console.WriteLine(place[i]); // is it necessary?
}
Console.WriteLine();
for (int i = 0; i < place.Length; i++)
{
Console.WriteLine(place[i]);
}
I also added code that prints the whole array, to see if this sorting works (and it does).

How can I fill a 2d array recursively?

I have a string filled with 9 numbers. I want to fill a 3x3 array with the numbers. I've managed to do it using a foreach and 2 for loops, but I feel this is quite messy. How can I modify my code to recursively enter the values into the array? This is my code currently:
int[,] matrix = new int[3, 3];
if(key.Length < 9 || key.Length > 9)
{
keyfield.GetComponent<InputField>().text = " Key Not Valid";
}
else
{
foreach(char c in key)
{
for (int k = 0; k < 3; k++)
{
for (int j = 0; j < 3; j++)
{
matrix[j, k] = c - 0;
}
}
}
}
Note, I'm working with Unity.
Well, just iterate over the chars in your key and assign them to the array, one field at a time. It's just a matter of calculating the correct columns and rows:
for (int i = 0; i < 9; ++i)
{
int row = i / 3;
int col = i % 3;
matrix[row, col] = (int)key[i];
}
Also note that neither the code in your question nor the code in my answer solves the problem in a recursive way. Recursion is given when a method calls itself directly or indirectly, which is not required to solve this particular problem.

Function not returning array

I have this function to initiate a two dimensional array:
static Array Matrix(int Rows, int Columns)
{
int[,] LotteryArray = new int[Rows,Columns];
for (int i = 0; i < LotteryArray.GetLength(0); i++)
{
for (int j = 0; j < LotteryArray.GetLength(1); j++)
{
LotteryArray[i, j] = RandomNum(1, 46);
Console.Write("{0,3},", LotteryArray[i, j]);
}
Console.WriteLine();
}
return LotteryArray;
}
Then I have this which is supposed to give me a one dimensional array and see how many numbers in the winning array are in the matrix:
int RowNum = 1;
int Prediction = 0;
Console.WriteLine("Your winning numbers are!");
Console.WriteLine("------------------------");
int[] Winner = new int[6];
for (int i = 0; i < Winner.Length; i++) //this loop is to initiate and print the winning numbers
{
Winner[i] = RandomNum(1, 46); //the numbers are supposed to be between 1 and 45, so i tell it to do it until 46 because the upper limit is exclusive
Console.Write("{0,3},", Winner[i]);
}
Console.WriteLine();
Console.WriteLine("------------------------"); //these two lines are for aesthetics
Matrix(Rows, Columns);
foreach (int i in Winner)
{
for (int j = 0; j<LotteryArray; j++)
{
if (Winner[i] == j)
{
Prediction++;
if (j % 6 == 0) { RowNum++; }
}
Console.WriteLine("you got {0} correct prediction in row number {1}",Prediction,RowNum);
RowNum = 1;
}
}
It's telling me LotteryArray doesn't exist in the current context.
LotteryArray is a variable within another method. You cannot access it in the scope you are showing.
You can do get the return from your method into a variable and then use it.
var LotteryArray = Matrix(Rows, Columns);
foreach (int i in Winner)
{
for (int j = 0; j<LotteryArray; j++)
{
if (Winner[i] == j)
{
Prediction++;
if (j % 6 == 0) { RowNum++; }
}
Console.WriteLine("you got {0} correct prediction in row number {1}",Prediction,RowNum);
RowNum = 1;
}
}
LotteryArray is a variable declared in Matrix method, and is not visible outside.

Printing a 2D-array into "squares"

I'm trying to learn how to work with 2D-array and I can't seem to understand how to print them correctly. I want to print them in a "square" like 5x5 but all I get is one line. I've tried both WriteLine and Write and changed some of the variables in the loops but I get either an error or not the result I want to have. The code is supposed to print out a 5x5 with a random sequence of 15 numbers in each column. I get the correct numbers out of it, it's only the layout that is wrong.
static void Main(string[] args)
{
Random rnd = new Random();
int[,] bricka = new int[5, 5];
int num = 0;
int num1 = 1;
for (int i = 0; i < bricka.GetLength(1); i++)
{
num += 16;
for (int j = 0; j < bricka.GetLength(0); j++)
{
bricka[j, i] = rnd.Next(num1, num);
}
num1 += 16;
}
for (int i = 0; i < bricka.GetLength(0); i++)
{
for (int j = 0; j < bricka.GetLength(1); j++)
{
Console.Write(bricka[i, j]+ " " );
}
}
Console.ReadKey();
}
This is my print, I would like to have the the 12 under the 8 and 14 under the 12 and so on.
http://i.imgur.com/tfyRxf1.png
You need to call WriteLine() after each line, so that each line is printed on a separate line:
for (int i = 0; i < bricka.GetLength(0); i++)
{
for (int j = 0; j < bricka.GetLength(1); j++)
{
Console.Write(bricka[i, j]+ " " );
}
Console.WriteLine();
}
That would be one way of doing it, anyway.

Categories

Resources