Generate non duplicate random number - c#

I'm trying to make a lottery console app, but have a problem with duplicated numbers in some rows.
A lottery coupon is 10 row with 7 numbers, min number is 0, max number is 36.
How can i check if the number is exist in same row in my for loop?
here is my code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Obligatorisk_Opgave_2
{
class Program
{
static void Main(string[] args)
{
int min = 0; // minimum number
int max = 36; // maximum number
int rows = 10; // number of rows in my copun
int col = 7; // number of column in my copun
// Get the date of PC
string NameDate;
NameDate = DateTime.Now.ToString("yyyy.MM.dd");
string Week = "1-uge";
string ComName = "LYN LOTTO";
Random rnd = new Random();
Console.WriteLine("{0,22} \n {1,15} \n{2,18}", NameDate, Week, ComName);
for (int i = 0; i < rows; i++)
{
Console.Write($"{i + 1}.");
for (int j = 0; j < col; j++)
Console.Write("{1,4}", i, rnd.Next(min, max));
Console.WriteLine();
}
Console.WriteLine("***** JOKER TAL *****");
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < col; j++)
Console.Write("{0,4}", rnd.Next(1,9));
Console.WriteLine();
}
}
}
}

You can use a recursive function to do this:
private static List<int> GetRandomRow(List<int> row, int colCount, int min, int max)
{
if(colCount <= 0)
{
return row;
}
var next = rnd.Next(min, max);
if(row.Contains(next))
{
return GetRandomRow(row, colCount, min, max);
}
row.Add(next);
return GetRandomRow(row, colCount - 1, min, max);
}
Then you can use your program like:
private static Random rnd = new Random();
static void Main(string[] args)
{
int min = 0; // minimum number
int max = 36; // maximum number
int rows = 10; // number of rows in my copun
int col = 7; // number of column in my copun
// Get the date of PC
string NameDate;
NameDate = DateTime.Now.ToString("yyyy.MM.dd");
string Week = "1-uge";
string ComName = "LYN LOTTO";
Random rnd = new Random();
Console.WriteLine("{0,22} \n {1,15} \n{2,18}", NameDate, Week, ComName);
for (int i = 0; i < rows; i++)
{
Console.Write($"{i + 1}.");
var row = new List<int>();
var currentRow = GetRandomRow(row, col, min, max);
foreach (var currentCol in currentRow)
{
Console.Write("{1,4}", i, currentCol);
}
Console.WriteLine();
}
Console.WriteLine("***** JOKER TAL *****");
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < col; j++)
Console.Write("{0,4}", rnd.Next(1, 9));
Console.WriteLine();
}
}

Instead of random numbers you could Shuffle your List.
Shuffle Function:
public static List<T> Shuffle<T> (List<T> list) {
Random rnd = new Random();
for (int i = 0; i < list.Count; i++)
{
int k = rnd.Next(0, i);
T value = list[k];
list[k] = list[i];
list[i] = value;
}
return list;
}
Now you can call that function and shuffle the content of your List.
Example:
int min = 0;
int max = 36;
int rows = 10;
List<int> mylist = new List<int>();
for (int i = max; i >= min; i--) {
mylist.Add(i);
}
mylist = Shuffle(mylist);
for (int i = 0; i < rows; i++) {
Console.WriteLine(mylist[i]);
}
Console.ReadLine();

