Autor Tema: Ejercicio! entrega CU00672B generar números aleatorios java  (Leído 8475 veces)

Jorge lopez

  • Sniper
  • Intermedio
  • ***
  • APR2.COM
  • Mensajes: 248
  • @SniperOfElite
    • Ver Perfil
 Hola!
public class EntradaDeTeclado
Código: [Seleccionar]
import java.util.Scanner;
public class EntradaDeTeclado
{
 private String entradaTeclado;
 public EntradaDeTeclado()
 {
   entradaTeclado = "";
 }
 public void pedirEntrada()
 {
   Scanner entradaEscaner = new Scanner (System.in);
   entradaTeclado = entradaEscaner.nextLine ();
 }
 public String getEntrada()
 {
   return entradaTeclado;
 }
}
public class GeneradorNumAleatorio
Código: [Seleccionar]
import java.util.*;
public class GeneradorNumAleatorio
{
  private ArrayList<Integer> listaDeNum;
  private Random numAleatorio;
  public GeneradorNumAleatorio()
  {
    listaDeNum = new ArrayList<Integer>();
    numAleatorio = new Random();
  }
 
  public void addNumeros(int cantidad)
  {
    for(int i = 1; i <= cantidad; i++)
    {
      listaDeNum.add(i);
    }
  }
 
  public void mostrarNumEnLista()
  {
    for(Integer numero: listaDeNum)
    {
      System.out.println(numero);
    }
  }
 
  public int getSize()
  {
    return listaDeNum.size();
  }
 
  public int generarNumAleat()
  {
    return listaDeNum.get(numAleatorio.nextInt(listaDeNum.size()));
  }
}
public class AdivinarNum
Código: [Seleccionar]
import javax.swing.*;
public class AdivinarNum
{
 public AdivinarNum()
 {
    //Nada que declarar
 }
 
 public static void main(String []args)
 {
   System.out.println("Vamos a jugar a adivinar un numero, primero introduce la cantidad de números que quieres que contenga la adivinanza:");
   EntradaDeTeclado entradaMain = new EntradaDeTeclado();
   GeneradorNumAleatorio listaConNum = new GeneradorNumAleatorio();
   entradaMain.pedirEntrada();
   int entero = Integer.parseInt(entradaMain.getEntrada());
   listaConNum.addNumeros(entero);
   System.out.println("\f\nAhora intenta adivinar el numero secreto que se ha elegido aleatoriamente entre los números del 1 al " + listaConNum.getSize() + ".");
   int numSecreto = listaConNum.generarNumAleat();
   boolean resuelto = false;
   int i = 0;
   do
   {
     entradaMain.pedirEntrada();
     int stringToInt = Integer.parseInt(entradaMain.getEntrada());
     int respuesta = 2;/*int respuesta se inicializa con un valor distinto a los valores numéricos que representan botones en el método showConfirmDialog(null,"","",0);
     de la clase JOptionPane, los cuales son 0 = botón: yes/si y 1 = botón: not/no, para así evitar errores en la ejecución del programa.*/
     if(numSecreto == stringToInt)
     {
        resuelto = true;
     }
     else
     {
       resuelto = false;
     }
     if(resuelto == false && numSecreto < stringToInt)
     {
        System.out.println("\f\nEl numero secreto no es " + stringToInt + ", intenta con un numero menor."); i++;
     }
     else if(resuelto == false && numSecreto > stringToInt)
     {
        System.out.println("\f\nEl numero secreto no es " + stringToInt + ", intenta con un numero mayor."); i++;
     }
     if(resuelto == true)
     {
       System.out.println("\f\nFelicitaciones! Has acertado, el numero secreto es " + numSecreto + ".\nTe costo " + i +  " intentos fallidos adivinar este numero secreto.");
     }
     if(resuelto == true)
     {
        respuesta = JOptionPane.showConfirmDialog(null,"Te gustaría volver a adivinar otro numero secreto ?","Confirmar",0);
     }
     if(respuesta == 0)
     {
       System.out.println("\f\nSe ha elegido un nuevo numero secreto al azar entre el 1 y el " + listaConNum.getSize() + ", intenta adivinarlo:");
       numSecreto = listaConNum.generarNumAleat();
       resuelto = false;
       i = 0;
     }
     else if(respuesta == 1)
     {
       System.out.println("\f\nComo prefieras!\nGracias por jugar a adivinar números.\nHasta luego...");
       resuelto = true;
     }
   }while(resuelto == false);
 }
}
Saludos!
« Última modificación: 31 de Agosto 2014, 10:56 por Alex Rodríguez »
while(estesVivo)
{
  aprende();
  ayuda();
  enseña();
}
if(mueres){teRecordaran();}

