2d_array random numbers (10Rows, 6 COLS) not repeated to file C# - c#

I need to streamwrite into a file.txt a 10 random numbers combinations (NOT REPEATED) like lottery program. I got everything except Non-repeated random numbers. it has to be seen (file.txt) like a 2D array with 10 combinations thx.
class Matriz
{
private int[,] array;
private int nfilas, ncols;
public void Ingresar()
{
Random aleatori = new Random();
nfilas = 10;
ncols = 6;
Console.WriteLine("\n");
array = new int[nfilas, ncols];
for (int filas = 0; filas < nfilas; filas++)
{
for (int columnas = 0; columnas < ncols; columnas++)
array[filas, columnas] = aleatori.Next(0, 50);
}
}
public void Imprimir()
{
StreamWriter fitxer = new StreamWriter(#"C:\andres\lotto649.txt");
int contador = 0;
for (int f = 0; f < nfilas; f++)
{
for (int c = 0; c < ncols; c++)
fitxer.Write(array[f, c] + " ");
fitxer.WriteLine();
contador++;
}
fitxer.WriteLine($"\n\n\tHay {contador} combinaciones de la Loteria 6/49");
fitxer.Close();
}
static void Main(string[] args)
{
Matriz array_menu = new Matriz();
array_menu.Ingresar();
array_menu.Imprimir();
}
}

Something like this should work.
Before inserting the new number in the given position, check the row thus far if the same number is already in there and if so, repeat the process until you get a number that isn't yet in there.
for (int filas = 0; filas < nfilas; filas++)
{
for (int columnas = 0; columnas < ncols; columnas++)
{
bool cont = true;
while(cont)
{
cont = false;
int newRand = aleatori.Next(0, 50);
for(int i = 0; i < columnas; i++)
if(array[filas, i] == newRand)
cont = true;
if(cont)
continue;
array[filas, columnas] = newRand;
break;
}
}
}
Alternatively, since the number is small you could also work with a list of ints and remove the given value from there.
This has the advantage, that you'll never have to redo your random number as it will always produce a valid result. The above example could (theoretically) run indefinitely long.
for (int filas = 0; filas < nfilas; filas++)
{
List<int> nums = new List<int>(49);
for(int i = 0; i < 49; i++)
nums.Add(i + 1); //num 1...49
for (int columnas = 0; columnas < ncols; columnas++)
{
int index = aleatori.Next(0, nums.Count)
array[filas, columnas] = nums[index];
nums.RemoveAt(index);
}
}

Related

Convert String[*,*] into int[*,*] in C# winform application

Hello everyone I am new to programming in c#, what I am going to do is that I want to convert the 2D string array to 2D integer array, the reason for this conversion is that I want to pass that integer array to another method for some calculation. Thanks in advance for helping.
public void Matrix()
{
int a = int.Parse(txtRowA.Text);
int b = int.Parse(txtColA.Text);
Random rnd = new Random();
int[,] matrixA = new int[a, b];
string matrixString = "";
for (int i = 0; i < a; i++)
{
for (int j = 0; j < b; j++)
{
matrixA[i, j] = rnd.Next(1, 100);
matrixString += matrixA[i, j];
matrixString += " ";
}
matrixString += Environment.NewLine;
}
txtA.Text = matrixString;
txtA.TextAlign = HorizontalAlignment.Center;
}
Your code is actually pretty close. Try this:
private Random rnd = new Random();
public int[,] Matrix(int a, int b)
{
int[,] matrixA = new int[a, b];
for (int i = 0; i < a; i++)
{
for (int j = 0; j < b; j++)
{
matrixA[i, j] = rnd.Next(1, 100);
}
}
return matrixA;
}
What you have there is a function that does not rely on any WinForms controls and will produce your int[,] quickly and efficiently.
Let the calling code work with the WinForms controls:
int a = int.Parse(txtRowA.Text);
int b = int.Parse(txtColA.Text);
int[,] matrix = Matrix(a, b);
Now you can pass the matrix to anything that requires an int[,].
If you need to display the matrix then create a separate function for that:
public string MatrixToString(int[,] matrix)
{
StringBuilder sb = new();
for (int i = 0; i < matrix.GetLength(0); i++)
{
string line = "";
for (int j = 0; j < matrix.GetLength(1); j++)
{
line += $"{matrix[i, j]} ";
}
sb.AppendLine(line.Trim());
}
return sb.ToString();
}
Your calling code would look like this:
int a = int.Parse(txtRowA.Text);
int b = int.Parse(txtColA.Text);
int[,] matrix = Matrix(a, b);
UseTheMatrix(matrix);
txtA.Text = MatrixToString(matrix);
txtA.TextAlign = HorizontalAlignment.Center;
A sample run produces:
You can use List as a helper to store the elements of the array extracted from the string, but first I replaced the SPACE between elements in your string with a special character '|' as a separator to make it easier to extract the numbers from the string.
you can do somthing like this:
public static int[,] ConvertToInt(string matrix)
{
List<List<int>> initial = new List<List<int>>();
int lineNumber = 0;
int currenctIndex = 0;
int lastIndex = 0;
int digitCount = 0;
initial.Add(new List<int>());
foreach (char myChar in matrix.ToCharArray())
{
if (myChar == '|')
{
initial[lineNumber].Add(int.Parse(matrix.Substring(lastIndex, digitCount)));
lastIndex = currenctIndex+1;
digitCount = 0;
}
else
digitCount++;
if (myChar == '\n')
{
lineNumber++;
if(currenctIndex < matrix.Length-1)
initial.Add(new List<int>());
}
currenctIndex++;
}
int[,] myInt = new int[initial.Count, initial[0].Count];
for (int i = 0; i < initial.Count; i++)
for (int j = 0; j < initial[i].Count; j++)
myInt[i, j] = initial[i][j];
return myInt;
}

Same number keeps being generated

When I try to generate a new random int each time to fill the array it just gives me back the same number. The seed won't change. I'm sure there is an easy answer but I have been looking at it for a few hours and just can't see it.
internal class LingoCard : ILingoCard
{
private ICardNumber[,] _cardNumber;
private int _teller;
private int _oddTeller;
private int rand;
Random rnd = new Random();
public LingoCard(bool useEvenNumbers)
{
ICardNumber[,] cardNumber = new ICardNumber[5,5];
_cardNumber = cardNumber;
if (useEvenNumbers == true)
{
UseEvenNumbers(_cardNumber);
} else {
UseOddNumbers(_cardNumber);
}
}
public void UseEvenNumbers(ICardNumber[,] cardNumber)
{
while (_teller < 70)
{
for (int g = 0; g < 1; g++)
{
rand = rnd.Next(0, 70);
CardNumber _walue = new CardNumber(rand);
if (rand % 2 == 0)
{
for (int i = 0; i < cardNumber.GetLength(0); i++)
{
for (int j = 0; j < cardNumber.GetLength(1); j++)
{
_cardNumber[i, j] = _walue;
}
_teller++;
}
}
}
}
}
The reason your random number is the same for all the card numbers is because you're generating one Random number before the two nested for loops and using it to fill in every card number
rand = rnd.Next(0, 70); // Random number generated once here
CardNumber _walue = new CardNumber(rand);
if (rand % 2 == 0)
{
for (int i = 0; i < cardNumber.GetLength(0); i++)
{
for (int j = 0; j < cardNumber.GetLength(1); j++)
{
_cardNumber[i, j] = _walue; // same random value assigned for every card number here
}
_teller++;
}
}
In order to fix it you'd need to generate the random number inside the for loop when you are assigning _cardNumber
for (int i = 0; i < cardNumber.GetLength(0); i++)
{
for (int j = 0; j < cardNumber.GetLength(1); j++)
{
rand = rnd.Next(0, 70) * 2; // Multiply by 2 so the random number is even
CardNumber _walue = new CardNumber(rand);
_cardNumber[i, j] = _walue;
}
_teller++;
}
Let me know if this helps!

C# how to do arithmetic operations on a 2d Array matrix

I've been toying with this code which prints a small matrix with negative and positive numbers,
I would like an efficient way to add together only the positive elements on the matrix and get the product of such elements also do the same but after a specific number, such as the highest on the matrix
static void Main(string[] args)
{
int row = 5;
int column = 5;
int[,] array = new int[row, column];
Random rand = new Random();
for (int i = 0; i < row; i++)
{
for (int j = 0; j < column; j++)
{
array[i, j] = rand.Next(-5, 10);
}
}
for (int i = 0; i < array.GetLength(0); i++)
{
for (int j = 0; j < array.GetLength(1); j++)
{
Console.Write(array[i, j].ToString() + " ");
}
Console.WriteLine(" ");
}
Console.ReadLine();
}
To filter and add positive matrix elements, you could do something like the following:
static void Main(string[] args)
{
const int rows = 5;
const int columns = 5;
var array = new int[rows, columns];
var rand = new Random();
int sum = 0;
bool numberSeen = false;
int numberToSee = 1;
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < columns; col++)
{
var cell = rand.Next(-5, 10);
if (!numberSeen && (cell == numberToSee))
{
numberSeen = true;
}
array[row, col] = cell;
if (numberSeen && (cell > 0))
{
sum += cell;
}
}
}
Console.WriteLine($"sum = {sum}");
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < columns; col++)
{
Console.Write(array[row, col].ToString() + " ");
}
Console.WriteLine(" ");
}
Console.ReadLine();
}

