0

How I can put randomize numbers to list without repetition? Here's my code, sometimes the numbers are repeated but I do not know why

Random losowa = new Random();
List<int> pula = new List<int>();

private void LosujPytania()
{            
    int a = losowa.Next(1,20);
    while (pula.Count < 10)
    {
        foreach (int i in pula)
        {
            if (a == i)
            {
                a = losowa.Next(1, 20);
                break;
            }

        }
        pula.Add(a);
    }
}
Dmitry
  • 13,797
  • 6
  • 32
  • 48
  • 1
    Every time you call `Next` it generates a number between 1 and 20. They are not guaranteed to be unique. You could look at the Fisher-Yates shuffle and have a go at implementing that. https://www.dotnetperls.com/fisher-yates-shuffle – Steve Jan 15 '17 at 14:55

5 Answers5

1

Code below create list of numbers without repetition. Key to resolve problem is use list.Contains().

    using System;
    using System.Collections.Generic;

    public class Program
    {
        public static void Main()
        {
            var list = new List<int>();             
            var rand = new Random();

            while(list.Count <10)
            {
                var number = rand.Next(1,20);

                if(! list.Contains(number))
                    list.Add(number);               
            }

            foreach(var item in list)           
                Console.WriteLine(item);  
        }
    }
MKasprzyk
  • 503
  • 5
  • 17
0

You should check if this number was previously generated and generate another number if it is repeated.

Change this:

private void LosujPytania()
{            
    int a = losowa.Next(1,20);
    while (pula.Count < 10)
    {
        foreach (int i in pula)
        {
            if (a == i)
            {
                a = losowa.Next(1, 20);
                break;
            }
        }
        pula.Add(a);
    }
}

by this:

private void LosujPytania()
{            
    int a = losowa.Next(1,20);
    pula.Add(a);
    while (pula.Count < 10)
    {
        do
        {
            a = losowa.Next(1, 20);
        } while(pula.Contains(a));

        pula.Add(a);
    }
}
Roman
  • 11,966
  • 10
  • 38
  • 47
0

You can do this, you can check my comments additional details:

 private static void LosujPytania()
            {         

        Random losowa = new Random();
        List<int> pula = new List<int>();

                int a = losowa.Next(1,20);
                while (pula.Count < 10)
                {
                    //Your code is not really checking for duplicates so I replace it with boolean condition below
                    //foreach (int i in pula)
                    //{
                    //    if (a == i)
                    //    {
                    //        a = losowa.Next(1, 20);
                    //        break;
                    //    }

                    //}

                    a = losowa.Next(1, 20);
                    //This will check if your list doesn't contain your numbers yet before adding to make sure everything is unique
                    if (!pula.Contains(a))
                    pula.Add(a);
                }
        }
Willy David Jr
  • 8,604
  • 6
  • 46
  • 57
0

if you want numbers without replications, I think it will be better to use HashSet.

            Random losowa = new Random();
            HashSet<int> pula = new HashSet<int>();
            while (pula.Count < 10)
            {
                pula.Add(r.Next(20));
            }

or if you really need the List, you can use a helper method something like:

  private void LosujPytania()
    {
        Random losowa = new Random();
        List<int> pula = new List<int>();
        int a = losowa.Next(1, 20);
        pula.AddRange(Get10RandomNumbers(losowa));
    }

    private IEnumerable<int> Get10RandomNumbers(Random losowa)
    {
        HashSet<int> ints = new HashSet<int>();   
        while (ints.Count < 10)
        {
            ints.Add(losowa.Next(20));
        }
        return ints;

    }
Alons
  • 1
  • 1
0

A simple 2 lines solution:

var rnd = new Random();
var list = Enumerable.Range(0, 20).OrderBy(x => rnd.Next()).Take(10).ToList();

Explanation:

Enumerable.Range(0, 20) will return an IEnumerable<int> with the numbers 0 to 19.

OrderBy(x => rnd.Next()) will sort the values to a random order.

Take(10) will return the first 10 numbers from the IEnumerable<int>,

and finally, ToList() will return a list of these int values.

Zohar Peled
  • 79,642
  • 10
  • 69
  • 121