Angolo Riduzioni
Parliamo esclusivamente di Superenalotto
Questa sezione ha lo scopo di condividere alcuni algoritmi da me utilizzati per trovare la migliore riduzione possibile al gioco del Superenalotto.
Mi riferisco in particolare alle riduzioni G5, G4, G3 o riduzione a garanzia N-1, N-2, N-3.
Data una sequenza di numeri trovare il minor numero possibile di combinazioni (di 6 numeri) in grado di rappresentare con lo scarto di 1 unità (G5 o N-1, ridotto Superenalotto a garanzia 5) o con lo scarto di 2 unità (G4 o N-2, biridotto Superenalotto a garanzia 4) oppure con uno scarto di 3 unità (G3 o N-3, triridotto Superenalotto a garanzia 3) tutte le combinazioni del sistema integrale, indovinando 6 numeri tra quelli scelti per la sequenza.
In pratica con il sistema ridotto G5 o n-1 si ha la garanzia di realizzare almeno un "5" quando si indovinano 6 numeri fra quelli giocati. Se invece si indovinano 5 numeri, si ha la garanzia di ottenere almeno un "4"... e di conseguenza se si indovinano 4 numeri, si ha la garanzia di fare almeno un 3.
mentre con il sistema ridotto G4 o N-2 si ha la garanzia di realizzare almeno un "4" quando si indovinano 6 numeri fra quelli giocati. Se invece si indovinano 5 numeri, si ha la garanzia di ottenere almeno un "3"... e cosi via...
Lo scopo di queste pagine è dare un'idea di come iniziare a ridurre un sistema integrale al superenalotto.
Le parti di codice e gli algoritmi che verranno inseriti, sono in delphi.
Da tempo sto cercando di individuare il minimo ridotto possibile...
per fare questo ho dovuto imparare a programmare e capire come funziona il gioco e le riduzioni...
questo è il mio programmino che uso per elaborare le riduzioni (NB. il programma non è disponibile per il download)
il codice e gli algoritmi descritti in questa pagina sono liberi e posso essere utilizzati liberamente per scopi personali.
Se utilizzate questo codice o questi algoritmi, o parte di essi, in forum o blog o discussioni pubbliche qualsiasi, potete farlo solo se menzionate come autore dello stesso il Sig. Gaetan Andrea o la provenienza della pagina web.
l'algoritmo funziona così:
nei cicli for annidati creo l'integrale di tutte le combinazioni possibili per i numeridaelaborare...
e lo confronto con il variabilearray per vedere se le sestine qui memorizzate coprono la sequenza che creo nei cicli for annidati...
se la sequenza non è coperta, allora incremento variabilearray della sequenza non coperta...
e riprendo a ciclare nei for annidati...
fino alla fine...
poi memorizzo la sequenza trovata di variabilearray in una tabella database
Il metodo qui sotto descritto è molto semplice ma non dà ottimi risultati in termini di riduzione...
comunque resta sempre una buona base di partenza per sviluppare ridotti migliori.
N.B. i numeri elaborati sono in sequenza x facilitare la comprensione dell'algoritmo
( es. uso 10 numeri... la sequenza dei numeri in gioco sarà 1-2-3-4-5-6-7-8-9-10 e non 3-12-15-23-31-35-43-48-52-62)
procedure TForm1.classicoClick(Sender: TObject);
type Tarraygrid = array of array of integer; // definisco il tipo di array
var
// definisco le variabili
tiporiduzione : smallint;
numeridaelaborare,et1,et2,et3,et4,et5,et6,i,riga,colonna,primogiro,f,avacont,quanterighe : integer;
variabilearray : tarraygrid;
label salto;
begin
//identifico il tipo di riduzione
if riduzionen1.Checked = true then tiporiduzione := 5;
if riduzionen2.Checked = true then tiporiduzione := 4;
if riduzionen3.Checked = true then tiporiduzione := 3;
//scelgo per quanti numeri elaborare la riduzione
numeridaelaborare := strtoint(numriduzionidaelaborare.Text); // importo il numero da una textbox
// crea array per i primati 1 riga e 6 colonne
SetLength(variabilearray,1,6);
// procedura di elaborazione RIDOTTO
primogiro := 0;
quanterighe := 1;
// cicli for annidati mi creano tutte le combinazioni possibili per numeridaelaborare (es.10 numero ho 210 combinazioni)
for et1 := 1 to numeridaelaborare - 5 do begin
for et2 := et1 + 1 to numeridaelaborare - 4 do begin
for et3 := et2 + 1 to numeridaelaborare - 3 do begin
for et4 := et3 + 1 to numeridaelaborare - 2 do begin
for et5 := et4 + 1 to numeridaelaborare - 1 do begin
for et6 := et5 + 1 to numeridaelaborare do begin
avantiquante := 0;
for riga := 0 to quanterighe - 1 do begin
avacont := 0;
for colonna := 0 to 5 do begin
if (et1 = variabilearray[riga,colonna]) or
(et2 = variabilearray[riga,colonna]) or
(et3 = variabilearray[riga,colonna]) or
(et4 = variabilearray[riga,colonna]) or
(et5 = variabilearray[riga,colonna]) or
(et6 = variabilearray[riga,colonna]) then begin
inc(avacont);
end;
end;
if avacont >= tiporiduzione then begin
inc(avantiquante);
end;
end;
if avantiquante = 0 then begin
if primogiro > 0 then begin
inc( quanterighe); // incremento la capienza dell'array per aggiungere una nuova sestina
SetLength(variabilearray,quanterighe,6);
end;
// popolo l'array dei primati trovati
variabilearray[quanterighe-1,0] := et1;
variabilearray[quanterighe-1,1] := et2;
variabilearray[quanterighe-1,2] := et3;
variabilearray[quanterighe-1,3] := et4;
variabilearray[quanterighe-1,4] := et5;
variabilearray[quanterighe-1,5] := et6;
primogiro := 1;
end;
end;
end;
end;
end;
end;
end; // end cicli for annidati
// FINE procedura di elaborazione RIDOTTO
// scrive sul database
f := 0;
for i := 0 to high(variabilearray) do begin
with dbf2 do begin
append;
f := f + 1;
Fields[0].asinteger := variabilearray[i,0];
Fields[1].asinteger := variabilearray[i,1];
Fields[2].asinteger := variabilearray[i,2];
Fields[3].asinteger := variabilearray[i,3];
Fields[4].asinteger := variabilearray[i,4];
Fields[5].asinteger := variabilearray[i,5];
post;
end;
end; // end for
// fine scrivo sul database
beep;
end;
un altro metodo più evoluto del Ridotto Semplice....
è quello di poter invertire l'ordine delle combinazioni... e cercare la sequenza di riduzione migliore.
Per fare questo dobbiamo adottare un metodo più elaborato.
-Creo un array contenente tutte combinazioni 6a6 di quanti numeri giocare (in sequenza... vedi ridotto semplice)
l'array creato sarà cosi impostato (per 10 numeri in gioco) totale integrale 210 combinazioni
1-2-3-4-5-6 (prima sequenza)
1-2-3-4-5-7
.....
2-3-4-5-6-7
...
...
5-6-7-8-9-10 (ultima sequenza)
-Creo il mio variabilearray dove andrò a memorizzare quelle sestine che coprono la garanzia richiesta.
-Scopo dell'algoritmo è girare l'array integrale in questo modo:
-prima di tutto controllo array integrale ed estraggo il ridotto semplice...
-poi sposto la prima sequenza dell'array integrale alla fine e
-ricontrollo array integrale per trovare una sequenza di ridotto migliore della precedente
-... continuo a spostare la prima nuova sequnza dell'array integrale alla fine e ricontrollo...
-... se incontro un ridotto migliore del precedente... lo memorizzo
fine
procedure TForm1.salvaClick(Sender: TObject);
type Tarraygrid = array of array of integer;
var
tiporiduzione : smallint;
numeridaelaborare,totarray,minimoraggiunto,et1,et2,et3,et4,et5,et6,i,numint,posizione,riga,colonna,primogiro,
sospeso1,sospeso2,sospeso3,sospeso4,sospeso5,sospeso6,partenza,quanterighe,avanti,avantiquante,avacont, : integer;
variabilearray,integralearray,primatoarray : tarraygrid;
begin
// CONTROLLO SU RIDUZIONI
if riduzionen1.Checked = true then tiporiduzione := 5; // scelgo il tipo di riduzione ottenere
if riduzionen2.Checked = true then tiporiduzione := 4;
if riduzionen3.Checked = true then tiporiduzione := 3;
numeridaelaborare := strtoint(numriduzionidaelaborare.Text); // quanti numeri elaborare
totarray := combin(numeridaelaborare,6); // richiama il calcolo combinazioni
SetLength(integralearray,totarray,6); // crea array integrale sestina
SetLength(variabilearray,1,6); // crea array riduzioni
SetLength(primatoarray,1,6); // crea array primati
// crea array POPOLA array integralearray come combinaz. integrale
numint := 0; // setto il contatore delle sestine a 0
for et1 := 1 to numeridaelaborare - 5 do begin
for et2 := et1 + 1 to numeridaelaborare - 4 do begin
for et3 := et2 + 1 to numeridaelaborare - 3 do begin
for et4 := et3 + 1 to numeridaelaborare - 2 do begin
for et5 := et4 + 1 to numeridaelaborare - 1 do begin
for et6 := et5 + 1 to numeridaelaborare do begin
integralearray[numint,0] := et1;
integralearray[numint,1] := et2;
integralearray[numint,2] := et3;
integralearray[numint,3] := et4;
integralearray[numint,4] := et5;
integralearray[numint,5] := et6;
numint := numint + 1;
end;
end;
end;
end;
end;
end;
//fine crea array integrale
minimoraggiunto := numint;
// ************** corpo della procedura ***************
posizione := 0;
repeat // ciclo repeat until dove sposto le sestine dell'integrale alla fine
primogiro := 0;
variabilearray := 0; // azzero variabilearray
SetLength(variabilearray,1,6); // setto variabilearray ad 1 riga x 6 colonne
for avanti := 0 to numint - 1 do begin // scorro array integrale
quanterighe := length(variabilearray); // quante righe ha array variabile
avantiquante := 0;
for riga := 0 to quanterighe - 1 do begin
avacont := 0;
for colonna := 0 to 5 do begin // confronto integrale con array dei ridotti
if (integralearray[avanti,0] = variabilearray[riga,colonna]) or
(integralearray[avanti,1] = variabilearray[riga,colonna]) or
(integralearray[avanti,2] = variabilearray[riga,colonna]) or
(integralearray[avanti,3] = variabilearray[riga,colonna]) or
(integralearray[avanti,4] = variabilearray[riga,colonna]) or
(integralearray[avanti,5] = variabilearray[riga,colonna]) then begin
inc(avacont); //incremento il contatore avacont
end;
end;
if avacont >= tiporiduzione then begin
inc(avantiquante); // incremento il contatore avantiquante
end;
end;
if avantiquante = 0 then begin
if primogiro > 0 then begin
inc(quanterighe); // incremento la capienza dell'array per aggiungere una nuova sestina
SetLength(variabilearray,quanterighe,6); // aggiungo una riga ad variabilearray
end;
variabilearray[quanterighe-1,0] := integralearray[avanti,0]; // popolo l'ultima riga di variabilearray
variabilearray[quanterighe-1,1] := integralearray[avanti,1];
variabilearray[quanterighe-1,2] := integralearray[avanti,2];
variabilearray[quanterighe-1,3] := integralearray[avanti,3];
variabilearray[quanterighe-1,4] := integralearray[avanti,4];
variabilearray[quanterighe-1,5] := integralearray[avanti,5];
primogiro := 1;
end;
end;
end; //end for avanti
if posizione = 1 then begin // memorizzo il primato in primatoarray
primatoarray := variabilearray;
end;
if (posizione > 1) and (length(primatoarray) > length(variabilearray)) then begin
primatoarray := variabilearray;
end;
minimoraggiunto := length(primatoarray);
// sposta la prima combinazione dell'integrale... alla fine
sospeso1 := integralearray[0,0];
sospeso2 := integralearray[0,1];
sospeso3 := integralearray[0,2];
sospeso4 := integralearray[0,3];
sospeso5 := integralearray[0,4];
sospeso6 := integralearray[0,5];
integralearray := copy(integralearray,1,numint);
SetLength(integralearray,numint,6);
integralearray[numint-1,0] := sospeso1;
integralearray[numint-1,1] := sospeso2;
integralearray[numint-1,2] := sospeso3;
integralearray[numint-1,3] := sospeso4;
integralearray[numint-1,4] := sospeso5;
integralearray[numint-1,5] := sospeso6;
until posizione = (numint + 1); // cicla fono a che non raggiungo ultima sequenza integrale
// scrive sul database
quanterighe := length(primatoarray);
for i := 0 to quanterighe - 1 do begin
with dbf2 do begin
append;
Fields[0].asinteger := primatoarray[i,0];
Fields[1].asinteger := primatoarray[i,1];
Fields[2].asinteger := primatoarray[i,2];
Fields[3].asinteger := primatoarray[i,3];
Fields[4].asinteger := primatoarray[i,4];
Fields[5].asinteger := primatoarray[i,5];
Fields[6].asinteger := primatoarray[i,6];
post;
end;
end; //end for
//fine scrivo sul database
end; // fine procedura