Autor
|
Tema: Es dificil o imposible? (Leído 7,912 veces)
|
explorer
Desconectado
Mensajes: 102
Analista/Programador Perl
|
Ya que lo vas a ejecutar en Codepad, prueba esta versión: #!/usr/bin/perl use strict; use warnings; my $alumnos = 20; # Número de alumnos my $grupos = 4; # Tamaño de los grupos my @alumnos = 1 .. $alumnos; my $n_grupo = 1; while (@alumnos >= $grupos) { # Creamos un @nuevo_grupo compuesto de tantos alumnos como de grande # sean los $grupos, elegidos al azar de los @alumnos restantes my @nuevo_grupo = map { splice @alumnos, rand(@alumnos), 1 } 1 .. $grupos; print "Grupo $n_grupo: [@nuevo_grupo]\n"; $n_grupo++; } # Resto que ha quedado sin asignar if (@alumnos) { print "Grupo $n_grupo: [@alumnos]\n"; }
|
|
|
En línea
|
|
|
|
yoyo2002
Desconectado
Mensajes: 8
|
Exacto, eso es, es decir, quiero todas las combinaciones posibles existentes entre los 20 en grupos de 4, sin que ninguno de los 20 vuelva a coincidir con el resto en la combinacion, sea cual sea el orden, pero que no coincidan 2 ni más numeros en una nueva combinación.
|
|
|
En línea
|
|
|
|
yoyo2002
Desconectado
Mensajes: 8
|
Gracias, ahora sí funciona. Pero ¿podría ser que salieran todas las combinaciones de 4 números existentes sin repetición, sin importar el orden en que salga? Es decir, si sale la combinación, 3-5-9-11, esta misma con otro orden no me vale (ej: 5-11-9-5) y tampoco me valdria otra donde volvieran a coincidir dos variables o más... Es decir, ya el 3 no puede volver a coincidir ni con el 5 ni con el 9 ni con el 11, al igual que el resto. Sé que es dificil.... Ya que lo vas a ejecutar en Codepad, prueba esta versión: #!/usr/bin/perl use strict; use warnings; my $alumnos = 20; # Número de alumnos my $grupos = 4; # Tamaño de los grupos my @alumnos = 1 .. $alumnos; my $n_grupo = 1; while (@alumnos >= $grupos) { # Creamos un @nuevo_grupo compuesto de tantos alumnos como de grande # sean los $grupos, elegidos al azar de los @alumnos restantes my @nuevo_grupo = map { splice @alumnos, rand(@alumnos), 1 } 1 .. $grupos; print "Grupo $n_grupo: [@nuevo_grupo]\n"; $n_grupo++; } # Resto que ha quedado sin asignar if (@alumnos) { print "Grupo $n_grupo: [@alumnos]\n"; }
|
|
|
En línea
|
|
|
|
explorer
Desconectado
Mensajes: 102
Analista/Programador Perl
|
Ahora estoy un poco dormido, pero creo que la solución es esta: my $visto; for my $a1 (1 .. 20) { for my $a2 (1 .. 20) { for my $a3 (1 .. 20) { for my $a4 (1 .. 20) { my @ordenados = sort { $a <=> $b } $a1, $a2, $a3, $a4; # salimos si hay coincidencia next if $ordenados[0] == $ordenados[1] or $ordenados[0] == $ordenados[2] or $ordenados[0] == $ordenados[3] or $ordenados[1] == $ordenados[2] or $ordenados[1] == $ordenados[3] or $ordenados[2] == $ordenados[3] ; # salimos si hay coincidencia por pares next if $visto{"$ordenados[0]-$ordenados[1]"} or $visto{"$ordenados[0]-$ordenados[2]"} or $visto{"$ordenados[0]-$ordenados[3]"} or $visto{"$ordenados[1]-$ordenados[2]"} or $visto{"$ordenados[1]-$ordenados[3]"} or $visto{"$ordenados[2]-$ordenados[3]"} ; # recordamos todos los pares nuevos $visto{"$ordenados[0]-$ordenados[1]"} = $visto{"$ordenados[0]-$ordenados[2]"} = $visto{"$ordenados[0]-$ordenados[3]"} = $visto{"$ordenados[1]-$ordenados[2]"} = $visto{"$ordenados[1]-$ordenados[3]"} = $visto{"$ordenados[2]-$ordenados[3]"} = 1; # Impresión } } } }
La salida es algo corta: [1-2-3-4] [1-5-6-7] [1-8-9-10] [1-11-12-13] [1-14-15-16] [1-17-18-19] [2-5-8-11] [2-6-9-12] [2-7-10-13] [2-14-17-20] [3-5-9-13] [3-6-8-14] [3-7-11-15] [3-10-12-16] [4-5-10-14] [4-6-11-16] [4-7-8-12] [4-9-15-17] [4-13-18-20] [5-12-15-18] [5-16-19-20] [6-10-15-19] [7-9-14-18] [8-13-16-17]Curiosamente, el alumno 1 nunca estará con el número 20. ¿Por qué? Supongamos que queremos la combinación [1-a-b-20]. ¿Qué valores serían a o b?. Pues cualquiera entre 2 y 19... pero eso no es posible, porque todos los números entre 2 y 19 ya han salido con el 1 antes (mirar las 6 primeras combinaciones). Y se cumpliría la condición de que el 1 ya se ha visto con cualquiera de esos números. Me temo que esto no es lo que quieres... Según las condiciones que has puesto, la segunda es la que limita la salida de todas las combinaciones: «tampoco me valdría otra donde volvieran a coincidir dos variables o más...». Como los grupos son de 4, eso quiere decir que habrá alumnos que estarán en más combinaciones (el 1, seis veces), pero otras, menos (el 20, tres veces) por la razón explicada antes.
|
|
« Última modificación: 22 Marzo 2012, 00:23 am por explorer »
|
En línea
|
|
|
|
yoyo2002
Desconectado
Mensajes: 8
|
Muchísimas gracias. Aunque no salgan todas, ya el resto de combinaciones las intentaré hacer manualmente, aunque tenga que usar una "Variable comodín". Ahora estoy un poco dormido, pero creo que la solución es esta: my $visto; for my $a1 (1 .. 20) { for my $a2 (1 .. 20) { for my $a3 (1 .. 20) { for my $a4 (1 .. 20) { my @ordenados = sort { $a <=> $b } $a1, $a2, $a3, $a4; # salimos si hay coincidencia next if $ordenados[0] == $ordenados[1] or $ordenados[0] == $ordenados[2] or $ordenados[0] == $ordenados[3] or $ordenados[1] == $ordenados[2] or $ordenados[1] == $ordenados[3] or $ordenados[2] == $ordenados[3] ; # salimos si hay coincidencia por pares next if $visto{"$ordenados[0]-$ordenados[1]"} or $visto{"$ordenados[0]-$ordenados[2]"} or $visto{"$ordenados[0]-$ordenados[3]"} or $visto{"$ordenados[1]-$ordenados[2]"} or $visto{"$ordenados[1]-$ordenados[3]"} or $visto{"$ordenados[2]-$ordenados[3]"} ; # recordamos todos los pares nuevos $visto{"$ordenados[0]-$ordenados[1]"} = $visto{"$ordenados[0]-$ordenados[2]"} = $visto{"$ordenados[0]-$ordenados[3]"} = $visto{"$ordenados[1]-$ordenados[2]"} = $visto{"$ordenados[1]-$ordenados[3]"} = $visto{"$ordenados[2]-$ordenados[3]"} = 1; # Impresión } } } }
La salida es algo corta: [1-2-3-4] [1-5-6-7] [1-8-9-10] [1-11-12-13] [1-14-15-16] [1-17-18-19] [2-5-8-11] [2-6-9-12] [2-7-10-13] [2-14-17-20] [3-5-9-13] [3-6-8-14] [3-7-11-15] [3-10-12-16] [4-5-10-14] [4-6-11-16] [4-7-8-12] [4-9-15-17] [4-13-18-20] [5-12-15-18] [5-16-19-20] [6-10-15-19] [7-9-14-18] [8-13-16-17]Curiosamente, el alumno 1 nunca estará con el número 20. ¿Por qué? Supongamos que queremos la combinación [1-a-b-20]. ¿Qué valores serían a o b?. Pues cualquiera entre 2 y 19... pero eso no es posible, porque todos los números entre 2 y 19 ya han salido con el 1 antes (mirar las 6 primeras combinaciones). Y se cumpliría la condición de que el 1 ya se ha visto con cualquiera de esos números. Me temo que esto no es lo que quieres... Según las condiciones que has puesto, la segunda es la que limita la salida de todas las combinaciones: «tampoco me valdría otra donde volvieran a coincidir dos variables o más...». Como los grupos son de 4, eso quiere decir que habrá alumnos que estarán en más combinaciones (el 1, seis veces), pero otras, menos (el 20, tres veces) por la razón explicada antes.
|
|
|
En línea
|
|
|
|
Runex
Desconectado
Mensajes: 192
http://tutogramacion.blogspot.com
|
#!/usr/bin/env python import random,os class partidos: def __init__(self,alumnos,grupos,grupox): self.alumnos = alumnos self.grupos = grupos self.grupox = grupox self.creagrupos(alumnos,grupos,grupox) def creagrupos(self,alumnos,grupos,grupox): print "La cantidad de alumnos es: " + str(self.alumnos) print "La cantidad de alumnos por grupo es: " + str(self.grupos) print "La cantidad de grupos es: " + str(self.grupox) self.x = 0 self.v = 0 while self.v < self.grupox: print "Grupo " + str(self.v) while self.x < self.grupos: y = random.randint(0,20) print y, self.x +=1 self.x = 0 print "\n" self.v += 1 print "Inserte numero alumnos: " alumnos = input("Alumnos>") print "Inserte numero de alumnos por grupo: " grupos = input("Alumnos x Grupo>") print "Inserte la cantidad de grupos que desea:" grupox = input("Grupos>") os.system("clear") if __name__ == "__main__": t = partidos(alumnos,grupos,grupox)
Hasta ahí he llegado, se me ocurre una posible solución, añadiendo cada numero aleatorio que se genere en una lista y comparando después cada elemento, sin embargo eso se escapa a mi capacidad de escritura de código XD. En el programa que te he escrito yo, puedes añadir tu manualmente el numero de alumnos total, la cantidad de alumnos por grupo y la cantidad de grupos que deseas crear, así te puede servir para otras veces que desees hacer equipos con una cantidad diferente de alumnos De todas formas creo que la solución ofrecida por explorer es bastante buena para tu objetivo
|
|
|
En línea
|
"No renunciaría al bambú. Nunca renuciaría a ti. No te compares con otros" "El me dijo: El bambú tenía un propósito diferente al del helecho, sin embargo eran necesarios y hacían del bosque un lugar hermoso".
|
|
|
Eleкtro
Ex-Staff
Desconectado
Mensajes: 9.878
|
se me ocurre una posible solución, añadiendo cada numero aleatorio que se genere en una lista y comparando después cada elemento
Yo probé otra cosa parecida: 1º - Escribir las 20 combinaciones aleatorias (20 .txt) 2º - comparar cada texto con el primer texto, Y Si algún número se repite, vuelve a crear el texto, y lo vuelve a comparar, hasta que no se repita ningún número y ningún texto séa igual. Pero ese método puede tardar demasiado, es poco efectivo, la verdad es que en 20 min no consiguió crear un texto aleatorio que no repita ningún número en algún grupo... (¿Mala suerte?) Quizás les sirva como idea. Salu2
|
|
|
En línea
|
|
|
|
yoyo2002
Desconectado
Mensajes: 8
|
Muchísimas gracias de nuevo a EleKtro H@cker y Runex, sé que no es facil lo que quiero, pero me habéis ayudado bastante y bien.
Gracias.
|
|
|
En línea
|
|
|
|
Runex
Desconectado
Mensajes: 192
http://tutogramacion.blogspot.com
|
Yoyo si aun necesitas el programa avisa, que ya se me ha ocurrido una forma factible de hacerlo . Un saludo
|
|
|
En línea
|
"No renunciaría al bambú. Nunca renuciaría a ti. No te compares con otros" "El me dijo: El bambú tenía un propósito diferente al del helecho, sin embargo eran necesarios y hacían del bosque un lugar hermoso".
|
|
|
|
|