Lotofácil Betting Algorithm

9

One of the ways to bet on lotto is to choose 15 numbers from 1 to 25. I would like an algorithm in C # to generate bets. Remember that in each combination the numbers can not be repeated among themselves and bets should not be repeated.

I already did something but it was not good. My strategy was to create a 15-number arraylist, for each position to generate a 1-to-25 rpm number, and check if that number was in some other position, in the end I would sort the numbers and check if there were any other bets with them numbers, if it did not exist I would store it. I would like to know new ways of thinking.

    
asked by anonymous 27.03.2014 / 15:44

3 answers

9

I would do it this way.

Solution 1

  • Would create a list of 25 numbered positions from 1 to 25
  • Would make multiple shuffles in the list
  • Get the first 15 elements
  • I would check if I do not already have these 15 numbers
  • Repeat the process for the number of times needed

Solution 2

  • Generate all 3,268,760
  • I would randomly choose how many I need

The choice between each solution depends on the choice of space / time.

If you need the algorithm here has the theoretical basis and several implementations including C # .

    
27.03.2014 / 15:56
8

Given an algorithm that can take the nth match, you just have to use random integers to get the games.

Class to get the nth combination

I made a class capable of getting the nth combination. Simply 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). Once created, call the PegarCombinacao method by passing the combination index, 0 being the first possible and 3268759 the last possible.

Speed guarantees

The advantage in speed is precisely in that we represent any of the possible games, simply being int ... being that selecting integers at random is very fast.

In addition, the class of picking the nth combination, is done 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 iterations 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 run on my machine, it may be that your results are a bit different.

    
27.03.2014 / 20:11
4

Since I'm cool, I've developed a routine that generates these "games" randomly.

Take a look:

  public List<int>[] GeraJogos(int numeroDeJogos)
    {
        List<int>[] jogos = new List<int>[numeroDeJogos];
        int i = 0;


        while (i < numeroDeJogos)
        {
            var lotoFacil = new List<int>();
            lotoFacil = LotoFacil();

            if (jogos.Contains(lotoFacil))
            {
                continue;
            }

            jogos[i] = lotoFacil;
            i++;
        }

        return jogos;
    }

    public List<int> LotoFacil()
    {
        var resultado = new List<int>();

        var randow = new Random();
        int randowNumber;
        int i = 0;

        while (i < 15)
        {
            randowNumber = randow.Next(1, 25);

            if (resultado.Contains(randowNumber))
            {
                continue;
            }

            resultado.Add(randowNumber);
            i++;
        }

        return resultado;
    }
    
27.03.2014 / 16:35