viernes, 6 de julio de 2018

Juego de la tirada más larga

Reto: Juego de la tirada más larga

Cada tirada genera una sucesión de números aleatorios entre 1 y 100. La tirada finaliza cuando se obtiene un número par, entre 40 y 60. El juego lanza 20 tiradas y al final se dice que tirada ha sido la más larga. 




Método 1

Necesitaremos la variable maxi para contabilizar el número de elementos de la tirada más larga. Nos metemos en un bucle for para hacer las 20 tiradas. Dentro del bucle inicializamos la variable texto como una cadena vacía. Esta variable contendrá los números que componen una tirada. La variable n contará el número de elementos que componen una tirada. Nos metemos en un bucle while para ir generando los elementos de cada tirada. En este caso ha de ser un bucle de tipo while ya que no sabemos a priori cuan larga será la tirada. Se genera el número aleatorio x, que se integra dentro de la variable de texto. Nos econtramos con un condicional if que pretende detectar cuándo se detendrá la generación de elementos dentro de una tirada.


Si el valor de x es par y está entre 40 y 60 entonces se cumplirá la condición e imprimiremos los números de la tirada i-ésima. Nos metemos en un nuevo condicional if para anotar el número de elementos de la tirada más larga. Esto se hace con la variable maxi, y con la variable tirmax lo que hacemos es anotar en cuál de las 20 tiradas se ha alcanzado el máximo. Esta será la tirada más larga. La instrucción break hace que nos salgamos del bucle while después de haber tratado la tirada i-ésima y devuelve el flujo del programa al bucle for. Si no se cumple la condición de haber llegado a un par entre 40 y 60, esto quiere decir que necesitamos generar un nuevo número aleatorio dentro de esta misma tirada y entonces tendremso que hacer n+=1 lo cual incrementa el valor del contador en una unidad. Al final se imprime la longitud de la tirada que más elementos tiene y se indica qué tirada fue en la que se alcanzó la máxima longitud.
Este método tiene el inconveniente de que si existe empate en el máximo entre dos o más tiradas no se indican todas ellas, unicamente se imprimirá una de ellas. Esto se soluciona en el método 2.


import random
maxi=0
for i in range(1,21):
  texto=''
  n=1
  while True:
    x=random.randint(1,100)
    texto+=str(x)+' '
    if x%2==0 and x>=40 and x<=60:
      print('Tirada',i,':',texto)
      if n>=maxi:
        maxi=n
        tirmax=i
      break
    n+=1
print('El maximo nº de elementos ha sido',maxi,'y se alcanza en la tirada',tirmax)


Método 2

En este caso hemos realizado una variante del caso anterior para que recoja varias tiradas en caso en empate. En la imagen adjunta se puede ve como las tiradas 7, 15, 17 y 18 empatan en longitud puesto que todas ellas tienen 9 elementos. Hemos logrado anotarlas usando la variable tirmax como un string que va recogiendo las cadenas cuando estas llegan al máximo.
La cadena tirmax añade una coma cada vez que se agrega un número. Lo que hemos hecho es eliminar la última coma y añadir un punto para cerrar la frase. Esto se logra con la expresión siguiente.

tirmax[:len(tirmax)-2]+'.'



import random
maxi=0
tirmax='' #texto que recoge la tirada o tiradas de longitud máxima
for i in range(1,21): #generamos las tiradas 1 a 20
  texto='' #cadena que recoge los valores numéricos de una tirada
  n=1 #número de elementos que tiene cada tirada
  while True:
    x=random.randint(1,100) #aleatorio entero entre 1 y 100
    texto+=str(x)+' ' #añadimos a la frase un nuevo elemento y un espacio
    if x%2==0 and 40<=x<=60: #cuando se ha de detener la generación de números en cada tirada
      print('Tirada',i,':',texto) #se imprime la frase de la tirada i-ésima
      if n>maxi: #si el nº de elemento de esta tirada (n) es mayor que el máximo que existía hasta ahora
        maxi=n #nuevo máximo
        tirmax=str(i)+','+' ' #si tenemos nuevo máximo la frase tirmax se inicializa con el indice de la tirada actual
      elif n==maxi: #si el nº de elemento de la tirada es igual al máximo actual
        tirmax+=str(i)+','+' ' #la frase tirmax añade el indice de la tirada actual
      break #nos salimos del bucle while porque ya se ha cumplido la condición del if
    n+=1 #contador: un nuevo elemento dentro de la tirada en la que estamos
print('El maximo nº de elementos ha sido ',maxi,' y se alcanza en ',tirmax[:len(tirmax)-2]+'.')
#al final se imprime tirmax pero se quita la última coma y se añade al final un punto.


Método 3

Con el código del método 2 puede llegar a ser muy tedioso ejecutarlo varias veces hasta que se obtenga una jugada donde dos o más tiradas de lógitud máxima se den simultaneamente.  Lo que hemos hecho con este método es embeber el código en un bucle while que busca que el número de tiradas repetidas de longitud máxima sea mayor o igual a un cierto valor. En el ejemplo hemos puesto que sean cuatro las tiradas repetidas.


También hemos añadido un condicional if que consigue que si el número que se genera aleatoriamente está entre 1 y 9 se le añade un espacio vacío al imprimirle en la fila de su tirada. Con ello lo que conseguimos es que las tiradas que tengan el mismo número de elementos queden visualmente con la misma longitud. Algo similar hemos añadido para que el número de tirada entre 1 y 0 lleve un espacio previo adicional para mejorar el aspecto visual. También hemos modificado el rango de variación del número aleatorio para que se mueva entre 1 y 99. Hemos evitado el 100 porque al tener tres dígitos visualmente puede alterar la longitud del texto cuando aparece en una tirada.


import random
while True:
  maximo=0
  tirmax=''
  for i in range(1,21):
    texto=''
    n=1
    while True:
      x=random.randint(1,99)
      if x>=10:
        texto+=str(x)+' '
      else:
        texto+=' '+str(x)+' ' #añadimos un espacio previo para que visualmente quede bien
      if x%2==0 and x>=40 and x<=60:
        if i>=10:
          print('Tirada',i,':',texto)
        else: #si i está entre 1 y 9 se antecede un espacio para que visualmente quede bien
          print('Tirada ',i,':',texto)
        if n>maximo:
          maximo=n
          tirmax=str(i)+','+' '
          repes=1 #contador de tiradas repetidas de longitud máxima
        elif n==maximo:
          tirmax+=str(i)+','+' '
          repes+=1 #el contador de tiradas repetidas máximas se incrementa
        break
      n+=1
  print('El maximo nº de elementos ha sido ',maximo,' y se alcanza en ',tirmax[:len(tirmax)-2]+'.')
  if repes>=4: #queremos un mínimo de 4 tiradas de máxima longitud
    break

No hay comentarios:

Publicar un comentario