dongo

  • Intermedio
  • ***
  • Mensajes: 177
    • Ver Perfil
Re:Ejercicio! entrega CU00672B
« Respuesta #1 en: 06 de Agosto 2014, 18:50 »
Hola, he probado tu ejercicio y funciona perfectamente. Si has entendido todo lo que has echo y no tienes ninguna duda, date una palmadita en la espalda XDD y nada, a seguir trabajando. Un saludo! 

César Krall

  • Moderador Global
  • Experto
  • *******
  • Mensajes: 2078
  • No vales por lo que dices, sino por lo que haces
    • Ver Perfil
    • aprenderaprogramar.com
Re:Ejercicio! entrega CU00672B
« Respuesta #2 en: 06 de Agosto 2014, 20:08 »
Hola, yo también he mirado y probado el código y funciona bien, pero tengo una matización que hacer en función de lo que dice el enunciado:

Crea un programa Java que permita “jugar a adivinar un número” como se expone a continuación. El programa debe iniciarse indicando “Se ha generado un número aletatorio entero entre 1 y 100, intente adivinarlo”. El usuario introducirá un número y si el número aleatorio generado por el ordenador es menor deberá indicarse “No has acertado: el número es menor. Prueba otra vez”. Si el usuario introduce un número menor que el número aleatorio deberá indicarse “No has acertado: el número es mayor”. El programa terminará cuando el usuario introduzca el número aleatorio que había escogido el ordenador.

En teoría, debías crear un número aleatorio entre 1 y 100 (en tu caso has decidido que 100 sea un valor flexible, a lo que no le veo problema).

El problema lo veo aquí:

  public void addNumeros(int cantidad)
  {
    for(int i = 1; i <= cantidad; i++)
    {
      listaDeNum.add(i);
    }
  }

Realmente no estás generando un número aleatorio entre 1 y cantidad, sino que estás creando un ArrayList de enteros entre 1 y cantidad, para luego elegir aleatoriamente un número de entre los números existentes en ese ArrayList.

Ahora te planteo las siguientes preguntas:

¿Realmente es necesario crear la lista para después elegir el número?

¿Si tuviéramos que elegir un aleatorio entre decimales qué ocurriría?

¿Sería eficiente el proceso si el aleatorio hubiera que elegirlo entre 1 y 100000000000?

Donde quiero ir a parar es que aunque en este contexto no tenga demasiada importancia (de hecho el tiempo que puede consumir es inapreciable para números pequeños) el diseño falla en cuanto a eficiencia: hacer algo, que consume recursos como memoria y tiempo, sin que realmente sea necesario.

El código lo veo bien trabajado, pero esta es la impresión que he sacado en cuanto al diseño, aunque quizás me equivoque en algo, por ello creo que lo mejor es que lo revises tú mismo y trates de valorar lo comentado. Saludos.
Responsable de departamento de producción aprenderaprogramar.com

dongo

  • Intermedio
  • ***
  • Mensajes: 177
    • Ver Perfil
Re:Ejercicio! entrega CU00672B
« Respuesta #3 en: 06 de Agosto 2014, 20:18 »
Yo estoy igual que cesar, me quede rallado también con ese ArrayList que creas y rellenas.
Como comenta Cesar, también pienso que es totalmente innecesario ese ArrayList, no comente nada, ya que tu al acertar el número preguntas si quieres jugar otra vez, y vuelves a coger otro número del arraylist, aun así sigo pensando que es innecesario, ya que te lleva menos memoria generar un numero aleatorio cada vez que se acierta, que mantener un array de números durante toda la ejecución.

Y como dice Krall y si fuera un rango de mil trillones de billones......XDDD

Buena puntualización krall 

Jorge lopez

  • Sniper
  • Intermedio
  • ***
  • APR2.COM
  • Mensajes: 248
  • @SniperOfElite
    • Ver Perfil
Re:Ejercicio! entrega CU00672B
« Respuesta #4 en: 08 de Agosto 2014, 02:52 »
 Hola!