simply you can define variable from string data type and add each column in this variable but before add operation you should check if this column exists in this string or not
code is updated
i have definde rndNumber as an integer type before check then i have assigned rnd.Next(min, max) to it, because if i check for rnd.Next(min, max) and if it was not exist so when add it in checkNumber may be it changed again for example...
if(checkNumber.Contains(rnd.Next(min, max))) // if value of rnd.Next(min, max) was 15 and this number not exist in checkNumber so i can add it
{
checkNumber += rnd.Next(min, max); // maybe value of rnd.Next(min, max) change to will be 20
}
notice that every time you call rnd.Next(min, max) it's value will be changed
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Obligatorisk_Opgave_2
{
class Program
{
static void Main(string[] args)
{
int min = 0; // minimum number
int max = 36; // maximum number
int rows = 10; // number of rows in my copun
int col = 7; // number of column in my copun
string checkColumn = ""; // string variable for storing rows values
// Get the date of PC
string NameDate;
NameDate = DateTime.Now.ToString("yyyy.MM.dd");
string Week = "1-uge";
string ComName = "LYN LOTTO";
Random rnd = new Random();
Console.WriteLine("{0,22} \n {1,15} \n{2,18}", NameDate, Week, ComName);
for (int i = 0; i < rows; i++)
{
Console.Write($"{i + 1}.");
for (int j = 0; j < col; j++)
{
// check here if string does not contains this random value then add this it into string and write this number, else will be written duplicated number
int rndNumber = rnd.Next(min, max);
if ( !checkColumn.Contains(rndNumber.ToString()+", ") )
{
checkColumn += rndNumber.ToString()+", ";
Console.Write("{1,4}", i, rndNumber);
}
else
{
Console.Write("duplicated number");
}
}
checkColumn += "\n";
Console.WriteLine();
}
Console.WriteLine("***** JOKER TAL *****");
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < col; j++)
Console.Write("{0,4}", rnd.Next(1,9));
Console.WriteLine();
}
}
}
}

I'd use something more like:
for (int i = 1; i <= rows; i++)
{
Console.Write((i + ".").PadRight(3));
var row = Enumerable.Range(min, (max - min) + 1).OrderBy(x => rnd.Next()).Take(col).ToList();
foreach(var num in row) {
Console.Write(num.ToString("00").PadLeft(3));
}
Console.WriteLine();
}
Producing:
1. 33 14 24 27 07 29 30
2. 12 31 03 19 04 02 30
3. 34 03 14 23 20 09 04
4. 09 11 24 07 00 30 17
5. 26 04 22 02 25 20 12
6. 28 26 12 08 04 25 35
7. 09 26 20 34 17 03 23
8. 25 26 35 08 29 06 01
9. 29 33 00 04 09 35 36
10. 00 14 19 25 03 21 33

Related

3x3 user input bingo game

