I've searched for a while and been struggling to find this, I'm trying to generate several random, unique numbers is C#. I'm using System.Random, and I'm using a DateTime.Now.Ticks seed:
public Random a = new Random(DateTime.Now.Ticks.GetHashCode());
private void NewNumber()
{
MyNumber = a.Next(0, 10);
}
I'm calling NewNumber() regularly, but the problem is I often get repeated numbers. Some people suggested because I was declaring the random every time I did it, it would not produce a random number, so I put the declaration outside my function. Any suggestions or better ways than using System.Random ? Thank you
I'm calling NewNumber() regularly, but the problem is I often get
repeated numbers.
Random.Next doesn't guarantee the number to be unique. Also your range is from 0 to 10 and chances are you will get duplicate values. May be you can setup a list of int and insert random numbers in the list after checking if it doesn't contain the duplicate. Something like:
public Random a = new Random(); // replace from new Random(DateTime.Now.Ticks.GetHashCode());
// Since similar code is done in default constructor internally
public List<int> randomList = new List<int>();
int MyNumber = 0;
private void NewNumber()
{
MyNumber = a.Next(0, 10);
if (!randomList.Contains(MyNumber))
randomList.Add(MyNumber);
}
You might try shuffling an array of possible ints if your range is only 0 through 9. This adds the benefit of avoiding any conflicts in the number generation.
var nums = Enumerable.Range(0, 10).ToArray();
var rnd = new Random();
// Shuffle the array
for (int i = 0;i < nums.Length;++i)
{
int randomIndex = rnd.Next(nums.Length);
int temp = nums[randomIndex];
nums[randomIndex] = nums[i];
nums[i] = temp;
}
// Now your array is randomized and you can simply print them in order
for (int i = 0;i < nums.Length;++i)
Console.WriteLine(nums[i]);
NOTE, I dont recommend this :).
Here's a "oneliner" as well:
var result = Enumerable.Range(0,9).OrderBy(g => Guid.NewGuid()).ToArray();
I'm posting a correct implementation of a shuffle algorithm, since the other one posted here doesn't produce a uniform shuffle.
As the other answer states, for small numbers of values to be randomized, you can simply fill an array with those values, shuffle the array, and then use however many of the values that you want.
The following is an implementation of the Fisher-Yates Shuffle (aka the Knuth Shuffle). (Read the "implementation errors" section of that link (search for "always selecting j from the entire range of valid array indices on every iteration") to see some discussion about what is wrong with the other implementation posted here.)
using System;
using System.Collections.Generic;
namespace ConsoleApplication2
{
static class Program
{
static void Main(string[] args)
{
Shuffler shuffler = new Shuffler();
List<int> list = new List<int>{ 1, 2, 3, 4, 5, 6, 7, 8, 9 };
shuffler.Shuffle(list);
foreach (int value in list)
{
Console.WriteLine(value);
}
}
}
/// <summary>Used to shuffle collections.</summary>
public class Shuffler
{
public Shuffler()
{
_rng = new Random();
}
/// <summary>Shuffles the specified array.</summary>
/// <typeparam name="T">The type of the array elements.</typeparam>
/// <param name="array">The array to shuffle.</param>
public void Shuffle<T>(IList<T> array)
{
for (int n = array.Count; n > 1; )
{
int k = _rng.Next(n);
--n;
T temp = array[n];
array[n] = array[k];
array[k] = temp;
}
}
private System.Random _rng;
}
}
This is a unity only answer:
Check this ready-to-use method: Give in a range & count of number you want to get.
public static int[] getUniqueRandomArray(int min, int max, int count) {
int[] result = new int[count];
List<int> numbersInOrder = new List<int>();
for (var x = min; x < max; x++) {
numbersInOrder.Add(x);
}
for (var x = 0; x < count; x++) {
var randomIndex = UnityEngine.Random.Range(0, numbersInOrder.Count);
result[x] = numbersInOrder[randomIndex];
numbersInOrder.RemoveAt(randomIndex);
}
return result;
}
Same as #Habib's answer, but as a function:
List<int> randomList = new List<int>();
int UniqueRandomInt(int min, int max)
{
var rand = new Random();
int myNumber;
do
{
myNumber = rand.Next(min, max);
} while (randomList.Contains(myNumber));
return myNumber;
}
If randomList is a class property, UniqueRandomInt will return unique integers in the context of the same instance of that class. If you want it to be unique globally, you will need to make randomList static.
Depending on what you are really after you can do something like this:
using System;
using System.Collections.Generic;
using System.Linq;
namespace SO14473321
{
class Program
{
static void Main()
{
UniqueRandom u = new UniqueRandom(Enumerable.Range(1,10));
for (int i = 0; i < 10; i++)
{
Console.Write("{0} ",u.Next());
}
}
}
class UniqueRandom
{
private readonly List<int> _currentList;
private readonly Random _random = new Random();
public UniqueRandom(IEnumerable<int> seed)
{
_currentList = new List<int>(seed);
}
public int Next()
{
if (_currentList.Count == 0)
{
throw new ApplicationException("No more numbers");
}
int i = _random.Next(_currentList.Count);
int result = _currentList[i];
_currentList.RemoveAt(i);
return result;
}
}
}
And here my version of finding N random unique numbers using HashSet.
Looks pretty simple, since HashSet can contain only different items.
It's interesting - would it be faster then using List or Shuffler?
using System;
using System.Collections.Generic;
namespace ConsoleApplication1
{
class RnDHash
{
static void Main()
{
HashSet<int> rndIndexes = new HashSet<int>();
Random rng = new Random();
int maxNumber;
Console.Write("Please input Max number: ");
maxNumber = int.Parse(Console.ReadLine());
int iter = 0;
while (rndIndexes.Count != maxNumber)
{
int index = rng.Next(maxNumber);
rndIndexes.Add(index);
iter++;
}
Console.WriteLine("Random numbers were found in {0} iterations: ", iter);
foreach (int num in rndIndexes)
{
Console.WriteLine(num);
}
Console.ReadKey();
}
}
}
I noted that the accepted answer keeps adding int to the list and keeps checking them with if (!randomList.Contains(MyNumber)) and I think this doesn't scale well, especially if you keep asking for new numbers.
I would do the opposite.
Generate the list at startup, linearly
Get a random index from the list
Remove the found int from the list
This would require a slightly bit more time at startup, but will scale much much better.
public class RandomIntGenerator
{
public Random a = new Random();
private List<int> _validNumbers;
private RandomIntGenerator(int desiredAmount, int start = 0)
{
_validNumbers = new List<int>();
for (int i = 0; i < desiredAmount; i++)
_validNumbers.Add(i + start);
}
private int GetRandomInt()
{
if (_validNumbers.Count == 0)
{
//you could throw an exception here
return -1;
}
else
{
var nextIndex = a.Next(0, _validNumbers.Count - 1);
var number = _validNumbers[nextIndex];
_validNumbers.RemoveAt(nextIndex);
return number;
}
}
}
It's may be a little bit late, but here is more suitable code, for example when you need to use loops:
List<int> genered = new List<int>();
Random rnd = new Random();
for(int x = 0; x < files.Length; x++)
{
int value = rnd.Next(0, files.Length - 1);
while (genered.Contains(value))
{
value = rnd.Next(0, files.Length - 1);
}
genered.Add(value);
returnFiles[x] = files[value];
}
with Functional way*
static Func<int> GetNextUniqueIntegerFunc(int min, int max)
{
var list = new List<int>();
var random = new Random();
int getNextValue()
{
while (true)
{
var random_number = random.Next(min, max);
if (!list.Contains(random_number))
{
list.Add(random_number);
return random_number;
}
}
}
return getNextValue;
}
unique random number from 0 to 9
int sum = 0;
int[] hue = new int[10];
for (int i = 0; i < 10; i++)
{
int m;
do
{
m = rand.Next(0, 10);
} while (hue.Contains(m) && sum != 45);
if (!hue.Contains(m))
{
hue[i] = m;
sum = sum + m;
}
}
You could also use a dataTable storing each random value, then simply perform the random method while != values in the dataColumn
randomNumber function return unqiue integer value between 0 to 100000
bool check[] = new bool[100001];
Random r = new Random();
public int randomNumber() {
int num = r.Next(0,100000);
while(check[num] == true) {
num = r.Next(0,100000);
}
check[num] = true;
return num;
}
hi here i posted one video ,and it explains how to generate unique random number
public List<int> random_generator(){
Random random = new Random();
List<int> random_container = new List<int>;
do{
int random_number = random.next(10);
if(!random_container.contains(random_number){
random_container.add(random_number)
}
}
while(random_container.count!=10);
return random_container;
}
here ,,, in random container you will get non repeated 10 numbers starts from 0 to 9(10 numbers) as random.. thank you........
You can use basic Random Functions of C#
Random ran = new Random();
int randomno = ran.Next(0,100);
you can now use the value in the randomno in anything you want but keep in mind that this will generate a random number between 0 and 100 Only and you can extend that to any figure.
Try this:
private void NewNumber()
{
Random a = new Random(Guid.newGuid().GetHashCode());
MyNumber = a.Next(0, 10);
}
Some Explnations:
Guid : base on here : Represents a globally unique identifier (GUID)
Guid.newGuid() produces a unique identifier like "936DA01F-9ABD-4d9d-80C7-02AF85C822A8"
and it will be unique in all over the universe base on here
Hash code here produce a unique integer from our unique identifier
so Guid.newGuid().GetHashCode() gives us a unique number and the random class will produce real random numbers throw this
Sample:
https://rextester.com/ODOXS63244
generated ten random numbers with this approach with result of:
-1541116401
7
-1936409663
3
-804754459
8
1403945863
3
1287118327
1
2112146189
1
1461188435
9
-752742620
4
-175247185
4
1666734552
7
we got two 1s next to each other, but the hash codes do not same.
Related
What is the best way to randomize the order of a generic list in C#? I've got a finite set of 75 numbers in a list I would like to assign a random order to, in order to draw them for a lottery type application.
Shuffle any (I)List with an extension method based on the Fisher-Yates shuffle:
private static Random rng = new Random();
public static void Shuffle<T>(this IList<T> list)
{
int n = list.Count;
while (n > 1) {
n--;
int k = rng.Next(n + 1);
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
Usage:
List<Product> products = GetProducts();
products.Shuffle();
The code above uses the much criticised System.Random method to select swap candidates. It's fast but not as random as it should be. If you need a better quality of randomness in your shuffles use the random number generator in System.Security.Cryptography like so:
using System.Security.Cryptography;
...
public static void Shuffle<T>(this IList<T> list)
{
RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider();
int n = list.Count;
while (n > 1)
{
byte[] box = new byte[1];
do provider.GetBytes(box);
while (!(box[0] < n * (Byte.MaxValue / n)));
int k = (box[0] % n);
n--;
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
A simple comparison is available at this blog (WayBack Machine).
Edit: Since writing this answer a couple years back, many people have commented or written to me, to point out the big silly flaw in my comparison. They are of course right. There's nothing wrong with System.Random if it's used in the way it was intended. In my first example above, I instantiate the rng variable inside of the Shuffle method, which is asking for trouble if the method is going to be called repeatedly. Below is a fixed, full example based on a really useful comment received today from #weston here on SO.
Program.cs:
using System;
using System.Collections.Generic;
using System.Threading;
namespace SimpleLottery
{
class Program
{
private static void Main(string[] args)
{
var numbers = new List<int>(Enumerable.Range(1, 75));
numbers.Shuffle();
Console.WriteLine("The winning numbers are: {0}", string.Join(", ", numbers.GetRange(0, 5)));
}
}
public static class ThreadSafeRandom
{
[ThreadStatic] private static Random Local;
public static Random ThisThreadsRandom
{
get { return Local ?? (Local = new Random(unchecked(Environment.TickCount * 31 + Thread.CurrentThread.ManagedThreadId))); }
}
}
static class MyExtensions
{
public static void Shuffle<T>(this IList<T> list)
{
int n = list.Count;
while (n > 1)
{
n--;
int k = ThreadSafeRandom.ThisThreadsRandom.Next(n + 1);
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
}
}
If we only need to shuffle items in a completely random order (just to mix the items in a list), I prefer this simple yet effective code that orders items by guid...
var shuffledcards = cards.OrderBy(a => Guid.NewGuid()).ToList();
As people have pointed out in the comments, GUIDs are not guaranteed to be random, so we should be using a real random number generator instead:
private static Random rng = new Random();
...
var shuffledcards = cards.OrderBy(a => rng.Next()).ToList();
I'm bit surprised by all the clunky versions of this simple algorithm here. Fisher-Yates (or Knuth shuffle) is bit tricky but very compact. Why is it tricky? Because your need to pay attention to whether your random number generator r(a,b) returns value where b is inclusive or exclusive. I've also edited Wikipedia description so people don't blindly follow pseudocode there and create hard to detect bugs. For .Net, Random.Next(a,b) returns number exclusive of b so without further ado, here's how it can be implemented in C#/.Net:
public static void Shuffle<T>(this IList<T> list, Random rnd)
{
for(var i=list.Count; i > 0; i--)
list.Swap(0, rnd.Next(0, i));
}
public static void Swap<T>(this IList<T> list, int i, int j)
{
var temp = list[i];
list[i] = list[j];
list[j] = temp;
}
Try this code.
Extension method for IEnumerable:
public static IEnumerable<T> Randomize<T>(this IEnumerable<T> source)
{
Random rnd = new Random();
return source.OrderBy<T, int>((item) => rnd.Next());
}
Idea is get anonymous object with item and random order and then reorder items by this order and return value:
var result = items.Select(x => new { value = x, order = rnd.Next() })
.OrderBy(x => x.order).Select(x => x.value).ToList()
public static List<T> Randomize<T>(List<T> list)
{
List<T> randomizedList = new List<T>();
Random rnd = new Random();
while (list.Count > 0)
{
int index = rnd.Next(0, list.Count); //pick a random item from the master list
randomizedList.Add(list[index]); //place it at the end of the randomized list
list.RemoveAt(index);
}
return randomizedList;
}
EDIT
The RemoveAt is a weakness in my previous version. This solution overcomes that.
public static IEnumerable<T> Shuffle<T>(
this IEnumerable<T> source,
Random generator = null)
{
if (generator == null)
{
generator = new Random();
}
var elements = source.ToArray();
for (var i = elements.Length - 1; i >= 0; i--)
{
var swapIndex = generator.Next(i + 1);
yield return elements[swapIndex];
elements[swapIndex] = elements[i];
}
}
Note the optional Random generator, if the base framework implementation of Random is not thread-safe or cryptographically strong enough for your needs, you can inject your implementation into the operation.
A suitable implementation for a thread-safe cryptographically strong Random implementation can be found in this answer.
Here's an idea, extend IList in a (hopefully) efficient way.
public static IEnumerable<T> Shuffle<T>(this IList<T> list)
{
var choices = Enumerable.Range(0, list.Count).ToList();
var rng = new Random();
for(int n = choices.Count; n > 1; n--)
{
int k = rng.Next(n);
yield return list[choices[k]];
choices.RemoveAt(k);
}
yield return list[choices[0]];
}
This is my preferred method of a shuffle when it's desirable to not modify the original. It's a variant of the Fisher–Yates "inside-out" algorithm that works on any enumerable sequence (the length of source does not need to be known from start).
public static IList<T> NextList<T>(this Random r, IEnumerable<T> source)
{
var list = new List<T>();
foreach (var item in source)
{
var i = r.Next(list.Count + 1);
if (i == list.Count)
{
list.Add(item);
}
else
{
var temp = list[i];
list[i] = item;
list.Add(temp);
}
}
return list;
}
This algorithm can also be implemented by allocating a range from 0 to length - 1 and randomly exhausting the indices by swapping the randomly chosen index with the last index until all indices have been chosen exactly once. This above code accomplishes the exact same thing but without the additional allocation. Which is pretty neat.
With regards to the Random class it's a general purpose number generator (and If I was running a lottery I'd consider using something different). It also relies on a time based seed value by default. A small alleviation of the problem is to seed the Random class with the RNGCryptoServiceProvider or you could use the RNGCryptoServiceProvider in a method similar to this (see below) to generate uniformly chosen random double floating point values but running a lottery pretty much requires understanding randomness and the nature of the randomness source.
var bytes = new byte[8];
_secureRng.GetBytes(bytes);
var v = BitConverter.ToUInt64(bytes, 0);
return (double)v / ((double)ulong.MaxValue + 1);
The point of generating a random double (between 0 and 1 exclusively) is to use to scale to an integer solution. If you need to pick something from a list based on a random double x that's always going to be 0 <= x && x < 1 is straight forward.
return list[(int)(x * list.Count)];
Enjoy!
If you don't mind using two Lists, then this is probably the easiest way to do it, but probably not the most efficient or unpredictable one:
List<int> xList = new List<int>() { 1, 2, 3, 4, 5 };
List<int> deck = new List<int>();
foreach (int xInt in xList)
deck.Insert(random.Next(0, deck.Count + 1), xInt);
I usually use:
var list = new List<T> ();
fillList (list);
var randomizedList = new List<T> ();
var rnd = new Random ();
while (list.Count != 0)
{
var index = rnd.Next (0, list.Count);
randomizedList.Add (list [index]);
list.RemoveAt (index);
}
You can achieve that be using this simple extension method
public static class IEnumerableExtensions
{
public static IEnumerable<t> Randomize<t>(this IEnumerable<t> target)
{
Random r = new Random();
return target.OrderBy(x=>(r.Next()));
}
}
and you can use it by doing the following
// use this on any collection that implements IEnumerable!
// List, Array, HashSet, Collection, etc
List<string> myList = new List<string> { "hello", "random", "world", "foo", "bar", "bat", "baz" };
foreach (string s in myList.Randomize())
{
Console.WriteLine(s);
}
Just wanted to suggest a variant using an IComparer<T> and List.Sort():
public class RandomIntComparer : IComparer<int>
{
private readonly Random _random = new Random();
public int Compare(int x, int y)
{
return _random.Next(-1, 2);
}
}
Usage:
list.Sort(new RandomIntComparer());
One can use the Shuffle extension methond from morelinq package, it works on IEnumerables
install-package morelinq
using MoreLinq;
...
var randomized = list.Shuffle();
If you have a fixed number (75), you could create an array with 75 elements, then enumerate your list, moving the elements to randomized positions in the array. You can generate the mapping of list number to array index using the Fisher-Yates shuffle.
You can make the Fisher-Yates shuffle more terse and expressive by using tuples for the swap.
private static readonly Random random = new Random();
public static void Shuffle<T>(this IList<T> list)
{
int n = list.Count;
while (n > 1)
{
n--;
int k = random.Next(n + 1);
(list[k], list[n]) = (list[n], list[k]);
}
}
I have found an interesting solution online.
Courtesy: https://improveandrepeat.com/2018/08/a-simple-way-to-shuffle-your-lists-in-c/
var shuffled = myList.OrderBy(x => Guid.NewGuid()).ToList();
We can use an extension method for List and use a thread-safe random generator combination. I've packaged an improved version of this on NuGet with the source code available on GitHub. The NuGet version contains optional cryptographically-strong random.
Pre-.NET 6.0 version:
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Shuffle<T>(this IList<T> list)
{
if (list == null) throw new ArgumentNullException(nameof(list));
int n = list.Count;
while (n > 1)
{
int k = ThreadSafeRandom.Instance.Next(n--);
(list[n], list[k]) = (list[k], list[n]);
}
}
internal class ThreadSafeRandom
{
public static Random Instance => _local.Value;
private static readonly Random _global = new Random();
private static readonly ThreadLocal<Random> _local = new ThreadLocal<Random>(() =>
{
int seed;
lock (_global)
{
seed = _global.Next();
}
return new Random(seed);
});
}
On .NET 6.0 or later:
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Shuffle<T>(this IList<T> list)
{
ArgumentNullException.ThrowIfNull(list);
int n = list.Count;
while (n > 1)
{
int k = Random.Shared.Next(n--);
(list[n], list[k]) = (list[k], list[n]);
}
}
Install the library via NuGet for more features.
A simple modification of the accepted answer that returns a new list instead of working in-place, and accepts the more general IEnumerable<T> as many other Linq methods do.
private static Random rng = new Random();
/// <summary>
/// Returns a new list where the elements are randomly shuffled.
/// Based on the Fisher-Yates shuffle, which has O(n) complexity.
/// </summary>
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> list) {
var source = list.ToList();
int n = source.Count;
var shuffled = new List<T>(n);
shuffled.AddRange(source);
while (n > 1) {
n--;
int k = rng.Next(n + 1);
T value = shuffled[k];
shuffled[k] = shuffled[n];
shuffled[n] = value;
}
return shuffled;
}
List<T> OriginalList = new List<T>();
List<T> TempList = new List<T>();
Random random = new Random();
int length = OriginalList.Count;
int TempIndex = 0;
while (length > 0) {
TempIndex = random.Next(0, length); // get random value between 0 and original length
TempList.Add(OriginalList[TempIndex]); // add to temp list
OriginalList.RemoveAt(TempIndex); // remove from original list
length = OriginalList.Count; // get new list <T> length.
}
OriginalList = new List<T>();
OriginalList = TempList; // copy all items from temp list to original list.
Here is an implementation of the Fisher-Yates shuffle that allows specification of the number of elements to return; hence, it is not necessary to first sort the whole collection before taking your desired number of elements.
The sequence of swapping elements is reversed from default; and proceeds from the first element to the last element, so that retrieving a subset of the collection yields the same (partial) sequence as shuffling the whole collection:
collection.TakeRandom(5).SequenceEqual(collection.Shuffle().Take(5)); // true
This algorithm is based on Durstenfeld's (modern) version of the Fisher-Yates shuffle on Wikipedia.
public static IList<T> TakeRandom<T>(this IEnumerable<T> collection, int count, Random random) => shuffle(collection, count, random);
public static IList<T> Shuffle<T>(this IEnumerable<T> collection, Random random) => shuffle(collection, null, random);
private static IList<T> shuffle<T>(IEnumerable<T> collection, int? take, Random random)
{
var a = collection.ToArray();
var n = a.Length;
if (take <= 0 || take > n) throw new ArgumentException("Invalid number of elements to return.");
var end = take ?? n;
for (int i = 0; i < end; i++)
{
var j = random.Next(i, n);
(a[i], a[j]) = (a[j], a[i]);
}
if (take.HasValue) return new ArraySegment<T>(a, 0, take.Value);
return a;
}
Implementation:
public static class ListExtensions
{
public static void Shuffle<T>(this IList<T> list, Random random)
{
for (var i = list.Count - 1; i > 0; i--)
{
int indexToSwap = random.Next(i + 1);
(list[indexToSwap], list[i]) = (list[i], list[indexToSwap]);
}
}
}
Example:
var random = new Random();
var array = new [] { 1, 2, 3 };
array.Shuffle(random);
foreach (var item in array) {
Console.WriteLine(item);
}
Demonstration in .NET Fiddle
Here's an efficient Shuffler that returns a byte array of shuffled values. It never shuffles more than is needed. It can be restarted from where it previously left off. My actual implementation (not shown) is a MEF component that allows a user specified replacement shuffler.
public byte[] Shuffle(byte[] array, int start, int count)
{
int n = array.Length - start;
byte[] shuffled = new byte[count];
for(int i = 0; i < count; i++, start++)
{
int k = UniformRandomGenerator.Next(n--) + start;
shuffled[i] = array[k];
array[k] = array[start];
array[start] = shuffled[i];
}
return shuffled;
}
`
Your question is how to randomize a list. This means:
All unique combinations should be possible of happening
All unique combinations should occur with the same distribution (AKA being non-biased).
A large number of the answers posted for this question do NOT satisfy the two requirements above for being "random".
Here's a compact, non-biased pseudo-random function following the Fisher-Yates shuffle method.
public static void Shuffle<T>(this IList<T> list, Random rnd)
{
for (var i = list.Count-1; i > 0; i--)
{
var randomIndex = rnd.Next(i + 1); //maxValue (i + 1) is EXCLUSIVE
list.Swap(i, randomIndex);
}
}
public static void Swap<T>(this IList<T> list, int indexA, int indexB)
{
var temp = list[indexA];
list[indexA] = list[indexB];
list[indexB] = temp;
}
Here's a thread-safe way to do this:
public static class EnumerableExtension
{
private static Random globalRng = new Random();
[ThreadStatic]
private static Random _rng;
private static Random rng
{
get
{
if (_rng == null)
{
int seed;
lock (globalRng)
{
seed = globalRng.Next();
}
_rng = new Random(seed);
}
return _rng;
}
}
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> items)
{
return items.OrderBy (i => rng.Next());
}
}
public Deck(IEnumerable<Card> initialCards)
{
cards = new List<Card>(initialCards);
public void Shuffle()
}
{
List<Card> NewCards = new List<Card>();
while (cards.Count > 0)
{
int CardToMove = random.Next(cards.Count);
NewCards.Add(cards[CardToMove]);
cards.RemoveAt(CardToMove);
}
cards = NewCards;
}
public IEnumerable<string> GetCardNames()
{
string[] CardNames = new string[cards.Count];
for (int i = 0; i < cards.Count; i++)
CardNames[i] = cards[i].Name;
return CardNames;
}
Deck deck1;
Deck deck2;
Random random = new Random();
public Form1()
{
InitializeComponent();
ResetDeck(1);
ResetDeck(2);
RedrawDeck(1);
RedrawDeck(2);
}
private void ResetDeck(int deckNumber)
{
if (deckNumber == 1)
{
int numberOfCards = random.Next(1, 11);
deck1 = new Deck(new Card[] { });
for (int i = 0; i < numberOfCards; i++)
deck1.Add(new Card((Suits)random.Next(4),(Values)random.Next(1, 14)));
deck1.Sort();
}
else
deck2 = new Deck();
}
private void reset1_Click(object sender, EventArgs e) {
ResetDeck(1);
RedrawDeck(1);
}
private void shuffle1_Click(object sender, EventArgs e)
{
deck1.Shuffle();
RedrawDeck(1);
}
private void moveToDeck1_Click(object sender, EventArgs e)
{
if (listBox2.SelectedIndex >= 0)
if (deck2.Count > 0) {
deck1.Add(deck2.Deal(listBox2.SelectedIndex));
}
RedrawDeck(1);
RedrawDeck(2);
}
private List<GameObject> ShuffleList(List<GameObject> ActualList) {
List<GameObject> newList = ActualList;
List<GameObject> outList = new List<GameObject>();
int count = newList.Count;
while (newList.Count > 0) {
int rando = Random.Range(0, newList.Count);
outList.Add(newList[rando]);
newList.RemoveAt(rando);
}
return (outList);
}
usage :
List<GameObject> GetShuffle = ShuffleList(ActualList);
Old post for sure, but I just use a GUID.
Items = Items.OrderBy(o => Guid.NewGuid().ToString()).ToList();
A GUID is always unique, and since it is regenerated every time the result changes each time.
A very simple approach to this kind of problem is to use a number of random element swap in the list.
In pseudo-code this would look like this:
do
r1 = randomPositionInList()
r2 = randomPositionInList()
swap elements at index r1 and index r2
for a certain number of times
What is the best way to randomize the order of a generic list in C#? I've got a finite set of 75 numbers in a list I would like to assign a random order to, in order to draw them for a lottery type application.
Shuffle any (I)List with an extension method based on the Fisher-Yates shuffle:
private static Random rng = new Random();
public static void Shuffle<T>(this IList<T> list)
{
int n = list.Count;
while (n > 1) {
n--;
int k = rng.Next(n + 1);
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
Usage:
List<Product> products = GetProducts();
products.Shuffle();
The code above uses the much criticised System.Random method to select swap candidates. It's fast but not as random as it should be. If you need a better quality of randomness in your shuffles use the random number generator in System.Security.Cryptography like so:
using System.Security.Cryptography;
...
public static void Shuffle<T>(this IList<T> list)
{
RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider();
int n = list.Count;
while (n > 1)
{
byte[] box = new byte[1];
do provider.GetBytes(box);
while (!(box[0] < n * (Byte.MaxValue / n)));
int k = (box[0] % n);
n--;
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
A simple comparison is available at this blog (WayBack Machine).
Edit: Since writing this answer a couple years back, many people have commented or written to me, to point out the big silly flaw in my comparison. They are of course right. There's nothing wrong with System.Random if it's used in the way it was intended. In my first example above, I instantiate the rng variable inside of the Shuffle method, which is asking for trouble if the method is going to be called repeatedly. Below is a fixed, full example based on a really useful comment received today from #weston here on SO.
Program.cs:
using System;
using System.Collections.Generic;
using System.Threading;
namespace SimpleLottery
{
class Program
{
private static void Main(string[] args)
{
var numbers = new List<int>(Enumerable.Range(1, 75));
numbers.Shuffle();
Console.WriteLine("The winning numbers are: {0}", string.Join(", ", numbers.GetRange(0, 5)));
}
}
public static class ThreadSafeRandom
{
[ThreadStatic] private static Random Local;
public static Random ThisThreadsRandom
{
get { return Local ?? (Local = new Random(unchecked(Environment.TickCount * 31 + Thread.CurrentThread.ManagedThreadId))); }
}
}
static class MyExtensions
{
public static void Shuffle<T>(this IList<T> list)
{
int n = list.Count;
while (n > 1)
{
n--;
int k = ThreadSafeRandom.ThisThreadsRandom.Next(n + 1);
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
}
}
If we only need to shuffle items in a completely random order (just to mix the items in a list), I prefer this simple yet effective code that orders items by guid...
var shuffledcards = cards.OrderBy(a => Guid.NewGuid()).ToList();
As people have pointed out in the comments, GUIDs are not guaranteed to be random, so we should be using a real random number generator instead:
private static Random rng = new Random();
...
var shuffledcards = cards.OrderBy(a => rng.Next()).ToList();
I'm bit surprised by all the clunky versions of this simple algorithm here. Fisher-Yates (or Knuth shuffle) is bit tricky but very compact. Why is it tricky? Because your need to pay attention to whether your random number generator r(a,b) returns value where b is inclusive or exclusive. I've also edited Wikipedia description so people don't blindly follow pseudocode there and create hard to detect bugs. For .Net, Random.Next(a,b) returns number exclusive of b so without further ado, here's how it can be implemented in C#/.Net:
public static void Shuffle<T>(this IList<T> list, Random rnd)
{
for(var i=list.Count; i > 0; i--)
list.Swap(0, rnd.Next(0, i));
}
public static void Swap<T>(this IList<T> list, int i, int j)
{
var temp = list[i];
list[i] = list[j];
list[j] = temp;
}
Try this code.
Extension method for IEnumerable:
public static IEnumerable<T> Randomize<T>(this IEnumerable<T> source)
{
Random rnd = new Random();
return source.OrderBy<T, int>((item) => rnd.Next());
}
Idea is get anonymous object with item and random order and then reorder items by this order and return value:
var result = items.Select(x => new { value = x, order = rnd.Next() })
.OrderBy(x => x.order).Select(x => x.value).ToList()
public static List<T> Randomize<T>(List<T> list)
{
List<T> randomizedList = new List<T>();
Random rnd = new Random();
while (list.Count > 0)
{
int index = rnd.Next(0, list.Count); //pick a random item from the master list
randomizedList.Add(list[index]); //place it at the end of the randomized list
list.RemoveAt(index);
}
return randomizedList;
}
EDIT
The RemoveAt is a weakness in my previous version. This solution overcomes that.
public static IEnumerable<T> Shuffle<T>(
this IEnumerable<T> source,
Random generator = null)
{
if (generator == null)
{
generator = new Random();
}
var elements = source.ToArray();
for (var i = elements.Length - 1; i >= 0; i--)
{
var swapIndex = generator.Next(i + 1);
yield return elements[swapIndex];
elements[swapIndex] = elements[i];
}
}
Note the optional Random generator, if the base framework implementation of Random is not thread-safe or cryptographically strong enough for your needs, you can inject your implementation into the operation.
A suitable implementation for a thread-safe cryptographically strong Random implementation can be found in this answer.
Here's an idea, extend IList in a (hopefully) efficient way.
public static IEnumerable<T> Shuffle<T>(this IList<T> list)
{
var choices = Enumerable.Range(0, list.Count).ToList();
var rng = new Random();
for(int n = choices.Count; n > 1; n--)
{
int k = rng.Next(n);
yield return list[choices[k]];
choices.RemoveAt(k);
}
yield return list[choices[0]];
}
This is my preferred method of a shuffle when it's desirable to not modify the original. It's a variant of the Fisher–Yates "inside-out" algorithm that works on any enumerable sequence (the length of source does not need to be known from start).
public static IList<T> NextList<T>(this Random r, IEnumerable<T> source)
{
var list = new List<T>();
foreach (var item in source)
{
var i = r.Next(list.Count + 1);
if (i == list.Count)
{
list.Add(item);
}
else
{
var temp = list[i];
list[i] = item;
list.Add(temp);
}
}
return list;
}
This algorithm can also be implemented by allocating a range from 0 to length - 1 and randomly exhausting the indices by swapping the randomly chosen index with the last index until all indices have been chosen exactly once. This above code accomplishes the exact same thing but without the additional allocation. Which is pretty neat.
With regards to the Random class it's a general purpose number generator (and If I was running a lottery I'd consider using something different). It also relies on a time based seed value by default. A small alleviation of the problem is to seed the Random class with the RNGCryptoServiceProvider or you could use the RNGCryptoServiceProvider in a method similar to this (see below) to generate uniformly chosen random double floating point values but running a lottery pretty much requires understanding randomness and the nature of the randomness source.
var bytes = new byte[8];
_secureRng.GetBytes(bytes);
var v = BitConverter.ToUInt64(bytes, 0);
return (double)v / ((double)ulong.MaxValue + 1);
The point of generating a random double (between 0 and 1 exclusively) is to use to scale to an integer solution. If you need to pick something from a list based on a random double x that's always going to be 0 <= x && x < 1 is straight forward.
return list[(int)(x * list.Count)];
Enjoy!
If you don't mind using two Lists, then this is probably the easiest way to do it, but probably not the most efficient or unpredictable one:
List<int> xList = new List<int>() { 1, 2, 3, 4, 5 };
List<int> deck = new List<int>();
foreach (int xInt in xList)
deck.Insert(random.Next(0, deck.Count + 1), xInt);
I usually use:
var list = new List<T> ();
fillList (list);
var randomizedList = new List<T> ();
var rnd = new Random ();
while (list.Count != 0)
{
var index = rnd.Next (0, list.Count);
randomizedList.Add (list [index]);
list.RemoveAt (index);
}
You can achieve that be using this simple extension method
public static class IEnumerableExtensions
{
public static IEnumerable<t> Randomize<t>(this IEnumerable<t> target)
{
Random r = new Random();
return target.OrderBy(x=>(r.Next()));
}
}
and you can use it by doing the following
// use this on any collection that implements IEnumerable!
// List, Array, HashSet, Collection, etc
List<string> myList = new List<string> { "hello", "random", "world", "foo", "bar", "bat", "baz" };
foreach (string s in myList.Randomize())
{
Console.WriteLine(s);
}
Just wanted to suggest a variant using an IComparer<T> and List.Sort():
public class RandomIntComparer : IComparer<int>
{
private readonly Random _random = new Random();
public int Compare(int x, int y)
{
return _random.Next(-1, 2);
}
}
Usage:
list.Sort(new RandomIntComparer());
One can use the Shuffle extension methond from morelinq package, it works on IEnumerables
install-package morelinq
using MoreLinq;
...
var randomized = list.Shuffle();
If you have a fixed number (75), you could create an array with 75 elements, then enumerate your list, moving the elements to randomized positions in the array. You can generate the mapping of list number to array index using the Fisher-Yates shuffle.
You can make the Fisher-Yates shuffle more terse and expressive by using tuples for the swap.
private static readonly Random random = new Random();
public static void Shuffle<T>(this IList<T> list)
{
int n = list.Count;
while (n > 1)
{
n--;
int k = random.Next(n + 1);
(list[k], list[n]) = (list[n], list[k]);
}
}
I have found an interesting solution online.
Courtesy: https://improveandrepeat.com/2018/08/a-simple-way-to-shuffle-your-lists-in-c/
var shuffled = myList.OrderBy(x => Guid.NewGuid()).ToList();
We can use an extension method for List and use a thread-safe random generator combination. I've packaged an improved version of this on NuGet with the source code available on GitHub. The NuGet version contains optional cryptographically-strong random.
Pre-.NET 6.0 version:
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Shuffle<T>(this IList<T> list)
{
if (list == null) throw new ArgumentNullException(nameof(list));
int n = list.Count;
while (n > 1)
{
int k = ThreadSafeRandom.Instance.Next(n--);
(list[n], list[k]) = (list[k], list[n]);
}
}
internal class ThreadSafeRandom
{
public static Random Instance => _local.Value;
private static readonly Random _global = new Random();
private static readonly ThreadLocal<Random> _local = new ThreadLocal<Random>(() =>
{
int seed;
lock (_global)
{
seed = _global.Next();
}
return new Random(seed);
});
}
On .NET 6.0 or later:
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Shuffle<T>(this IList<T> list)
{
ArgumentNullException.ThrowIfNull(list);
int n = list.Count;
while (n > 1)
{
int k = Random.Shared.Next(n--);
(list[n], list[k]) = (list[k], list[n]);
}
}
Install the library via NuGet for more features.
A simple modification of the accepted answer that returns a new list instead of working in-place, and accepts the more general IEnumerable<T> as many other Linq methods do.
private static Random rng = new Random();
/// <summary>
/// Returns a new list where the elements are randomly shuffled.
/// Based on the Fisher-Yates shuffle, which has O(n) complexity.
/// </summary>
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> list) {
var source = list.ToList();
int n = source.Count;
var shuffled = new List<T>(n);
shuffled.AddRange(source);
while (n > 1) {
n--;
int k = rng.Next(n + 1);
T value = shuffled[k];
shuffled[k] = shuffled[n];
shuffled[n] = value;
}
return shuffled;
}
List<T> OriginalList = new List<T>();
List<T> TempList = new List<T>();
Random random = new Random();
int length = OriginalList.Count;
int TempIndex = 0;
while (length > 0) {
TempIndex = random.Next(0, length); // get random value between 0 and original length
TempList.Add(OriginalList[TempIndex]); // add to temp list
OriginalList.RemoveAt(TempIndex); // remove from original list
length = OriginalList.Count; // get new list <T> length.
}
OriginalList = new List<T>();
OriginalList = TempList; // copy all items from temp list to original list.
Here is an implementation of the Fisher-Yates shuffle that allows specification of the number of elements to return; hence, it is not necessary to first sort the whole collection before taking your desired number of elements.
The sequence of swapping elements is reversed from default; and proceeds from the first element to the last element, so that retrieving a subset of the collection yields the same (partial) sequence as shuffling the whole collection:
collection.TakeRandom(5).SequenceEqual(collection.Shuffle().Take(5)); // true
This algorithm is based on Durstenfeld's (modern) version of the Fisher-Yates shuffle on Wikipedia.
public static IList<T> TakeRandom<T>(this IEnumerable<T> collection, int count, Random random) => shuffle(collection, count, random);
public static IList<T> Shuffle<T>(this IEnumerable<T> collection, Random random) => shuffle(collection, null, random);
private static IList<T> shuffle<T>(IEnumerable<T> collection, int? take, Random random)
{
var a = collection.ToArray();
var n = a.Length;
if (take <= 0 || take > n) throw new ArgumentException("Invalid number of elements to return.");
var end = take ?? n;
for (int i = 0; i < end; i++)
{
var j = random.Next(i, n);
(a[i], a[j]) = (a[j], a[i]);
}
if (take.HasValue) return new ArraySegment<T>(a, 0, take.Value);
return a;
}
Implementation:
public static class ListExtensions
{
public static void Shuffle<T>(this IList<T> list, Random random)
{
for (var i = list.Count - 1; i > 0; i--)
{
int indexToSwap = random.Next(i + 1);
(list[indexToSwap], list[i]) = (list[i], list[indexToSwap]);
}
}
}
Example:
var random = new Random();
var array = new [] { 1, 2, 3 };
array.Shuffle(random);
foreach (var item in array) {
Console.WriteLine(item);
}
Demonstration in .NET Fiddle
Here's an efficient Shuffler that returns a byte array of shuffled values. It never shuffles more than is needed. It can be restarted from where it previously left off. My actual implementation (not shown) is a MEF component that allows a user specified replacement shuffler.
public byte[] Shuffle(byte[] array, int start, int count)
{
int n = array.Length - start;
byte[] shuffled = new byte[count];
for(int i = 0; i < count; i++, start++)
{
int k = UniformRandomGenerator.Next(n--) + start;
shuffled[i] = array[k];
array[k] = array[start];
array[start] = shuffled[i];
}
return shuffled;
}
`
Your question is how to randomize a list. This means:
All unique combinations should be possible of happening
All unique combinations should occur with the same distribution (AKA being non-biased).
A large number of the answers posted for this question do NOT satisfy the two requirements above for being "random".
Here's a compact, non-biased pseudo-random function following the Fisher-Yates shuffle method.
public static void Shuffle<T>(this IList<T> list, Random rnd)
{
for (var i = list.Count-1; i > 0; i--)
{
var randomIndex = rnd.Next(i + 1); //maxValue (i + 1) is EXCLUSIVE
list.Swap(i, randomIndex);
}
}
public static void Swap<T>(this IList<T> list, int indexA, int indexB)
{
var temp = list[indexA];
list[indexA] = list[indexB];
list[indexB] = temp;
}
Here's a thread-safe way to do this:
public static class EnumerableExtension
{
private static Random globalRng = new Random();
[ThreadStatic]
private static Random _rng;
private static Random rng
{
get
{
if (_rng == null)
{
int seed;
lock (globalRng)
{
seed = globalRng.Next();
}
_rng = new Random(seed);
}
return _rng;
}
}
public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> items)
{
return items.OrderBy (i => rng.Next());
}
}
public Deck(IEnumerable<Card> initialCards)
{
cards = new List<Card>(initialCards);
public void Shuffle()
}
{
List<Card> NewCards = new List<Card>();
while (cards.Count > 0)
{
int CardToMove = random.Next(cards.Count);
NewCards.Add(cards[CardToMove]);
cards.RemoveAt(CardToMove);
}
cards = NewCards;
}
public IEnumerable<string> GetCardNames()
{
string[] CardNames = new string[cards.Count];
for (int i = 0; i < cards.Count; i++)
CardNames[i] = cards[i].Name;
return CardNames;
}
Deck deck1;
Deck deck2;
Random random = new Random();
public Form1()
{
InitializeComponent();
ResetDeck(1);
ResetDeck(2);
RedrawDeck(1);
RedrawDeck(2);
}
private void ResetDeck(int deckNumber)
{
if (deckNumber == 1)
{
int numberOfCards = random.Next(1, 11);
deck1 = new Deck(new Card[] { });
for (int i = 0; i < numberOfCards; i++)
deck1.Add(new Card((Suits)random.Next(4),(Values)random.Next(1, 14)));
deck1.Sort();
}
else
deck2 = new Deck();
}
private void reset1_Click(object sender, EventArgs e) {
ResetDeck(1);
RedrawDeck(1);
}
private void shuffle1_Click(object sender, EventArgs e)
{
deck1.Shuffle();
RedrawDeck(1);
}
private void moveToDeck1_Click(object sender, EventArgs e)
{
if (listBox2.SelectedIndex >= 0)
if (deck2.Count > 0) {
deck1.Add(deck2.Deal(listBox2.SelectedIndex));
}
RedrawDeck(1);
RedrawDeck(2);
}
private List<GameObject> ShuffleList(List<GameObject> ActualList) {
List<GameObject> newList = ActualList;
List<GameObject> outList = new List<GameObject>();
int count = newList.Count;
while (newList.Count > 0) {
int rando = Random.Range(0, newList.Count);
outList.Add(newList[rando]);
newList.RemoveAt(rando);
}
return (outList);
}
usage :
List<GameObject> GetShuffle = ShuffleList(ActualList);
Old post for sure, but I just use a GUID.
Items = Items.OrderBy(o => Guid.NewGuid().ToString()).ToList();
A GUID is always unique, and since it is regenerated every time the result changes each time.
A very simple approach to this kind of problem is to use a number of random element swap in the list.
In pseudo-code this would look like this:
do
r1 = randomPositionInList()
r2 = randomPositionInList()
swap elements at index r1 and index r2
for a certain number of times
I have created a short program that creates 3 random integers between 1-9 and stores them in an array, however, I would not like any of them to repeat, that is, I would like each to be unique. Is there an easier way to generate 3 unique integers other than having to iterate through the array and comparing each integer to each other? That just seems so tedious if I were to increase my array to beyond 3 integers.
This is my code to generate 3 random numbers. I saw other code in Java, but I thought maybe C# has a easier and more efficient way to do it.
var number = new Numbers[3];
Random r = new Random();
for ( int i = 0; i < number.Length; i++)
{
number[i] = new Numbers(r.Next(1,9));
}
Console.WriteLine("The Three Random Numbers Are:");
foreach(Numbers num in number)
{
Console.WriteLine("{0}", num.Number);
}
I would do something like this:
var range = Enumerable.Range(1, 8);
var rnd = new Random();
var listInts = range.OrderBy(i => rnd.Next()).Take(3).ToList();
You could make an array or a list of the numbers that might be generated, e.g. 0, 1, 2, 3. Then you generate a number from 0 to this list's length, e.g. 2 and pick list[2] so for the next time you only have 0, 1, 3 in your list.
It takes longer to generate it, especially for long lists but it doesn't repeat numbers.
using System;
using System.Collections.Generic;
public class Test
{
static Random random = new Random();
public static List<int> GenerateRandom(int count)
{
// generate count random values.
HashSet<int> candidates = new HashSet<int>();
// top will overflow to Int32.MinValue at the end of the loop
for (Int32 top = Int32.MaxValue - count + 1; top > 0; top++)
{
// May strike a duplicate.
if (!candidates.Add(random.Next(top))) {
candidates.Add(top);
}
}
// load them in to a list.
List<int> result = new List<int>();
result.AddRange(candidates);
// shuffle the results:
int i = result.Count;
while (i > 1)
{
i--;
int k = random.Next(i + 1);
int value = result[k];
result[k] = result[i];
result[i] = value;
}
return result;
}
public static void Main()
{
List<int> vals = GenerateRandom(10);
Console.WriteLine("Result: " + vals.Count);
vals.ForEach(Console.WriteLine);
}
}
Grate explanation and answers from here
Source http://ideone.com/Zjpzdh
This question already has answers here:
Is using Random and OrderBy a good shuffle algorithm? [closed]
(13 answers)
Closed 9 years ago.
Part 1: All I am wanting to achieve is to write the numbers 1, 2, 3 ... 8, 9, 10 to the console window in random order. So all the numbers will need to be written to console window, but the order of them must be random.
Part 2: In my actual project I plan to write all of the elements in an array, to the console window in random order. I am assuming that if I can get the answer to part 1, I should easily be able to implement this with an array.
/// <summary>
/// Returns all numbers, between min and max inclusive, once in a random sequence.
/// </summary>
IEnumerable<int> UniqueRandom(int minInclusive, int maxInclusive)
{
List<int> candidates = new List<int>();
for (int i = minInclusive; i <= maxInclusive; i++)
{
candidates.Add(i);
}
Random rnd = new Random();
while (candidates.Count > 0)
{
int index = rnd.Next(candidates.Count);
yield return candidates[index];
candidates.RemoveAt(index);
}
}
In your program
Console.WriteLine("All numbers between 0 and 10 in random order:");
foreach (int i in UniqueRandom(0, 10)) {
Console.WriteLine(i);
}
Enumerable.Range(1, 10).OrderBy(i => Guid.NewGuid()) works nicely.
using System;
using System.Collections;
namespace ConsoleApplication
{
class Numbers
{
public ArrayList RandomNumbers(int max)
{
// Create an ArrayList object that will hold the numbers
ArrayList lstNumbers = new ArrayList();
// The Random class will be used to generate numbers
Random rndNumber = new Random();
// Generate a random number between 1 and the Max
int number = rndNumber.Next(1, max + 1);
// Add this first random number to the list
lstNumbers.Add(number);
// Set a count of numbers to 0 to start
int count = 0;
do // Repeatedly...
{
// ... generate a random number between 1 and the Max
number = rndNumber.Next(1, max + 1);
// If the newly generated number in not yet in the list...
if (!lstNumbers.Contains(number))
{
// ... add it
lstNumbers.Add(number);
}
// Increase the count
count++;
} while (count <= 10 * max); // Do that again
// Once the list is built, return it
return lstNumbers;
}
}
Main
class Program
{
static int Main()
{
Numbers nbs = new Numbers();
const int Total = 10;
ArrayList lstNumbers = nbs.RandomNumbers(Total);
for (int i = 0; i < lstNumbers.Count; i++)
Console.WriteLine("{0}", lstNumbers[i].ToString());
return 0;
}
}
}
int[] ints = new int[11];
Random rand = new Random();
Random is a class built into .NET, and allows us to create random integers really, really easily. Basically all we have to do is call a method inside our rand object to get that random number, which is nice. So, inside our loop, we just set each element to the results of that method:
for (int i = 0; i < ints.Length; i++)
{
ints[i] = rand.Next(11);
}
We are essentially filling our entire array with random numbers here, all between 0 and 10. At this point all we have to do is display the contents for the user, which can be done with a foreach loop:
foreach (int i in ints)
{
Console.WriteLine(i.ToString());
}
I made a lottery program : http://yadi.sk/d/bBKefn9g4OC7s
Here is the whole source code : http://yadi.sk/d/rnQMfrry4O8cu
Random rnd = new Random();
int[] loto;
loto = new int[7];
for (int f = 1; f <= 6; f++) {
loto[f] = rnd.Next(1, 50); // Generating random number between 1-49
for (int h = 1; h < f; h++) {
if (loto[f] == loto[h]) { // Check with other numbers for the case of duplicate
loto[f] = rnd.Next(1, 50); // If there is a duplicate create that number again
}
}
}
This section I'm generating random 6 different numbers between 1-49
Also I'm wondering in this example, are nested loops increase the spontaneity ?
I'm getting 3-4 max, this program wrong or am I so unlucky ?
( note that : that's my first program )
For all guys trying to help me : I'm really beginner on programming(c# yesterday | c++ 3 weeks i guess), and if you guys clarify what you mean in codes it'll be great.
And please not give me extreme hard coding examples( I don't wanna quit c# )
Your method looks unsafe, as get value from Random again in the inner loop does not guarantee that it will return unduplicated value. For low value as 1-49, you can use simple random-picking algorithm like this
var numbers = new List<int>();
for (int i = 1; i <= 49; i++) {
numbers.Add(i);
}
Random r = new Random();
var loto = new int[6];
for (int f = 0; f < 6; f++) {
int idx = r.Next(0, numbers.Count);
loto[f] = numbers[idx];
numbers.RemoveAt(idx);
}
Note that this is far from optimal solution in terms of performance, but if you will run it only once in a few seconds or more so it should be fine.
I think it's correct except for the for loop declaration: remember that arrays in C# are zero-based. Thus the loop should look like this:
for (int f = 0; f < 7; f++)
or even better:
for (int f = 0; f < loto.Length; f++)
Update: I cannot comment the other answers (too less reputation), thus I have to post it here:
#Dan: only one loop is not correct as it is not allowed to have the same number twice in Loto. In his inner loop, 1342 checks if the created random number already exists, so it is not correct to leave it out.
#James: As 1342 just started programming, it is not necessary to use a static field in my opinion. I guess that he or she has his whole code in the Main method so there is no benefit using a static variable.
There are a few issues here - you've got one too many loops for a start, and no comments.
See this (over-commented) example below:
// This is static so we don't recreate it every time.
private static Random _rnd;
static void Main(string[] args)
{
_rnd = new Random();
// You can declare and initialise a variable in one statement.
// In this case you want the array size to be 6, not 7!
Int32[] lotoNumbers = new Int32[6];
// Generate 10 sets of 6 random numbers
for (int i = 0; i < 10; i++)
{
// Use a meaningful name for your iteration variable
// In this case I used 'idx' as in 'index'
// Arrays in c# are 0-based, so your lotto array has
// 6 elements - [0] to [5]
for (Int32 idx = 0; idx < 6; idx++)
{
// Keep looping until we have a unique number
int proposedNumber;
do
{
proposedNumber = _rnd.Next(1, 50);
} while (lotoNumbers.Contains(proposedNumber));
// Assign the unique proposed number to your array
lotoNumbers[idx] = proposedNumber;
}
}
}
You should end up with a 6 element long array with 6 random numbers between 1 and 50 in it.
Hope that helps!
Edit:
It's also well worth taking note of James' answer - if you're doing the above in a loop, you'll get the same values every time from Random, due to how the seed is used. Using a static version of Random will give much better results.
You don't want to keep re-creating a new instance of Random each time, that's the likely cause of why you keep getting similar values each time. The better approach is to create a static instance of Random and use that across your entire app - this should give you more realistic results e.g.
using System.Collections.Generic;
using System.Linq;
...
static readonly Random rand = new Random();
...
List<int> lottoNumbers = new List<int>(6);
int drawnNumber = -1;
for (int i = 0; i < lottoNumbers.Count; i++) {
do
{
drawnNumber = rand.Next(1, 50); // generate random number
}
while (lottoNumbers.Contains(drawnNumber)) // keep generating random numbers until we get one which hasn't already been drawn
lottoNumbers[i] = drawnNumber; // set the lotto number
}
// print results
foreach (var n in lottoNumbers)
Console.WriteLine(n);
For easily testing it, I have left the console logs and static void main for you.
You do not need two iterations for this. Also - arrays are 0 based, so either f has to be equal to 0, or less than 7. I went with equal 0 below.
I have created a recursive method which creates a new value and checks if the array contains the value. If it does not contain it, it adds it. But if it does contain it, the method calls itself to find a new value. It will continue to do this until a new value is found.
Recursive methods are methods which call themselves. Don't try and fill an array with an index bigger than 50 with this, as you will get an endless loop.
private static readonly Random Rnd = new Random();
static void Main(string[] args)
{
var loto = new int[7];
for (int f = 0; f <= 6; f++)
{
var randomValue = GetRandomNumberNotInArr(loto);
Console.WriteLine(randomValue);
loto[f] = randomValue;
}
Console.Read();
}
/// <summary>
/// Finds a new random value to insert into arr. If arr already contains this another
///random value will be found.
/// </summary>
/// <param name="arr">arr with already found values</param>
/// <returns></returns>
private static int GetRandomNumberNotInArr(int[] arr)
{
var next = Rnd.Next(1, 50);
return !arr.Contains(next) ? next : GetRandomNumberNotInArr(arr);
}
I can see that you are trying to simulate drawing 6 lottery numbers between 1 and 50.
Your code has some logic errors, but rather than fixing it I'm going to suggest doing it a different way.
There are several ways to approach this; a common one is this:
Create an empty collection of numbers.
while there aren't enough numbers in the collection
let randomNumber = new random number in the appropriate range
if (randomNumber isn't already in the collection)
add randomNumber to the collection
But there's another approach which scales nicely, so I'll demonstrate this one (someone else will probably already have written about the other approach):
Add to a collection all the numbers you want to choose from
Randomly rearrange (shuffle) the numbers in the collection
Draw the required number of items from the collection
This is pretty much what happens in a real-life lottery.
To shuffle a collection we can use the Fisher-Yates Shuffle. Here's an implementation:
/// <summary>Used to shuffle collections.</summary>
public class Shuffler
{
/// <summary>Shuffles the specified array.</summary>
/// <typeparam name="T">The type of the array elements.</typeparam>
/// <param name="array">The array to shuffle.</param>
public void Shuffle<T>(IList<T> array)
{
for (int n = array.Count; n > 1;)
{
int k = _rng.Next(n);
--n;
T temp = array[n];
array[n] = array[k];
array[k] = temp;
}
}
private readonly Random _rng = new Random();
}
Here's a full compilable example. I've avoided using Linq in this example because I don't want to confuse you!
using System;
using System.Collections.Generic;
namespace Demo
{
public static class Program
{
private static void Main()
{
int[] lotoDraw = createDraw();
Shuffler shuffler = new Shuffler();
shuffler.Shuffle(lotoDraw); // Now they are randomly ordered.
// We want 6 numbers, so we just draw the first 6:
int[] loto = draw(lotoDraw, 6);
// Print them out;
foreach (int ball in loto)
Console.WriteLine(ball);
}
private static int[] draw(int[] bag, int n) // Draws the first n items
{ // from the bag
int[] result = new int[n];
for (int i = 0; i < n; ++i)
result[i] = bag[i];
return result;
}
private static int[] createDraw() // Creates a collection of numbers
{ // from 1..50 to draw from.
int[] result = new int[50];
for (int i = 0; i < 50; ++i)
result[i] = i + 1;
return result;
}
}
public class Shuffler
{
public void Shuffle<T>(IList<T> list)
{
for (int n = list.Count; n > 1; )
{
int k = _rng.Next(n);
--n;
T temp = list[n];
list[n] = list[k];
list[k] = temp;
}
}
private readonly Random _rng = new Random();
}
}