Mi primera intención al crear un ArrayList fue la siguiente: 1ro: Crear un ArrayList que contenga tantos números como indique la variable cantidad. 2do: que dichos numero se agregaran al ArrayList en orden ascendente desde el 1 hasta el valor de cantidad, desde la posición 0 hasta la posición (cantidad - 1). y 3ro: usar una sentencia como:
Código: [Seleccionar]
listaDeNum.get(numAleatorio.nextInt(listaDeNum.size())); para usar el numero devuelto por esta sentencia como el numero secreto a adivinar.

Una vez revisado el código luego de el comentario de Cesar, me di cuenta que esta intención ademas de ser innecesaria, limita la eficiencia del programa.
 
He rediseñado el código corrigiendo los puntos comentados por Cesar y e incorporado nuevas mejoras.

Citar
Ahora te planteo las siguientes preguntas:

1: ¿Realmente es necesario crear la lista para después elegir el número?

2: ¿Si tuviéramos que elegir un aleatorio entre decimales qué ocurriría?

3: ¿Sería eficiente el proceso si el aleatorio hubiera que elegirlo entre 1 y 100000000000?

 Respuestas:

1: No, no es necesario  ;D

2: Para esto abría que rediseñar el código para que trabaje con números tipo float y usar métodos como nextFloat(); ext.

3: Al indicar un numero tan grande como 1000000000, se obtiene un error de tipo: java.lang.OutOfMemoryError: Java heap space (in java.util.ArrayList). Tambien note que se demora un tiempo en saltar este error, al parecer esta operación consume bastante memoria.

A continuación las dos clases rediseñadas:
public class GeneradorNumAleatorio
Código: [Seleccionar]
import java.util.*;
public class GeneradorNumAleatorio
{
  private Random numAleatorio;
  private long cantidad;
  public GeneradorNumAleatorio()
  {
    numAleatorio = new Random();
    cantidad = 0L;
  }
 
  public void setCantidad(long entero)
  {
    cantidad = entero;
  }
 
  public long getCantidad()
  {
    return cantidad;
  }
 
  public long generarNumAleat()
  {
    return numAleatorio.nextInt((int)getCantidad()) + 1;
  }
}
public class AdivinarNum
Código: [Seleccionar]
import javax.swing.*;
public class AdivinarNum
{
 public AdivinarNum()
 {
    //Nada que declarar
 }
 
 public static void main(String []args)
 {
   System.out.println("Vamos a jugar a adivinar un numero, primero introduce la cantidad de números que quieres que contenga la adivinanza:");
   EntradaDeTeclado entradaMain = new EntradaDeTeclado();
   GeneradorNumAleatorio aleatorio = new GeneradorNumAleatorio();
   entradaMain.pedirEntrada();
   long entero = Long.valueOf(entradaMain.getEntrada());
   aleatorio.setCantidad(entero);
   System.out.println("\f\nAhora intenta adivinar el numero secreto que se ha generado aleatoriamente entre los numeros del 1 al " + entero + ".");
   long numSecreto = aleatorio.generarNumAleat();
   boolean resuelto = false;
   int i = 0;
   do
   {
     entradaMain.pedirEntrada();
     long stringToLong = Long.valueOf(entradaMain.getEntrada());
     int respuesta = 2;/*int respuesta se inicializa con un valor distinto a los valores numéricos que representan botones en el método showConfirmDialog(null,"","",0);
     de la clase JOptionPane, los cuales son 0 = boton: yes/si y 1 = boton: not/no, para así evitar errores en la ejecución del programa.*/
     long merrindo = Long.valueOf(entradaMain.getEntrada());
     
     if(merrindo == 0)
     {
       System.out.println("\f\nEsperando...");
       JOptionPane.showMessageDialog(null,"El numero secreto era: " + numSecreto + "\nPulsa aceptar/Ok para continuar...", "Ups! te has rendido.", 2);
       resuelto = true;
     }
     else if(numSecreto == stringToLong)
     {
        resuelto = true;
     }
     else
     {
       resuelto = false;
     }
     if(resuelto == false && numSecreto < stringToLong)
     {
        System.out.println("\f\nEl numero secreto no es " + stringToLong + ", intenta con un numero menor. Si deseas rendirte y conocer la respuesta introduce el numero \"0" + "\""); i++;
     }
     else if(resuelto == false && numSecreto > stringToLong)
     {
        System.out.println("\f\nEl numero secreto no es " + stringToLong + ", intenta con un numero mayor. Si deseas rendirte y conocer la respuesta introduce el numero \"0" + "\""); i++;
     }
     if(resuelto == true && merrindo != 0)
     {
       System.out.println("\f\nFelicitaciones! Has acertado, el numero secreto es " + numSecreto +
       ".\nTe costo " + i +  " intentos fallidos adivinar este numero secreto.\n\n\nEsperando respuesta...");
     }
     if(resuelto == true)
     {
       if(numSecreto != stringToLong)
       {
         System.out.println("\fEsperando respuesta...");
       }
       respuesta = JOptionPane.showConfirmDialog(null,"Te gustaría intentar adivinar otro numero secreto ?","Confirmar",0);
     }
     if(respuesta == 0)
     {
       System.out.println("\f\nSe ha generado un nuevo numero secreto al azar entre el 1 y el " + entero + ", intenta adivinarlo:");
       numSecreto = aleatorio.generarNumAleat();
       resuelto = false;
       i = 0;
     }
     else if(respuesta == 1)
     {
       System.out.println("\f\nFinalizando...");
       JOptionPane.showMessageDialog(null,"Hasta luego...","Gracias por jugar a adivinar números",1);
       resuelto = true;
       if(resuelto = true)
       {
         System.out.println("\fFin del juego...");
       }
     }
   }while(resuelto == false);
 }
}
 