I wrote a code for a 3x3 bingo game. It check for line, bingo or nothing for a given input where I get a 3x3 bingo card and next 15 numbers extracted.
Basically I use a 2D user inputed array for the 3x3 bingo card, then I have a function which asks me to input 15 numbers. If all the numbers from the 3x3 bingo card are present in those 15 extracted numbers then I have "bingo". If I have numbers from a line but not all numbers then the program will output "line". And if i will not have bingo neither line the program will output "nothing".
Here is the input:
1 2 3
90 91 92
93 94 95
1
2
3
4
5
6
7
8
10
11
12
13
14
15
16
The program should return "line" but instead I get "nothing"
using System;
class Program
{
static void Main()
{
const int numberOfRows = 3;
const int numberOfColumnns = 3;
const int numbersExtracted = 15;
int[,] bingoCard = ReadBingoCard(numberOfRows, numberOfColumnns);
int[] numbers = ReadNumbersExtracted(numbersExtracted);
PrintResult(bingoCard, numbers);
Console.ReadLine();
}
static int[,] ReadBingoCard(int rowsNumber, int columnNumber)
{
int[,] card = new int[rowsNumber, columnNumber];
for (int i = 0; i < rowsNumber; i++)
{
string[] array = Console.ReadLine().Split(' ');
for (int j = 0; j < columnNumber; j++)
{
card[i, j] = Convert.ToInt32(array[j]);
}
}
return card;
}
static int[] ReadNumbersExtracted(int numbersExtracted)
{
int[] numbers = new int[numbersExtracted];
for (int i = 0; i < numbersExtracted; i++)
{
numbers[i] = Convert.ToInt32(Console.ReadLine());
}
return numbers;
}
static bool CheckForBingo(int[,] bingoCard, int[] numbers)
{
int numMatchesFound = 0;
foreach (var number in bingoCard)
{
for (int numIndex = 0; numIndex < numbers.Length; numIndex++)
{
if (number == numbers[numIndex])
{
numMatchesFound++;
break;
}
}
}
return numMatchesFound == bingoCard.Length;
}
static bool CheckForLine(int[,] bingoCard, int[] numbers)
{
for (int row = 0; row < bingoCard.GetLength(0); row++)
{
int colMatchesInRow = 0;
for (int col = 0; col < bingoCard.GetLength(1); col++)
{
if (Index(bingoCard, row, col, numbers, ref colMatchesInRow))
{
continue;
}
break;
}
if (colMatchesInRow == bingoCard.GetLength(1))
{
return true;
}
}
return false;
}
static bool Index(int[,] bingoCard, int row, int col, int[] numbers, ref int colMatchesInRow)
{
for (int numIndex = 0; numIndex < numbers.Length; numIndex++)
{
if (bingoCard[row, col] != numbers[numIndex])
{
continue;
}
colMatchesInRow++;
break;
}
return colMatchesInRow == bingoCard.GetLength(1);
}
static void PrintResult(int[,] bingoCard, int[] numbersExtracted)
{
if (CheckForBingo(bingoCard, numbersExtracted))
{
Console.WriteLine("bingo");
}
else if (CheckForLine(bingoCard, numbersExtracted))
{
Console.WriteLine("line");
}
else
{
Console.WriteLine("nothing");
}
}
}
Checking if one line has matched numbers is the same as checking for bingo (all input numbers) but for one row only.
Try to implement the function CheckForLine() this way :
static bool CheckForLine(int[,] bingoCard, int[] numbers)
{
int numMatchesFound = 0;
foreach (var number in bingoCard)
{
for (int numIndex = 0; numIndex < numbers.Length; numIndex++)
{
if (number == numbers[numIndex])
{
numMatchesFound++;
break;
}
}
if (numMatchesFound == bingoCard.GetLength(1))
{
return true;
}
}
return false;
}
The 2 bingo-card cases below will work :
1 97 99
90 2 92
93 94 3
and
1 2 3
90 91 92
93 94 95

Longest sequences in a list (including overlapping)?

Let's say we have a list of Node objects with a Value property.
Is there a time-efficient algorithm to link Node pairs of the same Value within the longest repeated Node-range(s) only?
Overlapping is allowed so is multiple longest node-pair spans if they have the same length.
The Value property is irreducible to char and therefore the "longest repeated substring" algorithm is not the answer.
Example:
INPUT:
Node Values =
{ AA, BB, CC, DD, AA, BB, CC, AA, BB, CC, DD, EE, BB, CC, DD, EE, FF, EE, FF } // Values
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 // indices
OUTPUT:
Edges (from_node_index, to_node_index) =
{
(00-07, 01-08, 02-09, 03-10),
(08-12, 09-13, 10-14, 11-15),
(15-17, 16-18)
}
Here is my naive attempt using C# which I think runs in O(n^2 log n) time complexity.
for (int i = 0; i < m_nodes.Count - 1; i++)
{
int first_j = -1;
int range = 0; // maximum number of repeated nodes in node range
int k = 0; // current number of repeated nodes in node range
for (int j = i + 1; j < m_nodes.Count; j++)
{
if (m_nodes[i].Value == m_nodes[j].Value)
{
k = 0;
do
{
k++;
if ((j + k) == m_nodes.Count) break;
} while (m_nodes[i + k].Value == m_nodes[j + k].Value);
if (k > range)
{
range = k;
first_j = j;
j += range; // skip repeating nodes
}
}
}
if (range > 0)
{
if (first_j > i)
{
for (int x = 0; x < range; x++)
{
if (first_j >= 0)
{
Edge edge = new Edge();
if (edge != null)
{
edge.Id = ++count;
edge.Source = m_nodes[i + x];
edge.Target = m_nodes[first_j + x];
edge.Label = m_nodes[first_j + x].Text + " = " + m_nodes[first_j + x].Value.ToString();
edge.Range = range;
edge.NumberInRange = x + 1;
m_edges.Add(edge);
}
}
}
}
}
}
I feel Dynamic Programming might be the answer but I am not familiar with that.
Here is the full source code: https://yadi.sk/d/aDdN9slB0H7BQA
Thank you in advance.

