jueves, 19 de noviembre de 2009

Lotería Primitiva


Dispone de un archivo de Excel que puede descargar: loteria.xlsm

Veamos un caso de simulación del juego de la Lotería Primitiva. Se trata de simular un gran número de jugadas y comprobar cuantos aciertos de 3, 4, 5, y 6 se producen. La macro no pretende ayudar a ganar dinero con este juego de azar. Sus pretensiones son formativas, ya que aprenderemos a programar macros con matrices y funciones. A la vista de los pobres resultados alcanzados, posiblemente la consecuencia sea que usted no vuelva a jugar a la lotería primitiva.


Reglas

Disponemos de 49 números, entre 1 y 49. Se deben elegir 6 de ellos, sin repetición. La jugada ganadora esta compuesta por otros 6 números, igualmente elegidos entre los 49 disponibles. Se compara nuestra jugada con la ganadora. Reciben premio los jugadores que tienen una combinación de números que coincide con la ganadora en 3 o 4 o 5 o 6. El premio mayor se obtiene si tienes 6 coincidencias, y el menor si tienes 3 coincidencias. La cuantía del premio varia en función del número de acertantes existentes en cada categoría.

Inicialmente estas fueron las reglas. Posteriormente añadieron la existencia de un número complementario, que da lugar a un premio intermedio entre el de acertar 5 y 6. Se trata de acertar 5 más el número complementario. La existencia de esta nueva regla no la vamos a considerar en nuestra simulación para simplificar el caso.




Función Genera

Hemos creado una función que genera 6 números aleatorios sin repetición entre 1 y 49.


Observar que se incluye la instrucción

Randomize

que en Visual Basic permite inicializar la semilla de los números aleatorios. Equivale a barajar las cartas de una baraja para sacar nuevas cartas al azar.


Código:

Private Function Genera() As Byte()
Dim A(6) As Byte
Dim i As Long
Dim j As Byte
Dim U As Byte
Dim repe As Boolean
Randomize
A(1) = Int(49 * Rnd + 1)
For i = 2 To 6
Do
U = Int(49 * Rnd) + 1
repe = False
For j = 1 To i - 1
If U = A(j) Then repe = True: Exit For
Next j
Loop While repe
A(i) = U
Next i
Genera = A
End Function


Macro

Disponemos de una macro que es la que dirige el flujo del programa. Llama a la función Genera inicialmente para solicitarle la combinación ganadora, y posteriormente cada vez que se realiza una jugada.



Código:

Sub primitiva_loto()
Dim i As Byte
Dim j As Double
Dim k As Byte
Dim s As Byte 'acumula las acertadas
Dim n As Double
Dim B(6) As Long 'B(3), B(4), B(5), B(6)
'acumulan las jugadas ganadas de 3,4,5,6
Dim G() As Byte 'combinación ganadora
Dim Z() As Byte
G = Genera()
n = InputBox("¿Núm. jugadas?", , 1000000)
For j = 1 To n 'j es la jugada
Z = Genera()
s = 0
For i = 1 To 6
  For k = 1 To 6
      If G(i) = Z(k) Then s = s + 1: Exit For
  Next k
Next i
For i = 3 To 6
  If s = i Then B(i) = B(i) + 1
Next i
Next j
For i = 1 To 6 'Imprimimos la Ganadora
Cells(i + 4, "B") = G(i)
Next i
For i = 3 To 6 'Imprimimos los resultados
Cells(i + 2, "E") = B(i)
Next i
Range("E10") = n
End Sub

Se comparan todos los elementos de la jugada con la ganadora, y se determina el número de aciertos. Si los aciertos son 3, o 4 o 5 o 6, se llevan a una matriz B() que acumula el número de aciertos de cada categoría.
  • B(3) acumula los acierto de 3
  • B(4) acumula los acierto de 4
  • B(5) acumula los acierto de 5
  • B(6) acumula los acierto de 6
