0

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();
            }
        }
    }
}
slugster
  • 49,403
  • 14
  • 95
  • 145

4 Answers4

1

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();
         }
      }
Stackedup
  • 680
  • 2
  • 9
  • 26
  • can you please explain what did you do, because i am a beginner – Rezan Rasoul Nov 12 '20 at 11:21
  • 1
    So the method GetRandomRow is called recursive function(If you Google it there are tons of explanations for it). We want to construct a row which is made of multiple columns. So we can start with first column, and then add the second one and so on. Since we are repeating the same set of steps, that means we can put it in one function, then let it call itself for adding every new column. When you are writing recursion, you just have to make sure that you cover the main conditions to prevent it from causing it endlessly call itself. Here the main condition is when you have added for all ... – Stackedup Nov 12 '20 at 11:33
  • 1
    ...all of the columns...that is the "if(colCount <= 0)" condition. Then you also need to understand when to call itself. There are two situations where you can let it to call itself. One if there was a repetition, which you want to skip...that is why I call it with with the same input parameters as before, since I am still trying to find the right value for the same column. The second situation is that I have found a suitable value for the current column, so I can let it call itself but this time I move to the next column by passing "colCount - 1". Hope that helps. – Stackedup Nov 12 '20 at 11:38
0

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();
IndieGameDev
  • 2,905
  • 3
  • 16
  • 29
  • 1
    `Shuffle` return type should be `void`, since it modify passed list. See also [related answer](https://stackoverflow.com/a/1262619/1997232) for a proper implementation of shuffle. – Sinatr Nov 11 '20 at 12:35
0

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();
        }
    }
  }
}
  • This results in false positives. So if your checkcolumn has "31, 22" and your next is 3, then it will print duplicated number right? – Stackedup Nov 11 '20 at 20:40
  • 1
    no if checkColumn has "31, 22" as you say and i want to add 3at the first i will check if this string contains "3, " or not, and "3, " not exist in this string so i can add it easily. **note that contains method takes the string which you pass in parenthesis and check if that exactly string exist in whatever string or not** – Mahmoud Mohamed Ramadan Nov 12 '20 at 02:49
  • 1
    The behavior is odd, my take from OP's question and other answers are to generate a predefined amount of unique random numbers. Yours instead may generate less than the requested amount, since on duplicates you simply skip the number without creating replacement – Martheen Nov 12 '20 at 06:11
  • i think that he want to prevent duplicated values only without creating replacement – Mahmoud Mohamed Ramadan Nov 12 '20 at 10:24
0

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
Idle_Mind
  • 38,363
  • 3
  • 29
  • 40