print diagonal routes array

I make this code to print array if the number of array is
{
1, 2, 3, 4, 5,
6, 7, 8, 9,
10,11,12,13,
14,15,16,17,
18,19,20,21,
22,23,24,25
}
the out put of this code is
1,2,6,3,7,11,4,6,12,16,5,9,13,17,21,10,14,18,21,15,19,23,20,24,25
I want to make change in this my code to be the out put begging from
21 16 22 11 17 23 6 12 18 24 1 7 13 19 25 2 8 14 203 9 15 4 10 5
and this my Code
int [,] p = new int [5,5];
int sum = 1;
for (int i = 1; i <= 5; i++)
{
for (int j = 1; j <= 5; j++)
{
p[i, j] = sum;
richTextBox1.Text += p[i, j].ToString();
sum++;
}
}
int C;
int R=1;
for (int i = 1; i <= 5; i++)
{
C = i;
for (int r = 1; r <= i; r++)
{
Output = Output + p[r, C];
C--;
}
}
richTextBox2.Text += Output.ToString();
for (int i = 2; i >= 5; i++)
{
R = i;
for (C = 5; C >= i; C--)
{
Output = Output + p[R, C];
R++;
}
}
richTextBox2.Text += Output.ToString();
This is more fiddly than you might think!
You want to traverse the diagonals of this matrix:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
21 22 23 24 25
starting at the bottom left and traversing each diagonal as depicted in this very badly-drawn diagram:
I've written a helper method called DiagonalIndices() that for a given maximum index (in the case of your 5x5 matrix, it will be 4) will produce a sequence of (row,col) indices in the correct order to traverse all the diagonals.
Note that the input array MUST be square - I'm assuming that is the case for your data! It clearly is for a 5x5 matrix.
The output of the following program is
21 16 22 11 17 23 6 12 18 24 1 7 13 19 25 2 8 14 20 3 9 15 4 10 5
Here's the code:
using System;
using System.Collections.Generic;
namespace ConsoleApplication4
{
public sealed class Index
{
public Index(int row, int col)
{
Row = row;
Col = col;
}
public readonly int Row;
public readonly int Col;
}
public static class Program
{
private static void Main()
{
int [,] p = new int[5, 5];
for (int i = 0, n = 1; i < 5; ++i)
for (int j = 0; j < 5; ++j, ++n)
p[i, j] = n;
// This is the bit you will use in your program.
// Replace the Console.WriteLine() with your custom code
// that uses p[index.Row, index.Col]
int maxIndex = p.GetUpperBound(1);
foreach (var index in DiagonalIndices(maxIndex))
Console.Write(p[index.Row, index.Col] + " ");
Console.WriteLine();
}
public static IEnumerable<Index> DiagonalIndices(int maxIndex)
{
for (int i = 0; i <= maxIndex; ++i)
for (int j = 0; j <= i; ++j)
yield return new Index(maxIndex-i+j, j);
for (int i = 0; i < maxIndex; ++i)
for (int j = 0; j < maxIndex-i; ++j)
yield return new Index(j, i+j+1);
}
}
}
This is a more efficient of printing only the diagonal values in a positive direction in a matrix.
int [,] p = new int [5,5]
{
{1, 2, 3, 4,5},
{6, 7, 8, 9},
{10,11,12,13},
{14,15,16,17},
{18,19,20,21},
{22,23,24,25}
};
for (int i = 4, j = 4; i >= 0 && j > = 0; i--, j--)
{
Console.Writeline(p[ i, j ]);
}

Finding the column total in an array