B(1) y B(2) no se utilizan para nada.


Continua

Una variante sobre la macro anterior es otra macro que trabaja de forma continua y que no para hasta que el usuario la detiene, por ejemplo pulsando la tecla Esc. Despues de pulsar Esc sale una pantalla avisando de la interrupción de la macro, y en ella debe pulsas sobre 'Finalizar'.

Esta macro cada 100.000 jugadas realizadas muestra en pantalla los resultados alcanzados. Esto nos permite ver la evolución de los acierto.

Código:

Option Explicit
Private Function Genera() As Byte()
Dim A(6) As Byte
Dim i As Long
Dim j As Byte
Dim U As Byte
Dim repe As Boolean
Randomize
A(1) = Int(49 * Rnd + 1)
For i = 2 To 6
Do
   U = Int(49 * Rnd) + 1
   repe = False
   For j = 1 To i - 1
       If U = A(j) Then repe = True: Exit For
   Next j
Loop While repe
A(i) = U
Next i
Genera = A
End Function
Sub primitiva_continua()
Dim i As Byte
Dim j As Double
Dim k As Byte
Dim s As Byte 'acumula las acertadas
Dim B(6) As Long 'B(3), B(4), B(5), B(6) acumulan las jugadas ganadas de 3,4,5,6
Dim G() As Byte 'combinación ganadora
Dim Z() As Byte
G = Genera()
For i = 1 To 6 'Imprimimos la Ganadora
Cells(i + 4, 2) = G(i)
Next i
Do
j = j + 1 'j es la jugada
Z = Genera()
s = 0
For i = 1 To 6
   For k = 1 To 6
       If G(i) = Z(k) Then s = s + 1: Exit For
   Next k
Next i
For i = 3 To 6
   If s = i Then B(i) = B(i) + 1
Next i
If Int(j / 100000) - (j / 100000) = 0 Then
   For i = 3 To 6 'Imprimimos los resultados
       Cells(i + 2, 5) = B(i)
   Next i
   Cells(10, 5) = j
End If
Loop
End Sub


Tras dejar funcionando mi portatil durante ocho horas y media, conseguí algo más de cuatro mil millones de jugadas (4.126.700.000) siendo los aciertos obtenidos los siguientes.



De 6 aciertos no se consiguió ningún acierto. Esto probablemente no sea muy representativo debido a que estamos manejando números pseudoaleatorios, que no son verdaderamente aleatorios. Es posible que se mejoraran los resultados obtenidos utilizando no una única jugada ganadora, sino una ganadora por cada apuesta realizada. Pero, independientemente de este caso, lo que se ve con claridad es que no es muy rentable, en términos medios, jugar a la lotería. Aunque siempre nos quedará el consuelo de pensar que ... "a alguien le toca".

6 comentarios:

  1. Que clase me recomienda para iniciar el curso, ya que no tengo nada de conocimiento de excel avanzado.
    Gracias.

    ResponderEliminar
    Respuestas
    1. Hola David.
      Puedes seguir los enlaces que ya están publicados del siguiente curso: Curso

      Eliminar
  2. gracias adolfo, pero el generador aleatorio repite combinaciones, de lo contrario es imposible que de 40.000.000, no existan aciertos...ojalá compartas más cosas de este tema, con tus conocimientos, dedicandole más tiempo

    ResponderEliminar
  3. 250.000.000 jugadas, y ni un solo acierto de 6
    en la funcion de combinat nos da que 49;6 sale no más de 14.000.000 millones de combinaciones distintas, por eso la funcion de aleatoria que le has metido, no creo que sea de fiar, gracias por el blog, apenas estoy empezando en esto del excel

    ResponderEliminar
  4. Hola a todos:

    Supongo que habría alguna forma de conservar las combinaciones que haga para visualizarlos, así como también poner una cantidad que no sobrepase y calcule miles de millones, sin necesidad.

    Gracias por todo.
    Saludos.

    ResponderEliminar