public bool GeraCombinacoes(out List <StructResultados> Matriz, int[] VDezenas, int s) { Matriz = new List <StructResultados>(); StructResultados StrTmp = new StructResultados(); StrTmp.Dezenas = new List <int>(s); int i = 0, j = 0; int n = VDezenas.Length; int[] VCombIndex = new int[s]; int len = (int)AnaliseCombinatoria.numCombin(VDezenas.Length, s); if (len >= 252) { if (System.Windows.Forms.MessageBox.Show("Encontradas " + len.ToString() + " Combinações! Continuar com Processamento?", "TearDown - Imprimir " + MainWindow.NomeLoteria, System.Windows.Forms.MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.No) { return(false); } } // Primeira Combinação for (i = 0; i < s; ++i) { VCombIndex[i] = i; } // Pega as Dezenas em VDezenas de acordo com os indices da primeira combinação for (j = 0; j < VCombIndex.Length; j++) { StrTmp.Dezenas.Add(VDezenas[VCombIndex[j]]); } Matriz.Add(StrTmp); int ret = 1; // Pega as outras dezenas em VDezenas de acordo com os indices das outras combinações while (ret != 0) { ret = ProxCombinacao(VCombIndex, s, n); if (ret == 0) { break; } StrTmp = new StructResultados(); StrTmp.Dezenas = new List <int>(s); for (j = 0; j < VCombIndex.Length; j++) { StrTmp.Dezenas.Add(VDezenas[VCombIndex[j]]); } Matriz.Add(StrTmp); } return(true); }
public bool CombinarDezenas(out decimal Sorteios, out List <Tuple <int, int> > ListaSorteios, out List <StructResultados> Matriz, int[] VDezenas, decimal s) { Sorteios = 0; int found = 0; AnaliseCombinatoria AnComb = new AnaliseCombinatoria(); ulong[] iret; bool ret = AnComb.MainComb(1, VDezenas.Length, (int)s, 1, out iret); int[] Combinacoes = new int[iret[0]]; Matriz = new List <StructResultados>(); ListaSorteios = new List <Tuple <int, int> >(); try { ret = AnComb.GeraCombinacoes(out Matriz, VDezenas, (int)s); if (ret) { for (int j = 0; j < Matriz.Count; j++) { foreach (var jogo in MainWindow.Resultados) { found = 0; for (int k = 0; k < Matriz[j].Dezenas.Count; k++) { foreach (var dezena in jogo.Dezenas) { if (dezena == Matriz[j].Dezenas[k]) { found++; } } if (found == Matriz[j].Dezenas.Count) { var tup = new Tuple <int, int>(j, jogo.Sorteio); ListaSorteios.Add(tup); Sorteios++; } } } } return(true); } else { return(false); } } catch { return(false); } }
/// <summary> /// Método para converter um Número de Sequência de Combinação (CSN) para uma combinação /// </summary> /// <remarks>Baseado no algoritmo ACM #515 de B. P. Buckles e M. Lyabanon (1974)</remarks> /// <param name="csn">Número de Sequência de Combinação</param> /// <param name="n">Tamanho do set</param> /// <param name="k">Tamanho do subset</param> /// <returns>Combinação em array</returns> public static int[] csnToComb(int csn, int n, int k) { int lbound = 0; int r = 0; int[] comb = new int[k]; for (int i = 0; i < (k - 1); i++) { // colocar sempre o valor a 0 comb[i] = 0; // se a posição não for a 0, podemos copiar o valor de trás // se for... bem, atrás não está nada e, não sei porquê, os computadores gostam pouco disso... if (i != 0) { comb[i] = comb[i - 1]; } // fazer isto pelo menos uma vez (porque o valor ou está a 0 ou está igual ao precedente) do { // incrementar o bitxo comb[i]++; /* * E aqui é melhor dar um exemplo prático... * Imaginemos que estamos na chave 1-2-3-4-5 e o nosso número máximo é o 10 * Queremos a chave seguinte, isto é, CSN = 2, já estivemos em i=0, 1 e 2, vamos no 3; * chegamos aqui assim: 1-2-3-4-5 (o valor 4 mantém-se porque causa ali do ++); * então, numCombin(10 - 3, (5 - 1) - 3) = 21 * depois disto tudo, o lbound ainda está a zero (ver mais abaixo porquê) * aumentamos o lbound para em mais 21 e, como é superior ao pedido (2) seguimos viagem * (continua abaixo) */ r = (int)AnaliseCombinatoria.numCombin((n - comb[i]), ((k - 1) - i)); lbound += r; } while (lbound < csn); // (porquê aqui) ao lbound actual, tiramos a última combinação parcial, do exemplo, 21 lbound -= r; } // e agora, depois das posições 0, 1, 2 e 3, vamos tratar da última posição // que vai ser igual à posição anterior + o CSN pedido - o lbound actual // logo, do exemplo, 4 + 2 - 0 = 6 comb[k - 1] = comb[k - 2] + csn - lbound; return((int[])comb.Clone()); }
/// <summary> /// Método para converter uma combinação num CSN /// </summary> /// <param name="comb">Combinação</param> /// <param name="n">Tamanho do set</param> /// <returns>CSN (inteiro)</returns> public static ulong combToCsn(int[] comb, int n) { ulong k = (ulong)comb.Length; ulong lbound = 0; ulong r = 0; // pormenor importante: estritamente, deveria ser (int i = 0; i < k; i++), mas como vamos usar i sozinho várias vezes abaixo, podemos "esquecer" isso... for (ulong i = 1; i <= k; i++) { r = (ulong)(n - comb[k - i]); if (r >= i) { lbound += AnaliseCombinatoria.numCombin((int)r, (int)i); } } return(AnaliseCombinatoria.numCombin((int)n, (int)k) - lbound); }