Autor
|
Tema: Ejercicio básico de combinaciones (Leído 31,389 veces)
|
Serapis
|
Hola. Hoy he llegado tarde del trabajo, pero todavía he sacado un tiempito para calcular las cantidades...
Dado que (ahora) varía la cantidad de unidades y decenas que pueden aparecer, lo adecuado es categorizar, pués a unidades iguales las firmas son las mismas, resumiendo:
- Con 0 decenas y 6 unidades: No puede darse: ej: 5,6,7,8,9 ? Falta 1 dígito para poder formar 6 'apuestas'.
- Con 1 decenas y 5 unidades: Puede o no aceptarse (técnicamente no, pues estaríamos inventando un dígito 0): ej: 3; 5,6,7,8,9 35, 36, 37, 38, 39, 03? En cualquier caso si se aceptara, sería una sola combinación y por tanto puede 'calcularse' manualmente. Luego puede dejarse fera.
- Con 2 decenas y 4 unidades: Salen 210 firmas distintas (son las calculadas anteriormente). XY-RSTU ------------------- XY XR XS XT XU YX YR YS YT YU Ej: 0,1,___6,7,8,9 10, 08, 09, 16, 17, 19
- Con 3 decenas y 3 unidades: Salen 5.005 firmas. XYZ-RST ------------------- XY XZ XR XS XT YX YZ YR YS YT ZX ZY ZR ZS ZT Ej: 0,1,2,___ 7,8,9 20, 17, 28, 09, 27, 12
- Con 4 decenas y 2 unidades: Salen 38760 143.080 firmas. WXYZ-RS ------------------- WX WY WZ WR WS XW XY XZ XR XS YW YX YZ YR YS ZE ZX ZY ZR ZS Ej: 0,1,2,3,___ 8,9 38,39,13, 01,29, 12
- Con 5 decenas y 1 unidad: Salen 177100 402.895 firmas. VWXYZ-R ------------------- VW VX VY VZ VR WV WX WY WZ WR XV XW XY XZ XR YV YW YX YZ YR ZV ZW ZX ZY ZR
Ej: 0,1,2,3,4,___ 9 20,31,49, 43, 40
En total se aproximan al 1/4 de millón suben por encima del medio millón (y solo son las firmas).
p.d.: Mañana que vengo con más tiempo veré si me da tiempo a hacerlo. p.d.2: Actualizado los valores de las combinaciones (había un error).
|
|
« Última modificación: 7 Mayo 2021, 15:46 pm por Serapis »
|
En línea
|
|
|
|
Serapis
|
Me ha dado tiempo a rehacer lo que habíamos hecho, el resto es más de lo mismo y mañana en otro ratito lo completo... Al lío... Dado que ahora tendremos varias categorías, es más eficiente crear una interfaz e implementar una clase por cada categoría, que andar complicando algoritmos con condicionales. El código que tenías del proyecto previo, guardalo o bórralo... los cambios manuales son demasiados y es preferible copiar y pegar. Añade un interfaz al proyecto. Este es el código de la interfaz: Public Interface ICombina ''' <summary> ''' Cantidad de valores enumerados. ''' </summary> ReadOnly Property Cantidad As UInt32 ''' <summary> ''' Recrea el array de las combinaciones al inicio. ''' </summary> Sub Enumerar() ''' <summary> ''' Decodifica el valor enumerado en la posicion indicada, a 6 pares de valores numericos. ''' </summary> ''' <param name="Index">Indice de la enumeracion solicitado</param> ''' <param name="Decenas">Array de los digitos que (ademas) pueden actuar como decenas</param> ''' <param name="Unidades">Array de los digitos que solo pueden actuar como unidades</param> ''' <returns>Devuelve la combinacion con las 6 apuestas separadas por ', '"</returns> Function Tranformar(ByVal Index As Int32, ByRef Decenas() As Byte, ByRef Unidades() As Byte) As String End Interface
Los comentarios los puedes borrar si lo prefieres... NOTA: La interfaz debe llamarse como figura ahí... luego que esté todo el código, podrás cambiarlo si lo prefieres. Añade un módulo de código si no tienes alguno. Algunas funciones y extensiones de métodos se han trasladado aquí. es código estático (independiente de cualquier instancia). Este es el código a añadir dentro del módulo: <Extension()> Public Function EnRango(ByVal Valor As Byte, ByVal Minimo As Byte, ByVal Maximo As Byte) As Boolean Return ((Valor >= Minimo) And (Valor <= Maximo)) End Function <Extension()> Public Function EnRango(ByVal Valor As Char, ByVal Minimo As Byte, ByVal Maximo As Byte, ByVal Tope As Byte) As Boolean Dim asci As Byte = (Strings.Asc(Valor) - Tope) Return ((asci >= Minimo) And (asci <= Maximo)) End Function Public Function EnumeraComb(ByRef Inicio As String, ByRef Final As String, ByVal Cantidad As UInteger) As String() Dim k As UInt32 = 0 Dim Combina As String = Inicio Dim Maxchar As Byte = IndexLastChar(Inicio, Final) ' Final.Chars(Final.Length-1) Dim Permutas(0 To Cantidad - 1) As String Dim digitos(0 To 5) As Byte, n As Byte = 0 For k = 0 To 5 digitos(k) = k Next k = 0 Do Permutas(k) = Combina If (digitos(5) = Maxchar) Then n = 4 Do While Combina.Chars(n) = Combina.Chars(n + 1).Previo ' digitos(n) = digitos(n + 1) - 1 n -= 1 Loop digitos(n) += 1 For n = n + 1 To 5 digitos(n) = digitos(n - 1) + 1 Next Combina = "" ' 0 For n = 0 To 5 Combina &= CharIndexAZ(digitos(n)) ' * (10 ^ (5 - n)) Next Else Combina = Combina.NextComb() digitos(5) += 1 End If k += 1 Loop While (Combina < Final) Permutas(k) = Combina Return Permutas End Function #Region "Las siguiente funciones y extensiones son solo de ayuda para la función anterior (enumerar)." <Extension()> Private Function NextComb(ByRef Combina As String) As String Dim Last As Byte = Asc(Combina.Chars(5)) ' ojo Estamos usando siempre longitudes de 6 caracteres. Return Strings.Left(Combina, 5) & Strings.Chr(Last + 1) End Function ''' <summary> ''' Calcula el caracter previo en la secuencia ASCII. ''' </summary> ''' <param name="Ch">Caracter en el rango A-Z</param> ''' <returns>Devuelve el carácter previo al dado (en la secuencia ASCII).</returns> ''' <remarks></remarks> <Extension()> Private Function Previo(ByRef Ch As Char) As Char Dim n As Byte = Strings.Asc(Ch) - 1 Return Strings.Chr(n) End Function Private Function CharIndexAZ(ByRef Index As Byte) As Char Return Strings.Chr(65 + Index) End Function ' Devuelve la distancia entre el primer caracter de inicio y el último de 'final' ' Ejemplo: "'A'BCDEF" "EFGHI'J'" = 10; "'A'BCDEF" "MNOPQ'R'" = 17 Private Function IndexLastChar(ByRef Inicio As String, ByRef Final As String) As Byte Dim F As Byte = Strings.Asc(Final.Chars(Final.Length - 1)) Dim I As Byte = Strings.Asc(Inicio.Chars(0)) Return (F - I) End Function #End Region
Se ha añadido alguna función, la principal es 'enumerarCombinacion'. Las extensiones de métodos, son métodos que simplemente cambia la forma en que se llaman. Si tu creas por ejemplo una función Ordenar que ordena un array, lo llamarías así: call Ordenar(elArray, parametro1, parametro2)
Mediante una extensión, resulta más cómodo, pués se recurre al intellisense, para que pueda invocarse así: elArray.Odenar(parametro1, parametro2)
Con lo que parece un método nativo más del tipo de datos al que se extiende. Naturalmente la extensión solo es aplicable al proyecto actual. Finalmente volvemos a la ventana principal... (se asume que ahora mismo está vacía). Public Class Form1 Private perm24, perm33, perm42, perm51,perm60 As ICombina Private Decenas() As Byte, Unidades() As Byte Public Sub New() InitializeComponent() ' Crear las instancias una única vez. perm24 = New Permutas2_4 perm33 = New Permutas3_3 perm42 = New Permutas4_2 perm51 = New Permutas5_1 perm60 = New Permutas6_0 End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Dim Nums() As String, txt As String Dim k As UInt16, n As Byte Dim Permuta As ICombina txt = TextBox1.Text.Replace(" ", "") Nums = txt.Split(",") If (Nums.Length = 6) Then Array.Sort(Nums) Do While (Nums(n).Chars(0).EnRango(0, 4, 48) = True) And (n < 5) n += 1 Loop If (n.EnRango(1, 5) = True) Then ReDim Decenas(0 To n - 1) ReDim Unidades(0 To 6 - n - 1) For k = 0 To n - 1 Decenas(k) = System.Byte.Parse(Nums(k)) Next For k = n To 5 Unidades(k - n) = System.Byte.Parse(Nums(k)) Next Select Case n Case 2 : Permuta = perm24 Case 3 : Permuta = perm33 Case 4 : Permuta = perm42 Case 5 : Permuta = perm51 case 6: Permuta = perm60 End Select ListBox1.Items.Clear() For j = 0 To Permuta.Cantidad - 1 ListBox1.Items.Add(Permuta.Tranformar(j, Decenas, Unidades)) Next Label3.Text = "Cantidad en lista: " & Permuta.Cantidad.ToString ' ListBox1.Items.Count.ToString Else MessageBox.Show("No se puede generar combinaciones si no hay 2-5 dígitos menores de 5.") End If Else MessageBox.Show("No, no no... Debe haber 6 y solo 6 numeros, separados por 1 coma...") End If End Sub End Class
Se han sacado las clases fuera de la clase del formulario, por claridad. Ahora hay una instancia de la interfaz 'ICombina', por cada categoría... Se considera una categoría, a cada diferenciación en la relación de cantidad entre dígitos que pueden ser decenas de los que no. Un ejemplo: Sean los dígitos 3, 6, 8, 0, 5, 1 ...hay 3 valores que pueden ser decenas: 0,1 y 3, luego pertenecen a la categoróa asociada a la intancia 'perm3_3 (3 decenas y 3 unidades, para qué complicarnos más en el nombre). Esta diferenciaciónd e categorías es necesaria, porque cada una presenta diferente cantidad de firmas, como ya se señaló en el mensaje anterior. en lo que al código de la función del botón respecta, para hallar a qué categoría pertenece, tras crear el array con los dígitos (nums), lo ordenamos, ahora un recorrido con un bucle nos permite contarlos, y luego selecciona la clase que operará conforme a la categoría reconocida. Se descartan los casos en que haya 0 o 1 decena solo (5,5,6,7,8,9) y (2, 5,6,7,8,9) y también cuando sean 6 decenas (esto directamente lo he descartado, generaría varios millones de combinaciones) En la misma ventana del formulario, bajo la clase de dicho formulario, irán la implementación de cada clase. Como digo, de momento, solo he dejado lista, la conversión d ela primera (que es equivalente a la que ya hice), las otras son básicamente rehacer lo mismo con pequeños cambios en la función transformar, ya mañana en otro ratito, lo completo. Friend Class Permutas2_4 Implements ICombina Const MAX_COMBINAS As UInt16 = 210 Private s_Combinas() As String ' UInt32 Public Sub New() Call Enumerar() End Sub Public ReadOnly Property Cantidad As UInteger Implements ICombina.Cantidad Get Return MAX_COMBINAS End Get End Property ' Para generar las permutaciones, delega en la función que yace en el módulo. Private Sub Enumerar() Implements ICombina.Enumerar ' combinacion inicial, final, Total combinaciones s_Combinas = EnumeraComb("ABCDEF", "EFGHIJ", MAX_COMBINAS) End Sub ' Alfabeto = X,Y, R,S,T,U ' A B C D E F G H I J ' XY XR XS XT XU YR YS YT YU YX Public Function Tranformar(ByVal Index As Integer, ByRef Decenas() As Byte, ByRef Unidades() As Byte) As String Implements ICombina.Tranformar Dim permuta As String = s_Combinas(Index) Dim s(0 To 5) As String, valor As String = "" Dim x As Byte = 0, k As Byte For k = 0 To 5 x = (Strings.Asc((permuta.Chars(k))) - 65) Select Case x Case 0 : x = ((Decenas(0) * 10) + Decenas(1)) Case 1 To 4 : x = ((Decenas(0) * 10) + Unidades(x - 1)) Case 5 To 8 : x = ((Decenas(1) * 10) + Unidades(x - 5)) Case 9 : x = ((Decenas(1) * 10) + Decenas(0)) End Select If (x < 10) Then s(k) = "0" & x.ToString Else s(k) = x.ToString Next Array.Sort(s) Return Join(s, ", ") End Function End Class
Y eso es todo por hoy. Mañana lo completo. Nota que ya se ha aprovechado para ordenar los elementos de cada combinación así además de estar el listado ordenado, también los valores de cada combinación. p.d.: Corrijo, con 6 dígitos como decenas, se generan muchas menos firmas, cuando lo calculé ayer, creí haber leído millones... pués nada, mañana se incluye también y se hace el cambio pertienente para contener su clase y en la llamada del botón considerar el caso. p.d.: Corregido cantidad de combinaciones para 4_2 y 5_1
|
|
« Última modificación: 10 Mayo 2021, 17:05 pm por Serapis »
|
En línea
|
|
|
|
Serapis
|
Tengo un momento hoy tras comer, aprovecho para terminarlo... Antes de nada, es conveniente aclarar que cometí un pequeño error (un '0' donde debí poner una 'O', que como es copia y pega... se tradujo al resto), pero no afecta a lo hecho si no a los que muestro. Esto implica que el numero de combinaciones para los casos de 4-2, 5-1 y 6-0, son mucho menores: Las combinaciones del caso 4 decenas + 2 unidades son 38.760 y no 143.080 Las combinaciones del caso 5 decenas + 1 unidades son 177.100 y no 402.895 Con el de 6 decenas + 0 unidades (no hay dígitos en el rango 5-9), se dan muchísimos casos ilegales de las 177.100 9 de cada 10 son ilegales... o bien tienen 00, o bien un valor repetido dos veces. Se puedne filtrar con ligeras modificaciones, abajo lo vuelvo a mencionar cuando llegue el momento... Friend Class Permutas3_3 Implements ICombina Const MAX_COMBINAS As UInt32 = 5005 Private s_Combinas() As String Public Sub New() Call Enumerar() End Sub Public ReadOnly Property Cantidad As UInteger Implements ICombina.Cantidad Get Return MAX_COMBINAS End Get End Property Public Sub Enumerar() Implements ICombina.Enumerar s_Combinas = EnumeraComb("ABCDEF", "JKLMNO", MAX_COMBINAS) ' 5005 End Sub ' Alfabeto = XYZ RST ' A B C D E F G H I J K L M N O ' XY XZ XR XS XT YX YZ YR YS YT ZX ZY ZR ZS ZT Public Function Tranformar(ByVal Index As Integer, ByRef Decenas() As Byte, ByRef Unidades() As Byte) As String Implements ICombina.Tranformar Dim permuta As String = s_Combinas(Index) Dim s(0 To 5) As String Dim v As Byte, m As Byte, n As Byte, k As Byte For k = 0 To 5 v = (Strings.Asc((permuta.Chars(k))) - 65) m = (Decenas(v \ 5) * 10) n = (v Mod 5) If (n < 2) Then If (v < 5) Then v = (m + Decenas(n + 1)) ' XY, XZ ElseIf (v < 10) Then If (n = 0) Then v = (m + Decenas(n)) ' YX Else v = (m + Decenas(n + 1)) ' YZ End If Else v = (m + Decenas(n)) ' ZX, ZY End If Else v = (m + Unidades(n - 2)) ' *R,*S,*T End If If (v < 10) Then s(k) = "0" & v.ToString Else s(k) = v.ToString Next Array.Sort(s) Return Join(s, ", ") End Function End Class Friend Class Permutas4_2 Implements ICombina Const MAX_COMBINAS As UInt32 = 38760 '143080 Private s_Combinas() As String Public Sub New() Call Enumerar() End Sub Public ReadOnly Property Cantidad As UInteger Implements ICombina.Cantidad Get Return MAX_COMBINAS End Get End Property Public Sub Enumerar() Implements ICombina.Enumerar s_Combinas = EnumeraComb("ABCDEF", "OPQRST", MAX_COMBINAS) ' 38760 End Sub ' Alfabeto = WXYZ RS ' A B C D E F G H I J K L M N O P Q R S T ' WX WY WZ WR WS XW XY XZ XR XS YW YX YZ YR YS ZW ZX ZY ZR ZS Public Function Tranformar(ByVal Index As Integer, ByRef Decenas() As Byte, ByRef Unidades() As Byte) As String Implements ICombina.Tranformar Dim permuta As String = s_Combinas(Index) Dim s(0 To 5) As String Dim v As Byte, m As Byte, n As Byte, k As Byte For k = 0 To 5 v = (Strings.Asc((permuta.Chars(k))) - 65) m = (Decenas(v \ 5) * 10) n = (v Mod 5) If (n < 3) Then If (v < 5) Then v = (m + Decenas(n + 1)) ' WX, WY, WZ ElseIf (v < 10) Then If (n = 0) Then v = (m + Decenas(n)) ' XW Else v = (m + Decenas(n + 1)) ' XY, XZ End If ElseIf (v < 15) Then If (n < 2) Then v = (m + Decenas(n)) ' YW, YX Else v = (m + Decenas(n + 1)) ' YZ End If Else v = (m + Decenas(n)) ' ZW, ZX, ZY End If Else v = (m + Unidades(n - 3)) ' *R,*S End If If (v < 10) Then s(k) = "0" & v.ToString Else s(k) = v.ToString Next Array.Sort(s) Return Join(s, ", ") End Function End Class Friend Class Permutas5_1 Implements ICombina Const MAX_COMBINAS As UInt32 = 177100 '402895 Private s_Combinas() As String Public Sub New() Call Enumerar() End Sub Public ReadOnly Property Cantidad As UInteger Implements ICombina.Cantidad Get Return MAX_COMBINAS End Get End Property Public Sub Enumerar() Implements ICombina.Enumerar s_Combinas = EnumeraComb("ABCDEF", "TUVWXY", MAX_COMBINAS) ' 177.100 End Sub ' Alfabeto: VWXYZ R ' 01 02 03 04 0? 10 12 13 14 1? 20 21 23 24 2? 30 31 32 34 3? 40 41 42 43 4? ' A B C D E F G H I J K L M N O P Q R S T U V X Y Z ' VW VX VY VZ VR WV WX WY WZ WR XV XW XY XZ XR YV YW YX YZ YR ZV ZW ZX ZY ZR Public Function Tranformar(ByVal Index As Integer, ByRef Decenas() As Byte, ByRef Unidades() As Byte) As String Implements ICombina.Tranformar Dim permuta As String = s_Combinas(Index) Dim s(0 To 5) As String Dim v As Byte, m As Byte, n As Byte, k As Byte For k = 0 To 5 v = (Strings.Asc((permuta.Chars(k))) - 65) m = (Decenas(v \ 5) * 10) n = (v Mod 5) If (n < 4) Then If (v < 5) Then v = (m + Decenas(n + 1)) ' VW, VX, VY, VZ ElseIf (v < 10) Then If (n = 0) Then v = (m + Decenas(n)) ' WV Else v = (m + Decenas(n + 1)) ' WX, WY, WZ End If ElseIf (v < 15) Then If (n < 2) Then v = (m + Decenas(n)) ' XV, XW Else v = (m + Decenas(n + 1)) ' XY, XZ End If ElseIf (v < 20) Then If (n < 3) Then v = (m + Decenas(n)) ' YV, YW, YX Else v = (m + Decenas(n + 1)) ' YZ End If Else v = (m + Decenas(n)) ' ZV, ZW, ZX, ZY End If Else v = (m + Unidades(n - 4)) ' *R End If If (v < 10) Then s(k) = "0" & v.ToString Else s(k) = v.ToString Next Array.Sort(s) Return Join(s, ", ") End Function End Class Friend Class Permutas6_0 Implements ICombina Const MAX_COMBINAS As UInt32 = 177100 Private s_Combinas() As String Public Sub New() Call Enumerar() End Sub Public ReadOnly Property Cantidad As UInteger Implements ICombina.Cantidad Get Return MAX_COMBINAS End Get End Property Public Sub Enumerar() Implements ICombina.Enumerar s_Combinas = EnumeraComb("ABCDEF", "TUVWXY", MAX_COMBINAS) ' 177.100 End Sub ' Alfabeto: VWXYZ? _ ' 00 01 02 03 04 10 11 12 13 14 20 21 22 23 24 30 31 32 33 34 40 41 42 43 44 ' A B C D E F G H I J K L M N O P Q R S T U V W X Y ' VV VW VX VY VZ WV WW WX WY WZ XV XW XX XY XZ YV YW YX YY YZ ZV ZW ZX ZY ZZ Public Function Tranformar(ByVal Index As Integer, ByRef Decenas() As Byte, ByRef Unidades() As Byte) As String Implements ICombina.Tranformar Dim permuta As String = s_Combinas(Index) Dim s(0 To 6) As String Dim v As Byte, m As Byte, n As Byte, k As Byte For k = 0 To 5 ' el 0 se reserva (caso especial, para comparar un item con el previo) v = (Strings.Asc((permuta.Chars(k))) - 65) m = (Decenas(v \ 5) * 10) n = (v Mod 5) If (m = n) Then s(0) = " --- Combinacion ilegal --- " ' aparece '00' End If v = (m + n) If (v < 10) Then s(k + 1) = "0" & v.ToString Else s(k + 1) = v.ToString Next Array.Sort(s) For k = 1 To 5 If (s(k) = s(k - 1)) Then s(0) = " --- Combinacion ilegal --- " ' un mismo numero aparece 2 veces. End If Next Return Join(s, ", ") End Function End Class
Realmente la clase 6_0, es casi idéntica a la clase 5_1 (la enumeración es la misma), pero la transformación de los datos difiere. Más aún puesto que alredededor de 9 de cada 10 son ilegales, creo que es inecesario, o al menos filtrar los valores ilegales. Esto es bastante sencillo, simplemente basta reducirlo desde 6 decenas y 0 unidades a 5 decenas y 0 unidades. Habria que modificar ligeramente la función del botón, que ahora exige que haya 6 dígitos, para aceptar el caso de 5 dígitos y si son todos unidades, derivarlo a la nueva clase y si no error. El otro cambio a apalicar sería en la función de enumeración que yace en el módulo... todas las referencias a la cantidad (0-5), debería aceptar un valor sensible al tamaño que se entre, lo cual se toma del parámetro 'Inicio' (por ejemplo), reclamando su longitud -1, es 6-1 para todas excepto para esta que sería 5-1... Si te interesa avisas y rehago esta última clase para filtrar las combinaciones ilegales... una captura de ejemplo. Por ultimo, quizás intereses conocer el número de la combinación seleccionada en un momento dado... para cualquier referencia de interés: Private Sub ListBox1_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ListBox1.SelectedIndexChanged Label4.Text = "Indice: " & ListBox1.SelectedIndex.Tostring End Sub
|
|
« Última modificación: 7 Mayo 2021, 15:57 pm por Serapis »
|
En línea
|
|
|
|
luis456
Desconectado
Mensajes: 551
|
Gracias Serapis
Como te comentado trabajo fuera toda las semana y para mas hoy me han vacunado contra el covid y me tiene un poco nervioso jejej me vacunaron con la estraneca o astranaca o como se llame 🤣 esperare hasta mañana para probar tus códigos (aunque no he trabajado con las clases aparte , pienso que no será difícil ,recuerda que solo soy aficionado pero me afano ya que me encanta la programación y de simple como es el titulo del post ( Ejercicio básico de combinaciones ) esto ya es un bicho grande pero yo encantado ya que he visto mas posibilidades de mejorar los cálculos para encima otros sistemas de loterías pero ese es otro tema (para depues jejej)
te aviso Luis
|
|
|
En línea
|
Que tu sabiduria no sea motivo de Humillacion para los demas
|
|
|
Serapis
|
Tranquilo... esto no es una red social, donde la gente (parece) exigir que le contesten no tardando más de no se qué cuanto tiempo (so pena de enfadarse). Cada uno a su ritmo...
Hice al final también el filtrado para los de 6_0, de dos maneras distintas... Una de ellas simplemente ignora añadir al listbox, las entradas ilegales (al final quedna así alrededor de la mitad), el otro modo de fitrado es tratarlo como lo que son solo 5 dígitos, arroja unas 15500 combinaciones, pero no lo veo interesante por que contiene así solo 5 combinaciones (pero quien sabe si un oquisiera aparte poner el 6º manualmente).
Mañana lo comprimo en un zip y lo subo a alguna página de descarga...
|
|
|
En línea
|
|
|
|
luis456
Desconectado
Mensajes: 551
|
Tranquilo... esto no es una red social, donde la gente (parece) exigir que le contesten no tardando más de no se qué cuanto tiempo (so pena de enfadarse). Cada uno a su ritmo...
Hice al final también el filtrado para los de 6_0, de dos maneras distintas... Una de ellas simplemente ignora añadir al listbox, las entradas ilegales (al final quedna así alrededor de la mitad), el otro modo de fitrado es tratarlo como lo que son solo 5 dígitos, arroja unas 15500 combinaciones, pero no lo veo interesante por que contiene así solo 5 combinaciones (pero quien sabe si un oquisiera aparte poner el 6º manualmente).
Mañana lo comprimo en un zip y lo subo a alguna página de descarga...
Gracias y para esta Hora todavía sigo vivo 😃 ya veremos mañana saludos Luis
|
|
|
En línea
|
Que tu sabiduria no sea motivo de Humillacion para los demas
|
|
|
luis456
Desconectado
Mensajes: 551
|
Hola Serapis Bueno pase mala noche ya que me dio fiebre esta vacuna y ahora tengo un super catarro me he puesto un rato con el programa pero no me aclaro que es lo que tengo que hacer o poner para armarlo pensé me seria fácil jeje .me lo llevo al trabajo a ver si por la noche lo puedo terminar saludos Luis
|
|
|
En línea
|
Que tu sabiduria no sea motivo de Humillacion para los demas
|
|
|
Serapis
|
...'armar' el programa... bueno, se supone que quien pide tiene alguna idea básica de lo que es un proyecto en el lenguaje que trata... y con leves explicaciones debería entenderlo bien. De todos modos, lo he comprimido en su carpeta y lo subo a una página de descargas. También he añadido la clase para el caso de 5 decenas y 0 unidades, es decir para introducir solo 5 dígitos (los que pueden actuar como decenas): 0,1,2,3,4 y generar sus permutaciones, y la 6ª combinación introducirla manualmente... El código de esta clase, va al final del fichero 'form1.vb' y por supuesto, tras incluirlo, s eprecisa crear una instancia para invocarlo, etc... (mira el código del proyecto que adjunto, si tienes dudas) Friend Class Permutas5_0 Implements ICombina Const MAX_COMBINAS As UInt32 = 15504 Private s_Combinas() As String Public Sub New() Call Enumerar() End Sub Public ReadOnly Property Cantidad As UInteger Implements ICombina.Cantidad Get Return MAX_COMBINAS End Get End Property Public Sub Enumerar() Implements ICombina.Enumerar s_Combinas = EnumeraComb("ABCDE", "PQRST", MAX_COMBINAS) ' 15504 End Sub ' Alfabeto: VWXYZ ' 01 02 03 04 10 12 13 14 20 21 23 24 30 31 32 34 40 41 42 43 ' A B C D E F G H I J K L M N O P Q R S T ' VW VX VY VZ WV WX WY WZ XV XW XY XZ YV YW YX YZ ZV ZW ZX ZY Public Function Tranformar(ByVal Index As Integer, ByRef Decenas() As Byte, ByRef Unidades() As Byte) As String Implements ICombina.Tranformar Dim permuta As String = s_Combinas(Index) Dim s(0 To 4) As String Dim v As Byte, m As Byte, n As Byte, k As Byte For k = 0 To 4 v = (Strings.Asc((permuta.Chars(k))) - 65) m = (Decenas(v \ 4) * 10) n = (v Mod 4) If (v < 4) Then v = (m + Decenas(n + 1)) ' VW,VX, VY, VZ ElseIf (v < 8) Then If (n = 0) Then v = (m + Decenas(n)) ' WV Else v = (m + Decenas(n + 1)) ' WX, WY, WZ End If ElseIf (v < 12) Then If (n < 2) Then v = (m + Decenas(n)) ' XV, XW Else v = (m + Decenas(n + 1)) ' XY, XZ End If ElseIf (v < 16) Then If (n < 3) Then v = (m + Decenas(n)) ' YV, YW, YX Else v = (m + Decenas(n + 1)) ' YZ End If Else v = (m + Decenas(n)) ' ZV, ZW, ZX, ZY End If If (v < 10) Then s(k) = "0" & v.ToString Else s(k) = v.ToString Next Array.Sort(s) Return Join(s, ", ") End Function End Class
Nota que puede ser optimizado para ganar en velocidad de cálculo a cambio de complicar un poco más el algoritmo yacente en la función 'Transformar'. Dado que una combinación y la siguiente suele variar la mayor parte de las veces solo 1 valor de los 6 que tiene la combinación, retener el array 's' (hacerlo estático) y calcular solo el valor o valores que cambian. Pero en lo que a mí respecta te lo dejo así, queda a tu esfuerzo optimizarlo si es de tu interés y preferencia. En general (no siempre) cualquier optimización aplicada tiende a oscurecer el mecanismo del algoritmo, lo que dificulta su entendimiento. Descarga del proyecto: https://workupload.com/file/Nu6FVTcfH2g 15'11Kb.Cuando lo descarges y abras verás en cada fichero el código que adjunta. Los 3 ficheros principales son: Module1.vb, Interface1.vb y Form1.vb que son los que contienen el código y por tanto los que tienes que mirar (o copy-paste). El proyecto exige otros más para poder arrancar en el IDE de VS. (adjunté, la operatoria de 'reset', que explicaba mensajes más arriba, pero igualmente puedes ignorarlo al menos de momento).
|
|
|
En línea
|
|
|
|
luis456
Desconectado
Mensajes: 551
|
Perfecto Serapis funciona de maravilla te has brillado con este programa, aunque claro es inasumible apostar tal cantidad de apuestas ,he echo algunas apuestas "Virtuales " y si las hubiéramos jugados ya seriamos millonarios pero no es motivo de desesperanza ya que es cuestión de aplicar variados filtros, algo de estadística y otros métodos personales (aunque esta comprobado que las estadísticas para las loterías no sirven, porque será ??? ) Bien ahora es cuestión de hacer un menú ,guardar apuestas generadas por ejemplo para poder comparar resultados y aciertos con el sorteo (para no hacerlo a mano para eso esta la programación jejje) quien habrá dicho eso algunos filtros de reducción de apuestas etc ete. Bueno a pesar de que todavía ando con los efectos de la vacuna (me callo fatal esa *****) ya creo que no muero y pienso que este programa vale la pena hacerlo muy completo y puede ser un buen programa y muy eficaz solo es cuestión de ideas y de cálculos . Para el dia de hoy este post lo han visto 4,360 veces me imagino que hay expectativas sobre el desarrollo del programa jejje solo que no veo aportes e ideas. Bueno seguiré probándolo y vemos que tal De nuevo Gracias Serapis ya te contare Luis
|
|
|
En línea
|
Que tu sabiduria no sea motivo de Humillacion para los demas
|
|
|
Serapis
|
La bonoloto, no se presta a muchas estadísticas, por la enorme cantidad de permutaciones que tolera, y como solo se juega una vez a la semana... pués aunque reúnas los sorteos de 20 años, no creo que dé para sacar conclusiones. En los casinos (por ejemplo), pequeños fallos en la fabricación o montaje de mesas de apuestas, y la puesta en escena de otros juegos, pueden manifestar 'debilidades', precisamente porque se juegan mas apuestas en un solo día que la bonoloto en todo un año... Si hay 'debilidades' en el sistema, puede ser atacado matemáticamente.Mi cuñado solía jugar a la bonoloto, yo nunca he jugado, por lo que aunque conozco el juego, no los detalles de las reglas. En tú eliges 6 números y deben cincidir todos, entonces jugar alguna número más, reduce las posibilidades combinatorias (aumentan la sposibilidades de acertar), porque siguen bastando 6 combinaciones en una apuesta de 7 números, pero como no me sé las reglas, y por ello no sé si es posible apostar 7 números y si en tal caso (el precio de tal apuesta) equivale al número de apuestas que representan... y si por tanto su coste es equivalente a las apuestas que representan, si no es así, cuantos más números se apostasen aumentarían las posibilidades (de acierto) en menor cantía económica a las (posibilidades de) reducciones de permutaciones resultantes... pero, inclsuo así, es probable que el coste por apuesta unitaria impida señalar números grandes de apuestas, pués el coste total pueda llegar a ser prohibitivo par ale bolsillo. El número de combinaciones de la bonoloto (para apuestas que exigen 6 combinacones elegibles) es de: 49 * 48 * 47 * 46 * 45 * 44, ahora bien ahí no se filtra las combinaciones que resultan de la misma pero en diferente orden, luego queda dividirla entre 1 * 2 * 3 * 4 * 5 * 6, que supone divir esas más 10 mil millonres 720 veces, lo que siguen dando una cifra elevada pero asequible de 'mantener' a raya. Yo he sido siempre más de quinielas de fútbol... siendo resultado de una 'actividad humana', las estadisticas son más fáctibles de reflejar la realidad de los equipos (siempre que ellos mismos no apuesten y por ello falsifiquen resultados, seguro que te acuerdas que se ha dado más de un caso incluso con detenciones por delitos de este tipo, no solo en España, también en otros países)... De todos modos, lo que a mi me apasiona de este tipo de juegos son las matemáticas tras ellos. Tengo una intuición en la quiniela que aún no me he demostrado (a favor o en contra), que más o menos resumo así: "elegidas 2187 apuestas específicas (no cualesquiera, evidentemente), garantizan siempre un acierto de 14 y varios de 13, amén de los de 12 y 11...". La demostración por exhaustación es inviable en tiempo computacional, así que requiere mucho esfuerzo de cálculo para reducir por combinatoria la búsqueda de tales apuestas (algún día me pondré con ello ). Para cualquier interesado en la combinatoria, deben verlo como un sistema que autocontiene o da soporte a una infinitud de bases numéricas con condiciones más o menos 'caprichosas'. Pero que, conocidas tales condiciones uno puede enumerar correlativamente en la base decimal (1,2,3,4,5,6...) para referirse al número enésimo en dicha base numérica caprichosa, vamos como cualquier otra base numérica, y por tanto poder elaborar una fórmula para tomando la enésima combinación requerida (el enésimo número en esa base numérica), obtener el equivalente con los datos que uno pretende que le represente... vamos una abstracción igual que usamos los números para contar monedas, personas, y todo en general. Es justamente la forma en que los algoritmos están representados en este proyecto, donde cada uno (por ser condionantes distintos), mantienen un alfabeto propio, al ser representados por bases numéricas distintas. Un condicionante es la no repetición de elementos, algo deseable a filtrar siempre que sea suficiente mantener un sola copia de dicho elemento, de otro modo el número de permutaciones se dispara... Baste ver la difrencia de combinaciones totales de la bonoloto, 10.068.347.520 frente a las mismas sin repetición: 13.983.816, o dicho de otra manera dada una combinación cualquiera, por ejemplo: 05, 11, 18, 25, 37, 41, se pueden reordenar de 720 maneras distintas, pero de cara a la bonoloto, son la misma apuesta que si alguien decide apostar: 37, 18, 25, 41, 05, 11. Merece la pena crear un fichero con todas esas combinaciones de casi 14millones de apuestas distintas?. La respuesta se autoresponde sola: Solo si uno no sabe luego traducir de la base numérica 13983816 a la combinación específica enumerada, supongamos que la combinación antedicha fuera la 3.100.000ª combinación de esa base numérica, es decir, string = funcion GetCombinacion(entero32 Index) string Combinacion
return Bonoloto(13983816, index) fin funcion
entero32 index = 3100000 string comb = GetCombinacion(index) imprimir "El resultado es: " + comb //Salida: "El resultado es: 05, 11, 18, 25, 37, 41"
Por lo que, si uno sabe traducir un índice de una base numérica en el valor deseado, no es necesario generar un fichero con todas las combinaciones posibles (lo mismo que con las contraseñas, que es 'mas de los mismo', bases numéricas con condicionantes más o menos capichosos), es suficiente saber el número de combinaciones que se generan. Aunque normalemente tener las combinaciones totales, puede acelerar el cálculo cuando se trata de tomar muchas combinaciones contiguas, o cambia el modo de representación de la salida (en el ppppprograma cambian los dígitos a jugar, peor mantiene una combinación equivalente, es decir son 'instancias', especifidades d ela abstracción representada en la enumeración que es a fin de cuentas la base numérica subyacente), aunque para ello deben estar en una codificación intermedia (a medio hacer entre la enumeración consecutiva y el objetivo final), de otro modo tener un fichero con: 0, 1,2,3,4,5... 10002, 10003, 10004... 13983813, 13983814, y 13983815. Pués resulta obvio que es ridículo basta conocer que esi el numero máximo de combinaciones son 13983816, el rango quedará definido entre 0 y 13983816-1, luego puede mantenerse en un programa como constante... que es lo que se hace en el programa. Saludos.
|
|
« Última modificación: 12 Mayo 2021, 01:26 am por Serapis »
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Ejercicio: las posibles combinaciones de una lista [python]
Ejercicios
|
Ragnarok
|
5
|
18,883
|
9 Septiembre 2009, 22:16 pm
por do-while
|
|
|
Ayuda en ejercicio basico
.NET (C#, VB.NET, ASP)
|
The_Saint
|
2
|
2,620
|
16 Abril 2013, 20:27 pm
por The_Saint
|
|
|
Ejercicio básico Python
Programación General
|
srg
|
3
|
2,921
|
30 Octubre 2013, 01:46 am
por Mitsu
|
|
|
Ayuda con ejercicio basico en C
« 1 2 »
Programación C/C++
|
MartaR95
|
11
|
7,083
|
12 Diciembre 2016, 01:14 am
por MAFUS
|
|
|
Ejercicio Básico de Operadores en C
Programación C/C++
|
palacio29
|
4
|
2,870
|
14 Febrero 2017, 20:50 pm
por ivancea96
|
|