DreamsInCode logo

DreamsInCode

import { Research, Work, Passion } from Life;

Imagem de Algoritmo para Loto-Aplicações – De CSN para combinações e de combinações para CSNImagem de Algoritmo para Loto-Aplicações – De CSN para combinações e de combinações para CSN

Dylan Nolte @ Unsplash

Algoritmo para Loto-Aplicações – De CSN para combinações e de combinações para CSN

O CSN é número sequencial combinatórico (combinatorial sequence number) de uma dada combinação, quando estas se encontram ordenadas lexicograficamente (por ordem numérica, pronto).

Publicado Tuesday, January 19, 2010 at 1:10 AM

Uma forma de calcular os CSN, e vice-versa, seria simplesmente construir todo o desdobramento até ao CSN pretendido, ou até à chave pretendida. Don’t. É estúpido, é um desperdício de ciclos de processamento e é péssima programação. Sobretudo, se já alguém pensou no assunto e se os algoritmos são do domínio público.

Vamos então aos ditos

O algoritmo para calcular a combinação a partir do CSN é um engenhosa obra prima de B. P. Buckles e M. Lyabanon, publicada em 1974.

1função csnParaCombinacao(csn, n, k)
2 seja limite_inferior = 0;
3 seja r = 0;
4 seja combinação = [0...k-1]
5
6 para cada i, sendo i = 0, enquanto i < k - 1, incrementar i
7 combinação[i] = 0;
8 se(i != 0) combinação[i] = combinação[i - 1];
9
10 fazer
11 combinação[i] = combinação[i] + 1;
12 // lembram-se desta função?
13 r = numeroDeCombinacoes(n - combinação[i], (k - 1) - i);
14 limite_inferior = limite_inferior + r;
15 enquanto (limite_inferior < csn);
16
17 limite_inferior = limite_inferior - r;
18 fim de para;
19
20 combinação[k - 1] = combinação[k - 2] + csn - limite_inferior;
21
22 devolve combinação;
23fim de função;

Para começar, quero-vos dizer que parece bem mais complicado do que, na realidade, é.

Depois, reparem como a última posição da combinação é tratada à parte, duma maneira perfeitamente elegante, usando os valores do CSN pedido e do último limite inferior calculado.

Mas passemos, então, à manobra inversa, calcular o CSN a partir da combinação. O seguinte algoritmo não tem, que eu saiba, autores oficiais. A sua simplicidade decorre de ser um negativo quase perfeito da função anterior.

1função combinacaoParaCsn(combinação, n)
2 seja k = combinação.tamanho();
3 seja limite_inferior = 0;
4 seja r= 0;
5
6 para cada i, sendo i = 1, enquanto i <= k, incrementar i
7 r = n - combinação[k - i];
8 se (r >= i)
9 limite_inferior = limite_inferior + númeroDeCombinações(r, i);
10 fim de se;
11 fim de para;
12
13 devolve numeroDeCombinacoes(n, k) - limite_inferior;
14fim de função;

Podem ver, na segunda instrução do para, que a combinação está a ser percorrida de trás para a frente, e o limite inferior está a ser contado como o que falta até ao fim, sendo finalmente subtraído ao número de combinações total para nos dar o CSN.

Lotarias
Algoritmos

Postas relacionadas