I have an 1-dimensional array with random elements, got through a m*n grid. I want to find out the row total and column total, present in it.
Here is how the 1 dimensional array is:
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]
I want to treat it like :
01 02 03 04 05
06 07 08 09 10
11 12 13 14 15
16 17 18 19 20
Now i want to find the reo total and column total.
Row total is done as follows:
for (int i = 0; i < totalRows; i++)
{
for (int j = 0; j < totalColumns; j++)
{
rowTotal[i] += numbers[temp + j];
}
temp += totalColumns;
}
I am trying to do the same with Column.
Here is the code:
for (int i = 0; i < totalColumns; i++)
{
tempk = 0;
for (int j = 0; j < totalRows; j++)
{
blockTotal[i] += numbers[i+j+tempk];
tempk += totalColumns;
}
}
Am not able to get the column total, as intended. Please Help.
You can get both in the same loop
for (int i = 0; i < totalRows; i++)
{
for (int j = 0; j < totalColumns; j++)
{
rowTotal[i] += numbers[i * totalColumns + j];
blockTotal[j] += numbers[i * totalColumns + j];
}
}
The easiest thing to do is to write a little method that translates a "logical" (row, col) address to an index:
int numberAt(int row, int col)
{
return numbers[row * totalColumns + col];
}
int[] colTotals = new int[totalColumns];
int[] rowTotals = new int[totalRows];
for (int row = 0; row < totalRows; ++row)
{
for (int col = 0; col < totalColumns; ++col)
{
int number = numberAt(row, col);
rowTotals[row] += number;
colTotals[col] += number;
}
}
Edit in response to question in comments below:
Here's a complete compilable example that demonstrates it working on a non-square array:
using System;
using System.Collections.Generic;
using System.Linq;
namespace Demo
{
class Program
{
// Array will 4x3 (rows x cols):
//
// 1 2 3 | 6
// 4 5 6 | 15
// 7 8 9 | 24
// 10 11 12 | 33
// ---------
// 22 26 30
int[] numbers = Enumerable.Range(1, 12).ToArray();
int totalColumns = 3;
int totalRows = 4;
int numberAt(int row, int col)
{
return numbers[row * totalColumns + col];
}
void test()
{
int[] colTotals = new int[totalColumns];
int[] rowTotals = new int[totalRows];
for (int row = 0; row < totalRows; ++row)
{
for (int col = 0; col < totalColumns; ++col)
{
int number = numberAt(row, col);
rowTotals[row] += number;
colTotals[col] += number;
}
}
Console.WriteLine("Row totals");
foreach (int rowTotal in rowTotals)
Console.Write(rowTotal + " ");
Console.WriteLine("\nCol totals");
foreach (int colTotal in colTotals)
Console.Write(colTotal + " ");
Console.WriteLine();
}
static void Main()
{
new Program().test();
}
}
}
Total by rows
for(int r = 0; r < totalRows; r++)
{
for(int c = 0; c < totalColumns; c++)
{
rowTotal[r] += numbers[r * totalColumns + c];
}
}
Total by columns
for(int c = 0; c < totalColumns; c++)
{
for(int r = 0; r < totalRows; r++)
{
colTotal[c] += numbers[r * totalColumns + c];
}
}

Evenly distribute collection into new Arrays