How can I fill array with unique random numbers with for-loop&if-statement?

I'm trying to fill one dimensional array with random BUT unique numbers (No single number should be same). As I guess I have a logical error in second for loop, but can't get it right.
P.S I'm not looking for a more "complex" solution - all I know at is this time is while,for,if.
P.P.S I know that it's a really beginner's problem and feel sorry for this kind of question.
int[] x = new int[10];
for (int i = 0; i < x.Length; i++)
{
x[i] = r.Next(9);
for (int j = 0; j <i; j++)
{
if (x[i] == x[j]) break;
}
}
for (int i = 0; i < x.Length; i++)
{
Console.WriteLine(x[i);
}
Here is a solution with your code.
int[] x = new int[10];
for (int i = 0; i < x.Length;)
{
bool stop = false;
x[i] = r.Next(9);
for (int j = 0; j <i; j++)
{
if (x[i] == x[j]) {
stop = true;
break;
}
}
if (!stop)
i++;
}
for (int i = 0; i < x.Length; i++)
{
Console.WriteLine(x[i]);
}
A simple trace of the posted code reveals some of the issues. To be specific, on the line…
if (x[i] == x[j]) break;
if the random number is “already” in the array, then simply breaking out of the j loop is going to SKIP the current i value into the x array. This means that whenever a duplicate is found, x[i] is going to be 0 (zero) the default value, then skipped.
The outer i loop is obviously looping through the x int array, this is pretty clear and looks ok. However, the second inner loop can’t really be a for loop… and here’s why… basically you need to find a random int, then loop through the existing ints to see if it already exists. Given this, in theory you could grab the same random number “many” times over before getting a unique one. Therefore, in this scenario… you really have NO idea how many times you will loop around before you find this unique number.
With that said, it may help to “break” your problem down. I am guessing a “method” that returns a “unique” int compared to the existing ints in the x array, may come in handy. Create an endless while loop, inside this loop, we would grab a random number, then loop through the “existing” ints. If the random number is not a duplicate, then we can simply return this value. This is all this method does and it may look something like below.
private static int GetNextInt(Random r, int[] x, int numberOfRandsFound) {
int currentRand;
bool itemAlreadyExist = false;
while (true) {
currentRand = r.Next(RandomNumberSize);
itemAlreadyExist = false;
for (int i = 0; i < numberOfRandsFound; i++) {
if (x[i] == currentRand) {
itemAlreadyExist = true;
break;
}
}
if (!itemAlreadyExist) {
return currentRand;
}
}
}
NOTE: Here would be a good time to describe a possible endless loop in this code…
Currently, the random numbers and the size of the array are the same, however, if the array size is “larger” than the random number spread, then the code above will NEVER exit. Example, if the current x array is set to size 11 and the random numbers is left at 10, then you will never be able to set the x[10] item since ALL possible random numbers are already used. I hope that makes sense.
Once we have the method above… the rest should be fairly straight forward.
static int DataSize;
static int RandomNumberSize;
static void Main(string[] args) {
Random random = new Random();
DataSize = 10;
RandomNumberSize = 10;
int numberOfRandsFound = 0;
int[] ArrayOfInts = new int[DataSize];
int currentRand;
for (int i = 0; i < ArrayOfInts.Length; i++) {
currentRand = GetNextInt(random, ArrayOfInts, numberOfRandsFound);
ArrayOfInts[i] = currentRand;
numberOfRandsFound++;
}
for (int i = 0; i < ArrayOfInts.Length; i++) {
Console.WriteLine(ArrayOfInts[i]);
}
Console.ReadKey();
}
Lastly as other have mentioned, this is much easier with a List<int>…
static int DataSize;
static int RandomNumberSize;
static void Main(string[] args) {
Random random = new Random();
DataSize = 10;
RandomNumberSize = 10;
List<int> listOfInts = new List<int>();
bool stillWorking = true;
int currentRand;
while (stillWorking) {
currentRand = random.Next(RandomNumberSize);
if (!listOfInts.Contains(currentRand)) {
listOfInts.Add(currentRand);
if (listOfInts.Count == DataSize)
stillWorking = false;
}
}
for (int i = 0; i < listOfInts.Count; i++) {
Console.WriteLine(i + " - " + listOfInts[i]);
}
Console.ReadKey();
}
Hope this helps ;-)
The typical solution is to generate the entire potential set in sequence (in this case an array with values from 0 to 9). Then shuffle the sequence.
private static Random rng = new Random();
public static void Shuffle(int[] items)
{
int n = list.Length;
while (n > 1) {
n--;
int k = rng.Next(n + 1);
int temp = items[k];
items[k] = items[n];
items[n] = temp;
}
}
static void Main(string[] args)
{
int[] x = new int[10];
for(int i = 0; i<x.Length; i++)
{
x[i] = i;
}
Shuffle(x);
for(int i = 0; i < x.Length; i++)
{
Console.WritLine(x[i]);
}
}
//alternate version of Main()
static void Main(string[] args)
{
var x = Enumerable.Range(0,10).ToArray();
Shuffle(x);
Console.WriteLine(String.Join("\n", x));
}
You can simply do this:
private void AddUniqueNumber()
{
Random r = new Random();
List<int> uniqueList = new List<int>();
int num = 0, count = 10;
for (int i = 0; i < count; i++)
{
num = r.Next(count);
if (!uniqueList.Contains(num))
uniqueList.Add(num);
}
}
Or:
int[] x = new int[10];
Random r1 = new Random();
int num = 0;
for (int i = 0; i < x.Length; i++)
{
num = r1.Next(10);
x[num] = num;
}