La clase EntradaDeTeclado no tuvo ningún cambio.
Gracias por sus comentarios y observaciones.
Saludos!
« Última modificación: 08 de Agosto 2014, 02:59 por Sniper »
while(estesVivo)
{
  aprende();
  ayuda();
  enseña();
}
if(mueres){teRecordaran();}

dongo

  • Intermedio
  • ***
  • Mensajes: 177
    • Ver Perfil
Re:Ejercicio! entrega CU00672B
« Respuesta #5 en: 08 de Agosto 2014, 13:43 »
Muchísimo más simple y eficiente, como bien tu decías, el arraylist era totalmente inútil. Ha veces nos complicamos buscando una solución, cuando la solución es mucho mas sencilla.

Ahora te doy una cosita para que amplíes tu librería de objetos: El objeto "java.math.BigInteger"
Como bien sabes, o deberás saber, todos los tipos básicos tienen un limite máximo de valores. Pues bien, con BigInteger puedes crear números todo lo grandes que quieras.

Te añado un ejemplo para que veas los limites de cada tipo y después un ejemplo del uso del BigInteger:
Código: [Seleccionar]
import java.math.BigInteger;

public class Prueba {
    public static void main(String [] arg){
       System.out.println("El maximo numero int es: "+Integer.MAX_VALUE);
       System.out.println("El maximo numero long es: "+Long.MAX_VALUE);
       System.out.println("El maximo numero double es: "+Double.MAX_VALUE);
       System.out.println("El maximo numero short es: "+Short.MAX_VALUE);
        System.out.println("");
         System.out.println("Pero aun así, Con BigInteger puedes crear un numero mucho mas grandes, por ejemplo: ");
       
       BigInteger x = new BigInteger("1234567898765432123456786546846498416744");
       System.out.println("Este es un numero tocho: "+x.toString());
       
       System.out.println("El numero tocho entre 2 es: "+x.divide(new BigInteger("2")));
       
    }
}
Aun así esta bien eso de intentar complicar las cosas, así te pasan cosas como estas y te das cuenta de cosas que si te limitas a realizar solo lo que ya sabes hacer.

Bueno un saludo.
« Última modificación: 08 de Agosto 2014, 18:11 por dongo »

Jorge lopez

  • Sniper
  • Intermedio
  • ***
  • APR2.COM
  • Mensajes: 248
  • @SniperOfElite
    • Ver Perfil
Re:Ejercicio! entrega CU00672B
« Respuesta #6 en: 08 de Agosto 2014, 18:24 »
 Aunque no pude asociar un  BigInteger("numero") a mi código y lograr que compile y trabaje como a de esperarse, encuentro el objeto BigInteger("numero") muy muy muy útil e interesante.
Gracias por este aporte dongo.
Saludos!
« Última modificación: 08 de Agosto 2014, 18:35 por Sniper »
while(estesVivo)
{
  aprende();
  ayuda();
  enseña();
}
if(mueres){teRecordaran();}

dongo

  • Intermedio
  • ***
  • Mensajes: 177
    • Ver Perfil