I'm trying to create an method to evenly distribute an array into X numbers of new arrays, where there is only allowed 15 items pr array, and you are only allowed to create a new array, if the previous have 10 items, except if the array has less than 10 items.
EDIT
To make my question more understandable for future readers.
This is just like a fabric.
You need to build X number of products.
One product takes T amount to build for an employee.
How many employees do you need and how do you share the work load between them?
END EDIT
Max allowed number in array = 15;
Min allowed number in array = 10;
Number = Numbers of Items in the Collection.
Number 5 => [5]
Number 13 => [13]
Number 16 => [10] [6]
Number 29 => [15] [14]
Number 30 => [15] [15]
Number 31 => [11] [10] [10]
Number 32 => [12] [10] [10]
Number 33 => [11] [11] [11]
I'm trying to solve this in C#.
This is my code so far, but it fails at numbers like 16 = [16], 29 = [19][10], 38 = [18][10][10]
const int maxAllowedOrderLines = 15;
const int minAllowedOrderLines = 10;
var optimalOrderDisp = new List<int>();
Console.WriteLine("Number of OrderLines");
int linjer = Convert.ToInt32(Console.ReadLine());
if (linjer <= maxAllowedOrderLines)
optimalOrderDisp.Add(linjer);
else
{
for (var i = maxAllowedOrderLines; i > 0; i--)
{
var maxOrderLines = linjer%i;
if (maxOrderLines == 0 || i <= minAllowedOrderLines || linjer < maxAllowedOrderLines)
{
Console.WriteLine("Optimal number of order lines {0}--{1}", i, (double) linjer/(double) i);
var optimalNumberOfOrders = linjer/i;
for (var orderNumber = 0; orderNumber < optimalNumberOfOrders; orderNumber++)
{
optimalOrderDisp.Add(i);
}
if (maxOrderLines != 0)
optimalOrderDisp[0] += maxOrderLines;
break;
}
}
}
foreach (var i1 in optimalOrderDisp)
{
Console.Write("[{0}]", i1);
}
Console.WriteLine();
Erm ...
const double bucketSize = 15.0;
var totalItems = (double)linjer;
var optimumBuckets = Math.Ceiling(totalItems / bucketSize);
var itemsPerBucket = (int)Math.Ceiling(totalItems / optimumBuckets);
var buckets = new int[(int)optimumBuckets];
var itemsLeft = (int)totalItems
for (var i = 0; i < buckets.length; i++)
{
if (itemsLeft < itemsPerBucket)
{
buckets[i] = itemsLeft;
}
else
{
buckets[i] = itemsPerBucket;
}
itemsLeft -= itemsPerBucket;
}
seems to do what you want.
Fun question. I've given it a go:
const int maxAllowedOrderLines = 15;
const int minAllowedOrderLines = 10;
static List<int> optimalOrderDisp = new List<int>();
static void Main(string[] args)
{
int Lines = Convert.ToInt32(Console.ReadLine());
int MinNumberOfBuckets = (int) Math.Ceiling((double) Lines / minAllowedOrderLines);
int RemainingLines = Lines;
int BucketLines = Lines / MinNumberOfBuckets;
// Distribute evenly
for (int i = 0; i < MinNumberOfBuckets; i++)
{
optimalOrderDisp.Add(i != MinNumberOfBuckets - 1 ? BucketLines : RemainingLines);
RemainingLines -= BucketLines;
}
// Try to remove first bucket
while (RemoveBucket())
{
}
// Re-balance
Lines = optimalOrderDisp.Sum();
RemainingLines = Lines;
BucketLines = (int) Math.Round((double) Lines / (optimalOrderDisp.Count));
for (int i = 0; i < optimalOrderDisp.Count; i++)
{
optimalOrderDisp[i] = (i != optimalOrderDisp.Count - 1 ? BucketLines : RemainingLines);
RemainingLines -= BucketLines;
}
// Re-balance to comply to min size
for (int i = 0; i < optimalOrderDisp.Count - 1; i++)
if (optimalOrderDisp[i] < minAllowedOrderLines)
{
int delta = minAllowedOrderLines - optimalOrderDisp[i];
optimalOrderDisp[i] += delta;
optimalOrderDisp[optimalOrderDisp.Count - 1] -= delta;
}
Console.WriteLine(String.Join("\n", optimalOrderDisp.ToArray()));
}
static bool RemoveBucket()
{
if (optimalOrderDisp.Sum() > maxAllowedOrderLines * (optimalOrderDisp.Count - 1))
return false;
int Lines = optimalOrderDisp[0];
int RemainingLines = Lines;
int BucketLines = Lines / (optimalOrderDisp.Count - 1);
// Remove bucket and re-distribute content evenly
// Distribute evenly
for (int i = 1; i < optimalOrderDisp.Count; i++)
{
optimalOrderDisp[i] += (i != optimalOrderDisp.Count - 1 ? BucketLines : RemainingLines);
RemainingLines -= BucketLines;
}
optimalOrderDisp.RemoveAt(0);
return true;
}

Categories