Cannot redraw points which have been set to NULL

I have the following setup:
A TeeChart control with a Colorgrid, and a Points Series added to it:
grid = tChart2.Series[0] as Steema.TeeChart.Styles.ColorGrid;
points = tChart2.Series[1] as Steema.TeeChart.Styles.Points;
To init them, I do:
Random rnd = new Random();
for (int i = 0; i < 128; i++)
{
for (int j = 0; j < 128; j++)
{
grid.Add(j, rnd.Next(255), i);
}
}
for (int i = 0; i < 20; i++)
{
double x = rnd.Next();
double y = rnd.Next();
points.Add(x, y);
}
tChart2.Refresh();
And then I have a button on my form:
private void button1_Click(object sender, EventArgs e)
{
Random rnd = new Random();
for (int i = 0; i < 128; i++)
{
for (int j = 0; j < 128; j++)
{
grid.YValues[j + 128 * i] = rnd.Next(255);
}
}
for (int i = 0; i < 20; i++)
{
points.SetNull(i);
}
for (int i = 0; i < rnd.Next(20); i++)
{
points.XValues[i] = rnd.Next(128);
points.YValues[i] = rnd.Next(128);
}
points.BeginUpdate();
points.EndUpdate();
}
But the points do not get drawn. When I remove the for-loop containing the SetNull() statement, then they do get drawn, but I want to be able to clear the points (or hide the points don't want to be seen) without using the Points.Clear()/Points.Add(x, y) methodology.
I've also tried each of the following, but there's no difference.
points.TreatNulls = Steema.TeeChart.Styles.TreatNullsStyle.DoNotPaint;
points.TreatNulls = Steema.TeeChart.Styles.TreatNullsStyle.Ignore;
points.TreatNulls = Steema.TeeChart.Styles.TreatNullsStyle.Skip;
Does anyone know how to accomplish this?
Ok, the problem is caused when you set null all of points. You must know if you use method SetNull the point color is set transparent to make invisible the point. Therefore, if you want solve your problem you only need reset the colors of points you want visible, doing SetNull again or change the points color manually and combining the operation with TreatNullsStyle set to Ignore. In my opinion, I think the best option is use SetNull again as I do in next code:
public Form1()
{
InitializeComponent();
InitializeChart();
}
Steema.TeeChart.Styles.ColorGrid grid;
Steema.TeeChart.Styles.Points points;
private void InitializeChart()
{
grid = new ColorGrid(tChart1.Chart);
points = new Points(tChart1.Chart);
tChart1.Aspect.View3D = false;
Random rnd = new Random();
for (int i = 0; i < 128; i++)
{
for (int j = 0; j < 128; j++)
{
grid.Add(i, rnd.Next(255), j);
}
}
for (int i = 0; i < 20; i++)
{
double x = rnd.Next(100);
double y = rnd.Next(100);
points.Add(x, y);
}
}
private void button1_Click(object sender, EventArgs e)
{
Random rnd = new Random();
for (int i = 0; i < 128; i++)
{
for (int j = 0; j < 128; j++)
{
grid.YValues[j + 128 * i] = rnd.Next(255);
}
}
for (int i = 0; i < 20; i++)
{
points.SetNull(i);
}
for (int i = 0; i < rnd.Next(20); i++)
{
points.XValues[i] = rnd.Next(128);
points.YValues[i] = rnd.Next(128);
points.SetNull(i, false);
}
points.TreatNulls = TreatNullsStyle.Ignore;
}
Could you tell us if previous code works in correct way for you?
I hope will helps.
Thanks,

Categories