Reputation: 103
How can I generate a random number from two different ranges?
For example: one number from 10-20 and 50-60.
I know how to generate a random number from one range (1-13):
Random rnd = new Random();
int num = rnd.Next(1, 13);
Upvotes: 5
Views: 7076
Reputation: 2293
A more general approach would be to make an Extension Method for the Random
class in which you add NextFromRanges
and NextDoubleFromRanges
methods. So it will work for any given number of ranges of any type.
First you need to define a Range
class. Make it generic so you can reuse it for different types, not only for example for int
ranges but also for double
.
/// <summary>The Range class.</summary>
/// <typeparam name="T">Generic parameter.</typeparam>
public class Range<T>
{
/// <summary>Minimum value of the range.</summary>
public T Minimum { get; set; }
/// <summary>Maximum value of the range.</summary>
public T Maximum { get; set; }
public Range(T min, T max)
{
Minimum = min;
Maximum = max;
}
}
public static class RandomExtension
{
static Random random = new Random();
public static int NextFromRanges(this Random random, List<Range<int>> ranges)
{
int randomRange = random.Next(0, ranges.Count);
return random.Next(ranges[randomRange].Minimum, ranges[randomRange].Maximum);
}
public static double NextDoubleFromRanges(this Random random, List<Range<double>> ranges)
{
int randomRange = random.Next(0, ranges.Count);
double doubleNrRange = ranges[randomRange].Maximum - ranges[randomRange].Minimum;
return ranges[randomRange].Minimum + random.NextDouble()*doubleNrRange;
}
}
And then you can use it like this:
//instantiate a Random generator
Random random = new Random();
//define three integer ranges
List<Range<int>> intRanges = new List<Range<int>>();
intRanges.Add(new Range<int>(0, 10));
intRanges.Add(new Range<int>(50, 60));
intRanges.Add(new Range<int>(100, 110));
//define three double ranges
List<Range<double>> doubleRanges = new List<Range<double>>();
doubleRanges.Add(new Range<double>(0, 5.5));
doubleRanges.Add(new Range<double>(50, 55.5));
doubleRanges.Add(new Range<double>(100, 105.5));
//generate a random number between one of above three ranges
//it is shown in the Visual Studio - Output window (Ctrl-W,O)
Console.WriteLine(random.NextFromRanges(intRanges));
Console.WriteLine(random.NextDoubleFromRanges(doubleRanges));
It will produce:
-random int
number between one of the three given int
ranges: 0-10, 50-60 and 100-110.
-random double
number between one of the three given double
ranges: 0-5.5, 50-55.5, 100-105.5
Just like the Next and NextDouble methods the upperbound is exclusive.
You'll now have two extra methods added to the standard Random class:
Upvotes: 2
Reputation: 21492
int num = rnd.Next(1, 3)==1 ? rnd.Next(10, 21) : rnd.Next(50,61);
or
int num = rnd.Next(10, 32);
if (num>20) num+=29;
or just for fun (don't use with large ranges, and runs slow anyhow):
var ranges=new []{ Tuple.Create(10,20), Tuple.Create(50,60)};
var rnd=new Random();
var possible=ranges.Select(x=>Enumerable.Range(x.Item1,x.Item2-x.Item1+1))
.SelectMany(x=>x)
.Distinct();
var num=possible.Skip(rnd.Next(0,possible.Count())).First();
Upvotes: 6
Reputation: 2166
You could write your own Random class. Where you rewrite the Next method with a new overload that would accept an even number of arguments.
It would look something like:
Random.NextFromGroups(10, 20, 50, 60, 100, 110);
Where the number-pairs mean the ranges.
Signature:
int NextFromGroups(params int[]);
and it would throw an Exception when it gets an odd number of arguments.
Upvotes: -2
Reputation: 6717
You are generating 22 distinct random numbers, 10-20 and 50-60. So do that first:
int randomNumber = rnd.Next(0, 22);
Now, you have random numbers from 0 to 21.
Add ten:
randomNumber += 10;
Now, you have random numbers between from 10 to 31.
Add 29 for all numbers >= 21:
if (randomNumber >= 21) {
randomNumber += 29;
}
Now, you have random numbers from 10 to 20, and from 50 to 60.
Upvotes: 2
Reputation: 8807
Remember for the Next method, the lower bound is inclusive, while the upper bound is exclusive. How about:
var rand = new Random();
var num1 = rand.Next(10, 21);
var num2 = rand.Next(50, 61);
var myNum = rand.Next(0, 2) == 1 ? num1 : num2;
Upvotes: 2