Re:Ejercicio! entrega CU00672B
« Respuesta #7 en: 08 de Agosto 2014, 18:40 »
jajaja es mas complejo trabajar con bucles con este tipo de números, pero no imposible:

Código: [Seleccionar]
import java.math.BigInteger;
import java.lang.Thread;

public class Prueba {
    public static void main(String [] arg) throws InterruptedException  {
       BigInteger x = new BigInteger("1234567898765432123456786546846498416744");
       System.out.println("Este es un numero tocho: "+x.toString());
       
       System.out.println("El numero tocho entre 2 es: "+x.divide(new BigInteger("2")));
       
       
       BigInteger x2=new BigInteger("1");
       BigInteger incremento=new BigInteger("1");
       while(!x2.equals(x)){
           System.out.println("x vale: "+x2);
           x2=new BigInteger(x2.add(incremento).toString());
           Thread.sleep(300);
       }
       
    }
}

Nota: va tan despacito, porque le he puesto una pausa de 300ms, para evitar que el procesador se sature, jeje. Pero como ves ahí tienes un bucle prácticamente interminable... XDDD

Jorge lopez

  • Sniper
  • Intermedio
  • ***
  • APR2.COM
  • Mensajes: 248
  • @SniperOfElite
    • Ver Perfil
Re:Ejercicio! entrega CU00672B
« Respuesta #8 en: 08 de Agosto 2014, 21:27 »
 El problema para que BigInteger trabaje en mi código seria el siguiente:

Que la variable cantidad contenga un BigInteger y que el numero aleatorio se genere entre 1 y el valor de cantidad. Ejempl: 1 y "999999999999999999999999999999999999999" indicado por el usuario.

No se si me e explicado bien.
Saludos.
while(estesVivo)
{
  aprende();
  ayuda();
  enseña();
}
if(mueres){teRecordaran();}

dongo

  • Intermedio
  • ***
  • Mensajes: 177
    • Ver Perfil
Re:Ejercicio! entrega CU00672B
« Respuesta #9 en: 08 de Agosto 2014, 22:14 »
Pues la verdad que el post se ta saliendo bastante del tema, te paso ya el como generar números aleatorios, aunque los rangos van en potencias de dos, es decir:

entre 0 y 2
entre 0 y 4
entre 0 y 8
entre 0 y 16
....
entre 0 y 1024
....

Total te pongo el ejemplo que esta bien descrito y tu lo analizas. te servirá para generar números aleatorios de n bits

Código: [Seleccionar]
import java.math.BigInteger;
import java.util.Random;

public class Prueba {
    public static void main(String [] arg)   {
        BigInteger resultado;
        Random numAleatorio = new Random();// creamos un objeto de la clase Random que se usara en el constructor de BigInteger(numBits, ObjetoRamdom)
        System.out.println("________________________________________");
        System.out.println("Lista de numeros aleatorios con 6 bits");
        System.out.println("________________________________________");
        for(int i=0;i<10;i++){
            resultado = new BigInteger(6, numAleatorio);//Crea un numero aleatorio usando 6 bits, valor maximo= 2^6=64
            System.out.println(resultado+" |||||||| "+resultado.toString(2));
        }
        System.out.println("________________________________________");
        System.out.println("Lista de numeros aleatorios con 256 bits");
        System.out.println("________________________________________");
        for(int i=0;i<10;i++){
            resultado = new BigInteger(256, numAleatorio);//Crea un numero aleatorio usando 256 bits, valor maximo= 2^256=Un monton XDD
            System.out.println(resultado+" |||||||| "+resultado.toString(2));
        }
    }
}

El ejemplo te imprime en decimal y en binario, por si quieres contar que realmente son 256 1's y 0's XDDDD

Y nada, tras este interruptus, creo que deberías seguir con el curso, vas bastante bien y aun te queda mucho que aprender.
« Última modificación: 08 de Agosto 2014, 22:21 por dongo »

Jorge lopez

  • Sniper
  • Intermedio
  • ***
  • APR2.COM
  • Mensajes: 248
  • @SniperOfElite
    • Ver Perfil
Re:Ejercicio! entrega CU00672B
« Respuesta #10 en: 09 de Agosto 2014, 00:25 »
Copiado!
while(estesVivo)
{
  aprende();
  ayuda();
  enseña();
}
if(mueres){teRecordaran();}

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".