Given an algorithm capable of catching the n-th combination, you just need to use random integer numbers to get the games.
Class to obtain the nth combination
I made a class able to get the nth combination. Just instantiate it, passing the number of elements to be returned (in case 15), and an array with all possible elements (array of numbers from 1 to 25). After created call the method PegarCombinacao
passing the combination index, with 0 being the first possible and 3268759 the last possible.
Speed guarantees
The advantage in speed is exactly in the fact that we represent any of the possible games, simply as being a int
... where selecting whole numbers at random is very fast.
Also, the class of catching the nth combination, is made without iterating over all combinations. I use a summation-based algorithm to find the exact combination without having to iterate. For 15 elements to be returned, the maximum iteration of this algorithm is 15 * 15 in the worst case, and 1 * 1 in the best case.
Class code
public class Combinador<T>
{
private readonly int _cnt;
private readonly T[] _items;
private readonly List<int[]> _somatorios;
public Combinador(int cnt, T[] items)
{
_cnt = cnt;
_items = items;
var line0 = new[] { 1 }.Concat(Enumerable.Repeat(0, cnt)).ToArray();
var lines = new List<int[]>(cnt) { line0 };
for (int itLine = 1; itLine <= cnt; itLine++)
{
var prevLine = lines[itLine - 1];
var newLine = new int[line0.Length];
for (int itCol = 0; itCol < newLine.Length; itCol++)
newLine[itCol] = (itCol > 0 ? newLine[itCol - 1] : 0) + prevLine[itCol];
lines.Add(newLine);
}
_somatorios = lines;
}
public T[] PegarCombinacao(int seed)
{
return GerarIndices(_somatorios, _items.Length - _cnt, _cnt, seed)
.Select(i => _items[i])
.ToArray();
}
private static IEnumerable<int> GerarIndices(List<int[]> lines, int fs, int ts, int num)
{
if (ts <= 0) yield break;
var line = lines[ts];
var min = 0;
for (int itFs = 0; itFs <= fs; itFs++)
{
var max = min + line[itFs];
if (num < max)
{
var num2 = num - min;
yield return fs - itFs;
foreach (var idx in GerarIndices(lines, itFs, ts - 1, num2))
yield return fs - itFs + idx + 1;
yield break;
}
min = max;
}
throw new Exception("O parâmetro deve ser menor que " + min);
}
}
Example of use
Read the comments, they are very important.
var comb = new Combinador<int>(15, Enumerable.Range(1, 25).ToArray());
var rnd = new Random();
// Criando os jogos de 1 a 1 e colocando num HashSet até ter N elementos
// esse método é rápido para poucas combinações, e vai ficando mais lento
// tendendo a infinito quando o número se aproxima da quantidade máxima.
// Mesmo assim, essa técnica é a recomendável para até 3 milhões de jogos.
// Use para 0% até 95% de todas as alternativas.
var numeros = new HashSet<int>();
int tentativas = 0;
while (numeros.Count < 200000)
{
numeros.Add(rnd.Next(3268760));
tentativas++;
}
var jogosAleatorios2 = numeros
.Select(comb.PegarCombinacao)
.ToArray();
// Criando todos os jogos e pegando N aleatórios
// esse método é lento, e não recomendo se não for
// gerar todos os jogos ou algo muito próximo de todos.
// Use somente para 95% até 100% de todas as alternativas.
var jogosAleatorios1 = Enumerable.Range(0, 3268760)
.OrderBy(a => rnd.Next())
.Select(comb.PegarCombinacao)
.Take(100000)
.ToArray();
The recommendations I made in the comments are based on tests performed on my machine, it may be that in your results are a little different.
What’s the question? Do you want to write a program that picks sets of 15 random numbers without repeating? Have you tried something? What went wrong in its implementation?
– Guilherme Bernal
In this community, we help solve problems with code and we don’t work for free. Please show us what you have tried and are struggling with. If you do not know where to start, show us what you have researched and what you have so far. Don’t be offended, it’s nothing personal. It’s just how this community is. If you have questions, please read the Faq.
– Ricardo Souza
If you think about it, "working for free," the community becomes meaningless. Any doubt that is solved (via code or not) in the end someone worked to solve it (used their experience or knowledge).
– Douglas Cristhian
Douglas, instead of creating a comment, when you want to add details or information to your question edit it. So no one will miss the extra context by not having read the comment. This time I did it for you, but always try to remember this.
– Gabe