Categoría: Retos JAVA

  • R7 [Solución] – Guerra por el Sistema Solar: Tierra, Marte y el Cinturón” (The Expanse)

    1) Nave.java

    
    
    
    
    
    /**
     * Representa una nave espacial dentro del universo de The Expanse.
     * 
     * Conceptos que se trabajan aquí:
     * - Encapsulamiento (atributos privados + getters/setters)
     * - Constructor completo
     * - toString() para imprimir bonito el objeto
     */
    public class Nave {
    
        // -------------------------
        // Atributos (siempre privados)
        // -------------------------
        private String nombre;
        private String faccion; // "Tierra", "Marte", "Cinturon"
        private int misiles;
        private boolean necesitaReparacion;
    
        // -------------------------
        // Constructores
        // -------------------------
    
        /**
         * Constructor completo exigido por el enunciado.
         */
        public Nave(String nombre, String faccion, int misiles, boolean necesitaReparacion) {
            this.nombre = nombre;
            this.faccion = faccion;
            this.misiles = misiles;
            this.necesitaReparacion = necesitaReparacion;
        }
    
        /**
         * Constructor opcional de conveniencia (por si quieres crear naves “rápido”).
         * Por ejemplo: misiles = 0 y no necesita reparación por defecto.
         */
        public Nave(String nombre, String faccion) {
            this(nombre, faccion, 0, false);
        }
    
        // -------------------------
        // Getters y Setters
        // -------------------------
        public String getNombre() {
            return nombre;
        }
    
        public void setNombre(String nombre) {
            this.nombre = nombre;
        }
    
        public String getFaccion() {
            return faccion;
        }
    
        public void setFaccion(String faccion) {
            this.faccion = faccion;
        }
    
        public int getMisiles() {
            return misiles;
        }
    
        public void setMisiles(int misiles) {
            this.misiles = misiles;
        }
    
        public boolean isNecesitaReparacion() {
            return necesitaReparacion;
        }
    
        public void setNecesitaReparacion(boolean necesitaReparacion) {
            this.necesitaReparacion = necesitaReparacion;
        }
    
        // -------------------------
        // toString() (muy útil para listar)
        // -------------------------
        @Override
        public String toString() {
            return "Nave{" +
                    "nombre='" + nombre + '\'' +
                    ", faccion='" + faccion + '\'' +
                    ", misiles=" + misiles +
                    ", necesitaReparacion=" + (necesitaReparacion ? "Sí" : "No") +
                    '}';
        }
    }
    

    2) Flota.java

    
    
    
    
    
    import java.util.ArrayList;
    import java.util.Scanner;
    
    /**
     * Flota = conjunto de naves.
     *
     * Conceptos que se trabajan:
     * - ArrayList con objetos (ArrayList<Nave>)
     * - Métodos para recorrer y filtrar
     * - Métodos con Scanner para crear objetos desde teclado
     */
    public class Flota {
    
        // Lista privada: nadie fuera debería tocarla directamente
        private ArrayList<Nave> naves;
    
        // -------------------------
        // Constructor
        // -------------------------
        public Flota() {
            // Inicializamos la lista vacía (obligatorio)
            this.naves = new ArrayList<>();
        }
    
        // -------------------------
        // Agregar nave ya creada
        // -------------------------
        public void agregarNave(Nave nave) {
            if (nave == null) {
                System.out.println("No se puede añadir una nave nula.");
                return;
            }
            naves.add(nave);
            System.out.println("✅ Nave añadida a la flota: " + nave.getNombre());
        }
    
        // -------------------------
        // Crear nave por teclado
        // -------------------------
        public void crearNaveDesdeTeclado(Scanner sc) {
            System.out.println("=== CREAR NUEVA NAVE ===");
    
            // Nombre
            System.out.print("Nombre de la nave: ");
            String nombre = sc.nextLine().trim();
    
            // Facción (validada)
            String faccion = leerFaccionValida(sc);
    
            // Misiles (entero >= 0)
            int misiles = leerEnteroNoNegativo(sc, "Número de misiles: ");
    
            // Reparación (S/N)
            boolean necesitaReparacion = leerBooleanSN(sc, "¿Necesita reparación? (S/N): ");
    
            // Creamos el objeto Nave con los datos recogidos
            Nave nave = new Nave(nombre, faccion, misiles, necesitaReparacion);
    
            // La añadimos al ArrayList
            naves.add(nave);
    
            System.out.println("✅ Nave creada y añadida: " + nave);
        }
    
        // -------------------------
        // Número de naves
        // -------------------------
        public int getNumeroNaves() {
            return naves.size();
        }
    
        // -------------------------
        // Listar todas
        // -------------------------
        public void listarTodas() {
            System.out.println("=== LISTADO COMPLETO DE NAVES ===");
    
            if (naves.isEmpty()) {
                System.out.println("La flota está vacía.");
                return;
            }
    
            for (Nave n : naves) {
                System.out.println(n); // llama a toString()
            }
        }
    
        // -------------------------
        // Listar naves para reparar
        // -------------------------
        public void listarNavesParaReparar() {
            System.out.println("=== NAVES QUE NECESITAN REPARACIÓN ===");
    
            boolean hay = false;
    
            for (Nave n : naves) {
                if (n.isNecesitaReparacion()) {
                    System.out.println(n);
                    hay = true;
                }
            }
    
            if (!hay) {
                System.out.println("No hay naves marcadas para reparación.");
            }
        }
    
        // -------------------------
        // Total de misiles
        // -------------------------
        public int getTotalMisiles() {
            int total = 0;
            for (Nave n : naves) {
                total += n.getMisiles();
            }
            return total;
        }
    
        // -------------------------
        // Listar por facción
        // -------------------------
        public void listarPorFaccion(String faccion) {
            System.out.println("=== NAVES DE LA FACCIÓN: " + faccion + " ===");
    
            boolean hay = false;
    
            for (Nave n : naves) {
                // equalsIgnoreCase = compara ignorando mayúsculas/minúsculas
                if (n.getFaccion().equalsIgnoreCase(faccion)) {
                    System.out.println(n);
                    hay = true;
                }
            }
    
            if (!hay) {
                System.out.println("No se encontraron naves de esa facción.");
            }
        }
    
        // -------------------------
        // Contar por facción
        // -------------------------
        public int contarPorFaccion(String faccion) {
            int contador = 0;
    
            for (Nave n : naves) {
                if (n.getFaccion().equalsIgnoreCase(faccion)) {
                    contador++;
                }
            }
    
            return contador;
        }
    
        // ==========================================================
        // Métodos auxiliares (para que el código quede limpio y robusto)
        // ==========================================================
    
        /**
         * Pide al usuario una facción válida: Tierra / Marte / Cinturon.
         */
        private String leerFaccionValida(Scanner sc) {
            while (true) {
                System.out.print("Facción (Tierra/Marte/Cinturon): ");
                String faccion = sc.nextLine().trim();
    
                if (esFaccionValida(faccion)) {
                    // Normalizamos para que quede bonito y consistente
                    return normalizarFaccion(faccion);
                }
    
                System.out.println("❌ Facción no válida. Usa: Tierra, Marte o Cinturon.");
            }
        }
    
        private boolean esFaccionValida(String faccion) {
            String f = faccion.trim().toLowerCase();
            return f.equals("tierra") || f.equals("marte") || f.equals("cinturon");
        }
    
        private String normalizarFaccion(String faccion) {
            String f = faccion.trim().toLowerCase();
            if (f.equals("tierra")) return "Tierra";
            if (f.equals("marte")) return "Marte";
            return "Cinturon";
        }
    
        /**
         * Lee un entero >= 0, repitiendo hasta que sea válido.
         */
        private int leerEnteroNoNegativo(Scanner sc, String mensaje) {
            while (true) {
                System.out.print(mensaje);
                String linea = sc.nextLine().trim();
    
                try {
                    int valor = Integer.parseInt(linea);
                    if (valor < 0) {
                        System.out.println("❌ No puede ser negativo.");
                    } else {
                        return valor;
                    }
                } catch (NumberFormatException e) {
                    System.out.println("❌ Introduce un número entero válido.");
                }
            }
        }
    
        /**
         * Lee una respuesta tipo S/N y la convierte a boolean.
         * S -> true, N -> false
         */
        private boolean leerBooleanSN(Scanner sc, String mensaje) {
            while (true) {
                System.out.print(mensaje);
                String resp = sc.nextLine().trim().toLowerCase();
    
                if (resp.equals("s") || resp.equals("si") || resp.equals("sí")) return true;
                if (resp.equals("n") || resp.equals("no")) return false;
    
                System.out.println("❌ Respuesta no válida. Escribe S o N.");
            }
        }
    }
    

    3) ControlFlota.java (main + menú)

    
    
    
    
    
    import java.util.Scanner;
    
    /**
     * Controlador principal.
     *
     * Conceptos que se trabajan:
     * - Menú por consola repetitivo (do-while)
     * - switch para ejecutar opciones
     * - Reutilización de Scanner y validación de enteros
     */
    public class ControlFlota {
    
        public static void main(String[] args) {
    
            Scanner sc = new Scanner(System.in);
            Flota flota = new Flota();
    
            // Naves iniciales opcionales (ambiente The Expanse)
            flota.agregarNave(new Nave("Rocinante", "Cinturon", 24, false));
            flota.agregarNave(new Nave("Donnager", "Marte", 60, true));
            flota.agregarNave(new Nave("Agatha King", "Tierra", 40, true));
    
            int opcion;
    
            do {
                mostrarMenu();
                opcion = leerEnteroSeguro(sc);
    
                switch (opcion) {
    
                    case 1:
                        // Crear nave desde teclado
                        flota.crearNaveDesdeTeclado(sc);
                        break;
    
                    case 2:
                        // Crear nave desde el main (valores fijos)
                        Nave n = new Nave("Nauvoo", "Cinturon", 80, false);
                        flota.agregarNave(n);
                        System.out.println("Nave creada desde main y añadida: " + n);
                        break;
    
                    case 3:
                        flota.listarTodas();
                        break;
    
                    case 4:
                        flota.listarNavesParaReparar();
                        break;
    
                    case 5:
                        System.out.println("Número total de naves: " + flota.getNumeroNaves());
                        break;
    
                    case 6:
                        System.out.println("Misiles totales en la flota: " + flota.getTotalMisiles());
                        break;
    
                    case 7:
                        System.out.print("Introduce la facción (Tierra/Marte/Cinturon): ");
                        String fac = sc.nextLine().trim();
                        flota.listarPorFaccion(fac);
                        break;
    
                    case 8:
                        System.out.print("Introduce la facción (Tierra/Marte/Cinturon): ");
                        String fac2 = sc.nextLine().trim();
                        int num = flota.contarPorFaccion(fac2);
                        System.out.println("Número de naves de la facción " + fac2 + ": " + num);
                        break;
    
                    case 0:
                        System.out.println("Saliendo del sistema de control de flota...");
                        break;
    
                    default:
                        System.out.println("Opción no válida.");
                }
    
                System.out.println(); // línea en blanco para separar “vueltas” del menú
    
            } while (opcion != 0);
    
            sc.close();
        }
    
        // -------------------------
        // Menú
        // -------------------------
        private static void mostrarMenu() {
            System.out.println("=== CONTROL DE FLOTA - GUERRA DEL SISTEMA SOLAR ===");
            System.out.println("1. Añadir nave (datos por teclado)");
            System.out.println("2. Añadir nave (creada en el main)");
            System.out.println("3. Listar todas las naves");
            System.out.println("4. Listar naves que necesitan reparación");
            System.out.println("5. Mostrar número total de naves");
            System.out.println("6. Mostrar número total de misiles");
            System.out.println("7. Listar naves por facción");
            System.out.println("8. Contar naves por facción");
            System.out.println("0. Salir");
            System.out.print("Elige una opción: ");
        }
    
        /**
         * Lee un entero de forma segura usando nextLine() + parseInt.
         * Ventaja: evita problemas típicos de Scanner con nextInt() y saltos de línea.
         */
        private static int leerEnteroSeguro(Scanner sc) {
            while (true) {
                try {
                    return Integer.parseInt(sc.nextLine().trim());
                } catch (NumberFormatException e) {
                    System.out.print("Introduce un número válido: ");
                }
            }
        }
    }
    

  • R3.1 – Programación-bucles

    R3.1 – Programación-bucles

    Ejercicio 1

    Contando del 1 al 10

    Crea un programa en Java que muestre por pantalla los números del 1 al 10 utilizando un bucle for.

    Requisitos:

    1. El programa debe tener una clase llamada Contador.
    2. Dentro del método main, utiliza un bucle for para recorrer los números del 1 al 10.
    3. En cada iteración, imprime el número actual en una nueva línea.

    Salida esperada:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    

    Ejercicio 2

    Cuenta atrás de 100 a 0 en pasos de 10

    Crea un programa en Java que haga una cuenta atrás desde 100 hasta 0, restando 10 en cada paso.

    Cuando llegue a 0, debe mostrar el mensaje «Máquina hackeada».

    Requisitos:

    1. El programa debe tener una clase llamada CuentaAtras10.
    2. Dentro del método main, usa un bucle for que empiece en 100 y vaya disminuyendo de 10 en 10 hasta llegar a 0.
    3. En cada iteración imprime el número actual.
    4. Al finalizar, muestra el texto Máquina hackeada.

    Salida esperada:

    100
    90
    80
    70
    60
    50
    40
    30
    20
    10
    0
    Máquina hackeada
    
    

    Ejercicio 3

    Realiza un algoritmo que simule una caja registradora de un supermercado, donde va pidiendo cantidades y las va sumando, cada vez que pongamos una cantidad por la terminal saldra la suma acumulada del total.

    El programa dejara de pedir las cantidades de compra cuando insertemos un 0.

    En ese momento mostrara el total de la compra y nos pedira que le indiquemos con cuanto dinero nos pagan e indicara el cambio que debemos devolver.

    Ejemplo de ejecución:

    Introduce la cantidad de la compra (0 para finalizar): 25.50
    Suma acumulada: 25.50
    Introduce la cantidad de la compra (0 para finalizar): 40.00
    Suma acumulada: 65.50
    Introduce la cantidad de la compra (0 para finalizar): 15.75
    Suma acumulada: 81.25
    Introduce la cantidad de la compra (0 para finalizar): 0
    Total a pagar: 81.25
    Con cuánto dinero te pagan? 100.00
    Cambio a devolver: 18.75
    

    Ejercicio 4

    Desarrollar un programa en Java que genere un dibujo usando únicamente el carácter asterisco (*). Este ejercicio te ayudará a entender mejor el control de bucles y el diseño de patrones en la consola.

    Descripción:

    Tu tarea es crear un programa que dibuje una pirámide de asteriscos. La altura de la pirámide será determinada por el usuario al inicio del programa.

    Requisitos:

    1. El programa debe pedir al usuario que introduzca un número entero positivo, el cual representará la altura de la pirámide.
    2. Utiliza bucles for o while para generar el patrón.
    3. La pirámide debe estar alineada a la izquierda, sin utilizar espacios para centrar las líneas.

    Ejemplo de salida:

    Si el usuario ingresa 5, el programa deberá mostrar el siguiente patrón:

    *
    **
    ***
    ****
    *****
    

    Ejercicio 5

    Crea un programa en Java que muestre el siguiente patrón usando dos bucles for anidados:

    Salida esperada:

    54321
    4321
    321
    21
    1
    
    

    Requisitos:

    1. Crea una clase llamada PatronDel5al1.
    2. Dentro del método main, utiliza un primer bucle for para controlar las filas, que empiece en 5 y termine en 1.
    3. Dentro de ese bucle, usa otro for que empiece en el valor de la fila y baje hasta 1.
    4. Después del bucle interno, imprime un salto de línea (System.out.println()).

  • R3.2 Programación-Bucles

    R3.2 Programación-Bucles

    Walter White y Jesse Pinkman han cocinado 1000 pastillas de «mentaanfetamienta» en su caravana.

    Cada pastilla tiene una calidad aleatoria entre 0 y 100.

    El “señor del pollo” (Gus Fring) solo acepta aquellas con calidad mayor o igual que 90.

    RETO 1: “El recuento del lote”

    Calcular cuántas pastillas tienen una calidad superior a 90.

    Pistas:

    • Usa Random para generar números del 0 al 100.
    • Usa un for para simular las 1000 pastillas.
    • Usa un contador para las “buenas”.

    Ejemplo de salida:

    Pastillas totales: 1000
    De calidad superior: 128
    

    RETO 2: “Hasta lograr la receta perfecta”

    Walter repite la cocción hasta que consiga una pastilla con calidad 100.

    Pistas:

    • Genera números aleatorios entre 0 y 100.
    • Detén el bucle cuando salga 100.
    • Muestra cuántos intentos necesitó.

    Ejemplo:

    ¡Perfecta! Calidad 100 obtenida tras 57 intentos.
    

    RETO 3: “La producción nocturna”

    Walter y Jesse producen pastillas hasta llegar a 1000 unidades buenas (≥90).

    Muestra cuántas totales han hecho (incluyendo las malas).

    Ejemplo:

    Para conseguir 1000 pastillas buenas, produjeron un total de 8732.
    

    RETO 4: “El análisis por lotes”

    Dividir la producción en 10 lotes de 100 pastillas y mostrar cuántas buenas hay en cada lote.

    Salida esperada:

    Lote 1 → 13 pastillas buenas
    Lote 2 → 8 pastillas buenas
    ...
    Lote 10 → 11 pastillas buenas
    
    

    RETO 5: “Promedio de calidad”

    Calcular el promedio total de calidad de las 1000 pastillas.

    Salida:

    Promedio de calidad general: 72.38
    
    

    RETO 6 (extra): “La inspección de Gus Fring”

    Genera pastillas hasta tener 500 buenas, pero cada vez que salgan 50 malas seguidas, muestra:

    🔥 Gus Fring sospecha del laboratorio...
    
    

    Ayuda:

    Chuleta Java – Math, Random y String


    🔹 Clase Math (no necesita crear objeto)

    Usa directamente: Math.metodo()

    MétodoDescripciónEjemploResultado
    Math.abs(x)Valor absolutoMath.abs(-5)5
    Math.max(a,b)Mayor de dos valoresMath.max(8,3)8
    Math.min(a,b)Menor de dos valoresMath.min(8,3)3
    Math.pow(a,b)Potencia (a^b)Math.pow(2,3)8.0
    Math.sqrt(x)Raíz cuadradaMath.sqrt(9)3.0
    Math.round(x)Redondea al entero más cercanoMath.round(3.6)4
    Math.floor(x)Redondea hacia abajoMath.floor(3.9)3.0
    Math.ceil(x)Redondea hacia arribaMath.ceil(3.1)4.0
    Math.random()Número aleatorio entre 0 y 1Math.random()0.0–0.999...
    Math.PIConstante πMath.PI3.14159…
    Math.EConstante eMath.E2.71828…

    Ejemplo práctico:

    double area = Math.PI * Math.pow(5, 2);
    
    

    🎲 Clase Random

    Primero importa y crea el objeto:

    import java.util.Random;
    Random r = new Random();
    
    
    MétodoDescripciónEjemploResultado
    r.nextInt(n)Entero entre 0 y n-1r.nextInt(10)0–9
    r.nextInt(max - min + 1) + minEntero entre min y maxr.nextInt(21) + 8080–100
    r.nextDouble()Decimal entre 0.0 y 1.0r.nextDouble()0.0–0.999...
    r.nextBoolean()Verdadero o falsor.nextBoolean()true / false

    Ejemplo:

    int dado = r.nextInt(6) + 1; // 1 a 6
    
    

    🧵 Clase String

    Recuerda: los String son objetos, y sus métodos se invocan sobre la variable:

    texto.metodo()

    MétodoDescripciónEjemploResultado
    length()Longitud del texto"Hola".length()4
    charAt(i)Carácter en posición i"Hola".charAt(1)'o'
    toUpperCase()Convierte a mayúsculas"hola".toUpperCase()"HOLA"
    toLowerCase()Convierte a minúsculas"HOLA".toLowerCase()"hola"
    equals(cadena)Compara textos (sensible a mayúsculas)"Hola".equals("hola")false
    equalsIgnoreCase(cadena)Compara ignorando mayúsculas/minúsculas"Hola".equalsIgnoreCase("hola")true
    substring(inicio, fin)Extrae parte del texto"Java".substring(1,3)"av"
    indexOf(cadena)Posición de una subcadena"Hola".indexOf("la")2
    contains(cadena)¿Contiene la subcadena?"Hola".contains("Ho")true
    startsWith(prefijo)¿Empieza por…?"Hola".startsWith("Ho")true
    endsWith(sufijo)¿Termina en…?"Hola".endsWith("la")true
    trim()Elimina espacios al inicio y final" Hola ".trim()"Hola"
    replace(a, b)Sustituye texto"Hola".replace("a","e")"Hole"

    Ejemplo combinado:

    String nombre = " Antonio ";
    System.out.println(nombre.trim().toUpperCase());
    
    

    ⚗️ Extra para curiosos

    Rango aleatorio con Math (sin Random):

    int n = (int)(Math.random() * 21) + 80; // 80–100
    
    
  • R3.3 – Arrays – Bienvenido al mundo de Mr. Robot

    R3.3 – Arrays – Bienvenido al mundo de Mr. Robot

    Evil Corp —el gigante que controla todo lo que consumes, lo que piensas y hasta lo que olvidas— cree tenerlo todo bajo control.

    Pero no contaba contigo.

    En un sótano lleno de cables, pantallas parpadeantes y tazas de café frías, un grupo de hackers conocidos como Atriumsociety prepara su próximo golpe digital. Su misión: devolver el poder a la gente, línea de código a línea de código.

    Tu papel comienza aquí.

    Eres parte del equipo. Hoy no vienes a “hacer ejercicios”, vienes a infiltrarte en el sistema, Cada array que declares es una base de datos secreta, cada bucle un intento de intrusión, cada condicional una decisión que puede cambiarlo todo.

    Prepárate: el prompt está parpadeando.

    Atriumsociety te necesita.

    1. “Elliot vs Evil Corp”

    Enunciado:

    Elliot ha interceptado una lista con los balances de Evil Corp.

    Con el siguiente array:

    int[] balances = {12000, -50, 5000, 15000, 0, -300, 800, 22000, 9999, 100};
    
    

    Muestra:

    • Cuántas cuentas tienen saldo negativo.
    • Cuántas tienen saldo superior a 10 000 $.
    • El saldo medio.

    2. “Backdoor Scanner”

    Enunciado:

    Darlene analiza si los servidores de Evil Corp están vulnerables.

    Usa el siguiente array:

    boolean[] vulnerables = {false, true, false, false, true, false, true, false};
    
    

    Muestra:

    • Cuántos servidores son vulnerables (true).
    • En qué posiciones están.

    3. “Password Audit”

    Enunciado:

    Elliot encuentra las siguientes contraseñas antiguas de Evil Corp:

    String[] passwords = {"admin123", "e@mpl3", "supersecure99", "pass", "root@2020"};
    
    

    Indica:

    • Cuántas contienen el carácter @.
    • Cuántas tienen más de 8 caracteres.
    • Cuántas terminan en un número.
    • Cuál es la más larga.

    4. “Hack the Gibson”

    Enunciado:

    Simula los niveles de éxito de los ataques de Elliot con el siguiente array:

    int[] intentos = {82, 13, 45, 79, 90, 5, 33, 72, 18, 65, 40, 100, 29, 10, 67, 55, 88, 60, 14, 3};
    
    

    Muestra:

    • El valor máximo y el mínimo.
    • Cuántos intentos fueron “exitosos” (más de 70).
    • Si todos son menores de 30, muestra “Mr Robot sospecha que estás desconectado”.

    5. “Logs del Servidor”

    Enunciado:

    Angela revisa los registros de acceso de un servidor:

    String[] logs = {"OK", "ERROR", "OK", "OK", "ERROR", "OK", "ERROR", "ERROR", "OK", "OK"};
    
    

    Cuenta:

    • Cuántos accesos fueron "OK".
    • Cuántos "ERROR".
    • Si hay más errores que accesos correctos, muestra “Servidor en peligro”.

    6. “Temperaturas del Servidor”

    Enunciado:

    Durante un ataque, Elliot monitoriza las temperaturas del servidor:

    int[] temperaturas = {45, 49, 52, 57, 60, 59, 55, 48, 46, 50};
    
    

    Calcula:

    • La temperatura media.
    • Cuántas mediciones superan los 55 °C.
    • Si todas las temperaturas están por debajo de 60 °C, muestra “Sistema estable”; si alguna es 60 o más, muestra “¡Sobrecalentamiento detectado!”.

    7. “DDoS Simulator”

    Enunciado:

    Durante un ataque DDoS, se registran los siguientes tiempos de respuesta (en ms):

    int[] tiempos = {200, 540, 720, 150, 950, 330, 480, 510, 870, 610};
    
    

    Muestra:

    • La media, el máximo y el mínimo.
    • Si más del 60 % supera los 500 ms, muestra “Servidor saturado”.
    • Si menos del 10 % supera los 200 ms, muestra “Ataque fallido”.
  • R6 – Clase PsicoHistoriador (Fundación)

    R6 – Clase PsicoHistoriador (Fundación)


    RETO 1: Clase PsicoHistoriador (Fundación)

    Contexto

    Formas parte del Proyecto Seldon, dentro del universo de Fundación. Vas a modelar a un psico-historiador, un especialista capaz de analizar el futuro del Imperio mediante matemáticas y sociología.

    Objetivo

    Crear una única clase en Java que represente a un psico-historiador. Este reto sirve para practicar atributos privados, constructores, getters, setters y métodos simples. No se permite utilizar listas, arrays, ni otras clases.

    Instrucciones

    1. Nombre de la clase
    La clase debe llamarse PsicoHistoriador.

    2. Atributos privados obligatorios

    Debes declarar:

    • String nombre;
    • int nivelMatematico; (0 a 100)
    • boolean lealtadFundacion;
    • int prediccionesRealizadas;

    3. Constructor
    El constructor debe recibir String nombre e int nivelMatematico.

    El resto se inicializa así:
    lealtadFundacion = true;
    prediccionesRealizadas = 0;

    4. Getters y setters
    Implementa métodos getter y setter para los atributos necesarios, al menos los siguientes:

    • getNombre()
    • getNivelMatematico() y setNivelMatematico(int n)
    • isLealtadFundacion() y setLealtadFundacion(boolean v)
    • getPrediccionesRealizadas()

    5. Método realizarPrediccion()
    Cada vez que se llame:

    • Aumenta en 1 prediccionesRealizadas.
    • Calcula una probabilidad usando nivelMatematico.
    • Devuelve un texto como:
      “El psico-historiador NOMBRE calcula una probabilidad de colapso del Imperio del X%.”

    6. Método evaluarRiesgoImperial()
    Debe devolver un mensaje según el valor de nivelMatematico:

    • Mayor de 80 → “Riesgo alto: el Imperio se derrumbará pronto.”
    • Entre 50 y 80 → “Riesgo moderado: el Plan Seldon sigue estable.”
    • Menor de 50 → “Riesgo bajo: estabilidad aparente, pero no te fíes.”

    7. Método main
    La misma clase debe contener un main que:

    • Cree un objeto PsicoHistoriador.
    • Llame a realizarPrediccion() varias veces e imprima el resultado.
    • Llame a evaluarRiesgoImperial() y muestre el mensaje final.

    RETO 2: Clase NaveEstelarFundacion (Constructores y Aleatoriedad)

    La Fundación mantiene una flota de naves estelares para explorar la galaxia. En este ejercicio practicarás atributos privados, varios constructores y el uso de un método auxiliar que genera valores aleatorios.

    Objetivo

    Crear la clase NaveEstelarFundacion implementando tres constructores, getters, setters, un método aleatorio proporcionado y un pequeño main de prueba. No se permite el uso de listas, arrays ni otras clases.

    Instrucciones

    1. Nombre de la clase
    La clase debe llamarse NaveEstelarFundacion.

    2. Atributos privados

    • String nombre;
    • String modelo;
    • int escudo;
    • int velocidadMaxima;
    • int misionesCompletadas;

    3. Método auxiliar ya proporcionado (NO modificar)

    private int generarAleatorio(int min, int max) { return (int)(Math.random() * (max - min + 1)) + min; } 

    4. Constructores obligatorios

    a) Constructor sin parámetros
    Debe asignar valores por defecto, por ejemplo:

    • nombre = "Anonima"
    • modelo = "Basico"
    • escudo = 50
    • velocidadMaxima = 2000
    • misionesCompletadas = 0

    b) Constructor con parámetros (nombre y modelo)
    Debe asignar los valores recibidos y generar:

    • escudo aleatorio entre 40 y 90
    • velocidadMaxima aleatoria entre 1500 y 4000
    • misionesCompletadas = 0

    c) Constructor con todos los atributos
    Debe recibir y asignar todos los campos: nombre, modelo, escudo, velocidadMaxima y misionesCompletadas.

    5. Getters y setters
    Debes implementar getters y setters para todos los atributos.

    6. Método desplegar()
    Devuelve un texto con los datos de la nave:

    "La nave NOMBRE, modelo MODELO, se despliega con escudo ESCUDO% y velocidad máxima VELOCIDAD km/s." 

    7. Método registrarMision()
    Aumenta en 1 el contador misionesCompletadas.

    8. Main de prueba
    Debe:

    Aumentar misiones con registrarMision() y mostrar el total.

    Crear una nave con el constructor por defecto.

    Crear otra con el constructor de dos parámetros.

    Crear una con el constructor completo.

    Llamar a desplegar() en cada una.

  • R7 – Guerra por el Sistema Solar: Tierra, Marte y el Cinturón” (The Expanse)

    R7 – Guerra por el Sistema Solar: Tierra, Marte y el Cinturón” (The Expanse)

    En el universo de The Expanse, la tensión entre la Tierra, Marte y el Cinturón ha acabado en guerra abierta. Tú vas a programar el sistema de gestión de una flota de naves que participan en esa guerra.

    El objetivo del ejercicio es trabajar:

    • Clases y objetos.
    • Uso de ArrayList con objetos.
    • Encapsulamiento y métodos.
    • Uso de Scanner para leer datos.
    • Un controlador con menú en consola.

    Deberás crear al menos tres clases:

    • Nave
    • Flota
    • Una clase con main (por ejemplo ControlFlota)

    1. Clase Nave

    Crea una clase Nave que represente una nave espacial.

    Atributos mínimos:

    • String nombre
    • String faccion
      (valores recomendados: "Tierra", "Marte", "Cinturon")
    • int misiles → número de misiles que tiene esa nave.
    • boolean necesitaReparacion → indica si la nave necesita pasar por dique seco.

    Requisitos:

    1. Al menos un constructor con todos los parámetros:
      • Nave(String nombre, String faccion, int misiles, boolean necesitaReparacion)
    2. Puedes añadir más constructores si quieres (por ejemplo, uno con menos parámetros).
    3. Métodos get y set para los atributos que consideres necesarios.
    4. Método toString() para mostrar la información de la nave de forma legible.

    2. Clase Flota

    La clase Flota representa un conjunto de naves en guerra.

    Atributo:

    • Un atributo privado:
      • ArrayList<Nave> naves;

    Requisitos de la clase Flota:

    1. Constructor sin parámetros
      Inicializa la lista:
      • Crea un ArrayList<Nave> vacío.
    2. Método para añadir una nave ya creada
      • void agregarNave(Nave nave)
        Añade la nave recibida como parámetro al ArrayList.
    3. Método para crear una nave usando Scanner y añadirla a la flota
      • void crearNaveDesdeTeclado(Scanner sc)
        Este método debe:
      • Pedir por teclado:
        • Nombre de la nave.
        • Facción (Tierra, Marte o Cinturon).
        • Número de misiles.
        • Si necesita reparación (por ejemplo, S/N).
      • Crear un objeto Nave con esos datos.
      • Añadir la nave creada a la lista de la flota.
    4. Método que devuelve el número de naves
      • int getNumeroNaves()
        Devuelve cuántas naves hay en la flota (tamaño del ArrayList).
    5. Método para listar todas las naves
      • void listarTodas()
        Muestra por pantalla todas las naves de la flota.
    6. Método para listar solo las naves que necesitan reparación
      • void listarNavesParaReparar()
        Recorre la lista y muestra solo las naves cuyo atributo necesitaReparacion sea true.
    7. Método para calcular el número total de misiles de la flota
      • int getTotalMisiles()
        Suma el número de misiles de todas las naves y devuelve el total.
    8. Método para listar naves por facción
      • void listarPorFaccion(String faccion)
        Muestra solo las naves cuya facción coincida con la indicada (por ejemplo "Tierra").
    9. Método para contar naves por facción
      • int contarPorFaccion(String faccion)
        Devuelve cuántas naves pertenecen a la facción indicada.

    Puedes añadir métodos auxiliares si lo necesitas (por ejemplo para validaciones).


    3. Clase ControlFlota (o similar) con main

    Crea una clase que contenga el método main y actúe como controlador.

    Requisitos:

    1. Crear un objeto Scanner y un objeto Flota.
    2. Opcionalmente, crear algunas naves iniciales por código (por ejemplo naves típicas de The Expanse) y añadirlas a la flota con agregarNave.
    3. Implementar un menú por consola que se repita hasta que el usuario elija salir (puedes usar while o do-while).

    El menú deberá tener, como mínimo, estas opciones:

    1. Añadir nave pidiendo datos por teclado
      • Llamar a crearNaveDesdeTeclado(sc).
    2. Añadir nave creada en el main
      • Crear un objeto Nave directamente en el main (con valores que tú pongas) y añadirlo a la flota con agregarNave.
    3. Listar todas las naves
      • Llamar a listarTodas().
    4. Listar naves que necesitan reparación
      • Llamar a listarNavesParaReparar().
    5. Mostrar número total de naves
      • Llamar a getNumeroNaves() y mostrar el resultado.
    6. Mostrar número total de misiles de la flota
      • Llamar a getTotalMisiles() y mostrar el resultado.
    7. Listar naves por facción
      • Pedir al usuario una facción (Tierra, Marte o Cinturon) y llamar a listarPorFaccion(faccion).
    8. Mostrar cuántas naves hay de una facción
      • Pedir al usuario una facción y llamar a contarPorFaccion(faccion).
      • Mostrar el resultado.
    9. Salir del programa.

    Cada opción debe ejecutarse según el número introducido por el usuario, y después de ejecutar la acción, el menú se volverá a mostrar hasta que el usuario elija la opción 0.


    4. Información extra The Expanse

    • La facción Tierra representa a la ONU y su flota clásica.
    • La facción Marte representa a la MCRN, con naves militares muy avanzadas.
    • La facción Cinturon representa a la OPA y a los belters, normalmente con naves reutilizadas o modificadas.

    Puedes usar nombres de naves inspirados en la serie (por ejemplo, “Rocinante”, “Donnager”, “Agatha King”, “Nauvoo”, etc.) o inventarte los tuyos, siempre dentro del contexto de la guerra entre Tierra, Marte y el Cinturón.


    Ejemplo Controlador MAIN

    Código del ControlFlota (main)

    import java.util.Scanner;
    
    public class ControlFlota {
    
        public static void main(String[] args) {
    
            Scanner sc = new Scanner(System.in);
            Flota flota = new Flota();
    
            // Naves iniciales opcionales (The Expanse vibes)
            flota.agregarNave(new Nave("Rocinante", "Cinturon", 24, false));
            flota.agregarNave(new Nave("Donnager", "Marte", 60, true));
            flota.agregarNave(new Nave("Agatha King", "Tierra", 40, true));
    
            int opcion;
    
            do {
                mostrarMenu();
                opcion = leerEnteroSeguro(sc);
    
                switch (opcion) {
    
                    case 1:
                        // Crear nave con Scanner
                        flota.crearNaveDesdeTeclado(sc);
                        break;
    
                    case 2:
                        // Crear nave desde el propio main
                        Nave n = new Nave("Nauvoo", "Cinturon", 80, false);
                        flota.agregarNave(n);
                        System.out.println("Nave creada desde main y añadida: " + n);
                        break;
    
                    case 3:
                        flota.listarTodas();
                        break;
    
                    case 4:
                        flota.listarNavesParaReparar();
                        break;
    
                    case 5:
                        System.out.println("Número total de naves: " + flota.getNumeroNaves());
                        break;
    
                    case 6:
                        System.out.println("Misiles totales en la flota: " + flota.getTotalMisiles());
                        break;
    
                    case 7:
                        System.out.print("Introduce la facción (Tierra/Marte/Cinturon): ");
                        String fac = sc.nextLine();
                        flota.listarPorFaccion(fac);
                        break;
    
                    case 8:
                        System.out.print("Introduce la facción (Tierra/Marte/Cinturon): ");
                        String fac2 = sc.nextLine();
                        int num = flota.contarPorFaccion(fac2);
                        System.out.println("Número de naves de la facción " + fac2 + ": " + num);
                        break;
    
                    case 0:
                        System.out.println("Saliendo del sistema de control de flota...");
                        break;
    
                    default:
                        System.out.println("Opción no válida.");
                }
    
                System.out.println();
    
            } while (opcion != 0);
    
            sc.close();
        }
    
        // -------------------------
        // Métodos auxiliares
        // -------------------------
    
        private static void mostrarMenu() {
            System.out.println("=== CONTROL DE FLOTA - GUERRA DEL SISTEMA SOLAR ===");
            System.out.println("1. Añadir nave (datos por teclado)");
            System.out.println("2. Añadir nave (creada en el main)");
            System.out.println("3. Listar todas las naves");
            System.out.println("4. Listar naves que necesitan reparación");
            System.out.println("5. Mostrar número total de naves");
            System.out.println("6. Mostrar número total de misiles");
            System.out.println("7. Listar naves por facción");
            System.out.println("8. Contar naves por facción");
            System.out.println("0. Salir");
            System.out.print("Elige una opción: ");
        }
    
        private static int leerEnteroSeguro(Scanner sc) {
            while (true) {
                try {
                    int valor = Integer.parseInt(sc.nextLine());
                    return valor;
                } catch (NumberFormatException e) {
                    System.out.print("Introduce un número válido: ");
                }
            }
        }
    }
    

  • R8 – El Escalafón Mágico de Hogwarts

    R8 – El Escalafón Mágico de Hogwarts

    El Ministerio de Magia ha implantado un nuevo sistema de clasificación de magos para evaluar su progreso, capacidades y responsabilidades dentro del mundo mágico.

    Tu misión será desarrollar, en Java, un pequeño sistema que represente este escalafón utilizando herencia entre clases, donde cada rango mágico añade nuevas habilidades y comportamientos.

    ⚠️ Importante

    Usar una enumeración (enum) para representar las Casas de Hogwarts.

    En este ejercicio NO se deben usar:

    • Métodos abstractos
    • Polimorfismo como concepto principal
    • Interfaces

    Diagrama de clases

    1 – Enumeración de Casas

    Crea una enumeración llamada Casa con las siguientes opciones:

    • GRYFFINDOR
    • SLYTHERIN
    • RAVENCLAW
    • HUFFLEPUFF

    Cada mago pertenecerá a una casa, y esta afectará a sus atributos iniciales.


    2 – Clase base Mago

    Crea la clase Mago, que será la base de todos los personajes mágicos.

    Atributos

    • nombre
    • nivel (1–100)
    • vida (0–100)
    • mana (0–100)
    • casa (tipo Casa)

    Comportamiento

    • entrenar()
      Aumenta el nivel y consume algo de vida y mana.
    • descansar()
      Recupera vida y mana.
    • ficha()
      Devuelve una cadena con los datos del mago.
    • lanzarHechizo(String hechizo)
      Método general que devuelve el daño causado (por defecto, bajo o 0).

    Al crear un mago, se aplicará un bonus inicial según su casa.


    3 – Rangos mágicos (herencia)

    Aprendiz (hereda de Mago)

    Representa a los alumnos más jóvenes de Hogwarts.

    Atributo extra

    • torpeza (probabilidad de fallo)

    Métodos

    • practicarBasico() → reduce torpeza

    Comportamiento

    • Puede lanzar hechizos básicos (Lumos, Alohomora)
    • Tiene posibilidad de fallar según su torpeza

    Hechicero (hereda de Aprendiz)

    Magos con formación avanzada.

    Atributo extra

    • controlVarita

    Métodos

    • estudiarEnBiblioteca() → mejora control y nivel

    Comportamiento

    • Acceso a hechizos más potentes (Expelliarmus, Stupefy)
    • Menos fallos y más daño

    Auror (hereda de Hechicero)

    Magos especializados en combate y seguridad mágica.

    Atributos extra

    • experienciaCombate
    • arrestos

    Métodos

    • patrullar() → mejora experiencia
    • arrestar(Aprendiz objetivo) → solo si el objetivo está débil

    Comportamiento

    • Hechizos más efectivos en combate
    • Puede usar hechizos defensivos

    Profesor (hereda de Hechicero)

    Magos con rol docente en Hogwarts.

    Atributos extra

    • asignatura
    • prestigio

    Métodos

    • enseñar(Aprendiz alumno) → mejora al alumno
    • evaluar() → aumenta prestigio

    Comportamiento

    • Hechizos más controlados
    • Menor consumo de mana

    4 – Programa principal

    Crea una clase Main que:

    • Cree al menos:
      • 2 Aprendices
      • 2 Hechiceros
      • 1 Auror
      • 1 Profesor
    • Muestre la ficha de cada personaje.
    • Ejecute varias acciones:
      • Lanzar hechizos
      • Entrenar / descansar
      • Enseñar, patrullar o arrestar según el rango

    Cada variable debe declararse con su tipo concreto
    (no usar listas genéricas de Mago).




    El conocimiento es poder… pero en Hogwarts, también lo es la herencia bien diseñada.

  • R3.1 [Solución] – Programación-bucles

    R3.1 [Solución] – Programación-bucles

    Ejercicio 1

    Contando del 1 al 10

    Crea un programa en Java que muestre por pantalla los números del 1 al 10 utilizando un bucle for.

    Requisitos:

    1. El programa debe tener una clase llamada Contador.
    2. Dentro del método main, utiliza un bucle for para recorrer los números del 1 al 10.
    3. En cada iteración, imprime el número actual en una nueva línea.

    Salida esperada:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    

    Idea clave

    Usamos un bucle for cuando conocemos de antemano cuántas veces queremos repetir algo.
    Aquí queremos mostrar los números del 1 al 10, ni más ni menos.

    Lógica

    • Inicializamos el contador en 1
    • Mientras sea menor o igual que 10
    • En cada vuelta lo incrementamos en 1

    Código solución

    
    
    
    
    
    public class Contador {
    
        public static void main(String[] args) {
    
            for (int i = 1; i <= 10; i++) {
                System.out.println(i);
            }
    
        }
    }
    

    🔍 Explicación línea a línea

    • int i = 1 → valor inicial
    • i <= 10 → condición para seguir iterando
    • i++ → incremento en cada vuelta
    • System.out.println(i) → muestra el valor actual


    Ejercicio 2

    Cuenta atrás de 100 a 0 en pasos de 10

    Crea un programa en Java que haga una cuenta atrás desde 100 hasta 0, restando 10 en cada paso.

    Cuando llegue a 0, debe mostrar el mensaje «Máquina hackeada».

    Requisitos:

    1. El programa debe tener una clase llamada CuentaAtras10.
    2. Dentro del método main, usa un bucle for que empiece en 100 y vaya disminuyendo de 10 en 10 hasta llegar a 0.
    3. En cada iteración imprime el número actual.
    4. Al finalizar, muestra el texto Máquina hackeada.

    Salida esperada:

    100
    90
    80
    70
    60
    50
    40
    30
    20
    10
    0
    Máquina hackeada
    
    

    Idea clave

    Un for también sirve para contar hacia atrás si modificamos correctamente el incremento (en este caso, decremento).

    Lógica

    • Empezamos en 100
    • Vamos restando 10 en cada iteración
    • Cuando termina el bucle, mostramos el mensaje final

    Código solución

    
    
    
    
    
    public class CuentaAtras10 {
    
        public static void main(String[] args) {
    
            for (int i = 100; i >= 0; i -= 10) {
                System.out.println(i);
            }
    
            System.out.println("Máquina hackeada");
        }
    }
    

    Detalles importantes

    • i -= 10 → resta 10 en cada vuelta
    • El mensaje no va dentro del bucle, para que se muestre solo una vez


    Ejercicio 3

    Realiza un algoritmo que simule una caja registradora de un supermercado, donde va pidiendo cantidades y las va sumando, cada vez que pongamos una cantidad por la terminal saldra la suma acumulada del total.

    El programa dejara de pedir las cantidades de compra cuando insertemos un 0.

    En ese momento mostrara el total de la compra y nos pedira que le indiquemos con cuanto dinero nos pagan e indicara el cambio que debemos devolver.

    Ejemplo de ejecución:

    Introduce la cantidad de la compra (0 para finalizar): 25.50
    Suma acumulada: 25.50
    Introduce la cantidad de la compra (0 para finalizar): 40.00
    Suma acumulada: 65.50
    Introduce la cantidad de la compra (0 para finalizar): 15.75
    Suma acumulada: 81.25
    Introduce la cantidad de la compra (0 para finalizar): 0
    Total a pagar: 81.25
    Con cuánto dinero te pagan? 100.00
    Cambio a devolver: 18.75
    

    Idea clave

    Aquí necesitamos:

    • Repetir hasta que el usuario introduzca 0
    • Ir sumando cantidades
    • Pedir un pago final y calcular el cambio

    Este es un caso perfecto para un bucle while.

    Lógica

    1. Pedimos cantidades hasta que llegue un 0
    2. Mostramos la suma acumulada
    3. Mostramos el total
    4. Pedimos el dinero entregado
    5. Calculamos el cambio

    Código solución

    
    
    
    
    
    import java.util.Scanner;
    
    public class CajaRegistradora {
    
        public static void main(String[] args) {
    
            Scanner sc = new Scanner(System.in);
            double total = 0;
            double cantidad;
    
            do {
                System.out.print("Introduce la cantidad de la compra (0 para finalizar): ");
                cantidad = sc.nextDouble();
    
                if (cantidad != 0) {
                    total += cantidad;
                    System.out.println("Suma acumulada: " + total);
                }
    
            } while (cantidad != 0); // Direfente es ( ! = )
    
            System.out.println("Total a pagar: " + total);
    
            System.out.print("Con cuánto dinero te pagan? ");
            double pago = sc.nextDouble();
    
            double cambio = pago - total;
            System.out.println("Cambio a devolver: " + cambio);
    
            sc.close();
        }
    }
    

    Conceptos trabajados

    • do-while → asegura al menos una ejecución
    • Acumulador (total)
    • Uso de double para cantidades con decimales
    • Entrada de datos con Scanner

    Ejercicio 4

    Desarrollar un programa en Java que genere un dibujo usando únicamente el carácter asterisco (*). Este ejercicio te ayudará a entender mejor el control de bucles y el diseño de patrones en la consola.

    Descripción:

    Tu tarea es crear un programa que dibuje una pirámide de asteriscos. La altura de la pirámide será determinada por el usuario al inicio del programa.

    Requisitos:

    1. El programa debe pedir al usuario que introduzca un número entero positivo, el cual representará la altura de la pirámide.
    2. Utiliza bucles for o while para generar el patrón.
    3. La pirámide debe estar alineada a la izquierda, sin utilizar espacios para centrar las líneas.

    Ejemplo de salida:

    Si el usuario ingresa 5, el programa deberá mostrar el siguiente patrón:

    *
    **
    ***
    ****
    *****
    

    Idea clave

    Cada línea imprime un número creciente de asteriscos.
    El número de líneas lo decide el usuario.

    Lógica

    • Un bucle controla las filas
    • Otro bucle imprime los * en cada fila

    Código solución

    
    
    
    
    
    import java.util.Scanner;
    
    public class Piramide {
    
        public static void main(String[] args) {
    
            Scanner sc = new Scanner(System.in);
    
            System.out.print("Introduce la altura de la pirámide: ");
            int altura = sc.nextInt();
    
            for (int i = 1; i <= altura; i++) {
                for (int j = 1; j <= i; j++) {
                    System.out.print("*");
                }
                System.out.println();
            }
    
            sc.close();
        }
    }
    

    Si i = 3, el bucle interno imprime:

    
    
    
    
    
    ***
    

    Cada fila tiene tantos asteriscos como el número de la fila.


    Ejercicio 5

    Crea un programa en Java que muestre el siguiente patrón usando dos bucles for anidados:

    Salida esperada:

    54321
    4321
    321
    21
    1
    
    

    Requisitos:

    1. Crea una clase llamada PatronDel5al1.
    2. Dentro del método main, utiliza un primer bucle for para controlar las filas, que empiece en 5 y termine en 1.
    3. Dentro de ese bucle, usa otro for que empiece en el valor de la fila y baje hasta 1.
    4. Después del bucle interno, imprime un salto de línea (System.out.println()).

    Idea clave

    Este ejercicio refuerza el concepto de bucles anidados descendentes.

    Lógica

    • El bucle externo controla las filas (de 5 a 1)
    • El bucle interno imprime los números desde la fila hasta 1

    Código solución

    
    
    
    
    
    public class PatronDel5al1 {
    
        public static void main(String[] args) {
    
            for (int i = 5; i >= 1; i--) {
                for (int j = i; j >= 1; j--) {
                    System.out.print(j);
                }
                System.out.println();
            }
    
        }
    }
    

    Qué ocurre aquí

    Y así hasta llegar a 1

    Primera fila: i = 5 → imprime 54321

    Segunda fila: i = 4 → imprime 4321

  • R3.2 [Solución] Programación-Bucles

    R3.2 [Solución] Programación-Bucles

    Walter White y Jesse Pinkman han cocinado 1000 pastillas de «mentaanfetamienta» en su caravana.

    Cada pastilla tiene una calidad aleatoria entre 0 y 100.

    El “señor del pollo” (Gus Fring) solo acepta aquellas con calidad mayor o igual que 90.

    Base común: generar calidad 0–100

    Usaremos:

    
    
    
    
    
    Random r = new Random(); int calidad = r.nextInt(101); // 0..100 (incluye 100)

    RETO 1: “El recuento del lote”

    Calcular cuántas pastillas tienen una calidad superior a 90.

    Pistas:

    • Usa Random para generar números del 0 al 100.
    • Usa un for para simular las 1000 pastillas.
    • Usa un contador para las “buenas”.

    Ejemplo de salida:

    Pastillas totales: 1000
    De calidad superior: 128

    Objetivo: de 1000 pastillas, contar cuántas tienen calidad > 90 (ojo: tu historia dice “≥90”, pero el reto 1 pide “superior a 90” → >90).

    Idea

    • Bucle for de 1 a 1000
    • Generar calidad
    • Si calidad > 90, incrementamos contador

    Código

    
    
    
    
    
    import java.util.Random;
    
    public class Reto1RecuentoLote {
        public static void main(String[] args) {
            Random r = new Random();
    
            int total = 1000;
            int buenas = 0;
    
            for (int i = 1; i <= total; i++) {
                int calidad = r.nextInt(101); // 0..100
    
                if (calidad > 90) {           // superior a 90
                    buenas++;
                }
            }
    
            System.out.println("Pastillas totales: " + total);
            System.out.println("De calidad superior: " + buenas);
        }
    }
    

    RETO 2: “Hasta lograr la receta perfecta”

    Walter repite la cocción hasta que consiga una pastilla con calidad 100.

    Pistas:

    • Genera números aleatorios entre 0 y 100.
    • Detén el bucle cuando salga 100.
    • Muestra cuántos intentos necesitó.

    Ejemplo:

    ¡Perfecta! Calidad 100 obtenida tras 57 intentos.

    Objetivo: repetir intentos hasta que salga calidad 100, mostrar cuántos intentos.

    Idea

    • Bucle while o do-while
    • Contador de intentos
    • Se para cuando calidad == 100

    Código

    
    
    
    
    
    import java.util.Random;
    
    public class Reto2RecetaPerfecta {
        public static void main(String[] args) {
            Random r = new Random();
    
            int intentos = 0;
            int calidad;
    
            do {
                calidad = r.nextInt(101);
                intentos++;
            } while (calidad != 100);
    
            System.out.println("¡Perfecta! Calidad 100 obtenida tras " + intentos + " intentos.");
        }
    }
    

    Por qué do-while: garantiza al menos un intento (tiene sentido aquí).


    RETO 3: “La producción nocturna”

    Walter y Jesse producen pastillas hasta llegar a 1000 unidades buenas (≥90).

    Muestra cuántas totales han hecho (incluyendo las malas).

    Ejemplo:

    Para conseguir 1000 pastillas buenas, produjeron un total de 8732.
    
    

    Objetivo: producir hasta conseguir 1000 buenas (≥90), y mostrar cuántas totales se produjeron.

    Idea

    • buenas llega a 1000
    • totales cuenta todas, buenas y malas
    • Condición buena: calidad >= 90

    Código

    
    
    
    
    
    import java.util.Random;
    
    public class Reto3ProduccionNocturna {
        public static void main(String[] args) {
            Random r = new Random();
    
            int buenas = 0;
            int totales = 0;
    
            while (buenas < 1000) {
                int calidad = r.nextInt(101);
                totales++;
    
                if (calidad >= 90) {
                    buenas++;
                }
            }
    
            System.out.println("Para conseguir 1000 pastillas buenas, produjeron un total de " + totales + ".");
        }
    }
    

    RETO 4: “El análisis por lotes”

    Dividir la producción en 10 lotes de 100 pastillas y mostrar cuántas buenas hay en cada lote.

    Salida esperada:

    Lote 1 → 13 pastillas buenas
    Lote 2 → 8 pastillas buenas
    ...
    Lote 10 → 11 pastillas buenas
    
    

    Objetivo: 10 lotes de 100, contar buenas (≥90) por lote.

    Idea

    • Bucle externo: lotes 1..10
    • Bucle interno: 100 pastillas
    • Contador buenasLote reiniciado en cada lote

    Código

    
    
    
    
    
    import java.util.Random;
    
    public class Reto4AnalisisPorLotes {
        public static void main(String[] args) {
            Random r = new Random();
    
            int lotes = 10;
            int tamLote = 100;
    
            for (int lote = 1; lote <= lotes; lote++) {
                int buenasLote = 0;
    
                for (int i = 1; i <= tamLote; i++) {
                    int calidad = r.nextInt(101);
                    if (calidad >= 90) {
                        buenasLote++;
                    }
                }
    
                System.out.println("Lote " + lote + " \u2192 " + buenasLote + " pastillas buenas");
            }
        }
    }
    

    RETO 5: “Promedio de calidad”

    Calcular el promedio total de calidad de las 1000 pastillas.

    Salida:

    Promedio de calidad general: 72.38
    
    

    Objetivo: promedio de calidad de 1000 pastillas.

    Idea

    • Acumulador sumaCalidades
    • Tras el bucle: promedio = suma / total
    • Para mostrar con 2 decimales: System.out.printf

    Código

    
    
    
    
    
    import java.util.Random;
    
    public class Reto5PromedioCalidad {
        public static void main(String[] args) {
            Random r = new Random();
    
            int total = 1000;
            int sumaCalidades = 0;
    
            for (int i = 1; i <= total; i++) {
                int calidad = r.nextInt(101);
                sumaCalidades += calidad;
            }
    
            double promedio = (double) sumaCalidades / total;
    
            System.out.printf("Promedio de calidad general: %.2f%n", promedio);
        }
    }
    

    Detalle clave: el casteo a double evita división entera.

    RETO 6 (extra): “La inspección de Gus Fring”

    Genera pastillas hasta tener 500 buenas, pero cada vez que salgan 50 malas seguidas, muestra:

    🔥 Gus Fring sospecha del laboratorio...
    
    

    Objetivo: generar pastillas hasta tener 500 buenas (≥90), pero cada vez que haya 50 malas seguidas, imprimir:

    Gus Fring sospecha del laboratorio...

    Idea

    • Contador buenas hasta 500
    • Contador malasSeguidas que:
      • aumenta si sale mala (<90)
      • se reinicia a 0 si sale buena
    • Cuando malasSeguidas == 50, avisamos y reiniciamos (o seguimos contando, tú eliges; aquí reiniciamos para no spamear).

    Código

    import java.util.Random;
    
    public class Reto6InspeccionGusFring {
        public static void main(String[] args) {
            Random r = new Random();
    
            int buenas = 0;
            int totales = 0;
            int malasSeguidas = 0;
    
            while (buenas < 500) {
                int calidad = r.nextInt(101);
                totales++;
    
                if (calidad >= 90) {
                    buenas++;
                    malasSeguidas = 0; // racha de malas se rompe
                } else {
                    malasSeguidas++;
                }
    
                if (malasSeguidas == 50) {
                    System.out.println("🔥 Gus Fring sospecha del laboratorio...");
                    malasSeguidas = 0; // reiniciamos para volver a detectar otra racha de 50
                }
            }
    
            System.out.println("Buenas conseguidas: " + buenas);
            System.out.println("Pastillas producidas en total: " + totales);
        }
    }
    
    
  • R3.3 [Solución]- Arrays – Bienvenido al mundo de Mr. Robot

    R3.3 [Solución]- Arrays – Bienvenido al mundo de Mr. Robot

    Evil Corp —el gigante que controla todo lo que consumes, lo que piensas y hasta lo que olvidas— cree tenerlo todo bajo control.

    Pero no contaba contigo.

    En un sótano lleno de cables, pantallas parpadeantes y tazas de café frías, un grupo de hackers conocidos como Atriumsociety prepara su próximo golpe digital. Su misión: devolver el poder a la gente, línea de código a línea de código.

    Tu papel comienza aquí.

    Eres parte del equipo. Hoy no vienes a “hacer ejercicios”, vienes a infiltrarte en el sistema, Cada array que declares es una base de datos secreta, cada bucle un intento de intrusión, cada condicional una decisión que puede cambiarlo todo.

    Prepárate: el prompt está parpadeando.

    Atriumsociety te necesita.

    1. “Elliot vs Evil Corp”

    Enunciado:

    Elliot ha interceptado una lista con los balances de Evil Corp.

    Con el siguiente array:

    int[] balances = {12000, -50, 5000, 15000, 0, -300, 800, 22000, 9999, 100};
    
    

    Muestra:

    • Cuántas cuentas tienen saldo negativo.
    • Cuántas tienen saldo superior a 10 000 $.
    • El saldo medio.

    Qué se hace

    • Recorremos balances
    • Contamos negativos (<0)
    • Contamos los que superan 10.000 (>10000)
    • Sumamos todo para el promedio

    Código

    public class ElliotVsEvilCorp {
        public static void main(String[] args) {
    
            int[] balances = {12000, -50, 5000, 15000, 0, -300, 800, 22000, 9999, 100};
    
            int negativos = 0;
            int masDe10000 = 0;
            int suma = 0;
    
            for (int i = 0; i < balances.length; i++) {
                int b = balances[i];
    
                if (b < 0) negativos++;
                if (b > 10000) masDe10000++;
    
                suma += b;
            }
    
            double media = (double) suma / balances.length;
    
            System.out.println("Cuentas con saldo negativo: " + negativos);
            System.out.println("Cuentas con saldo superior a 10000$: " + masDe10000);
            System.out.printf("Saldo medio: %.2f%n", media);
        }
    }
    

    2. “Backdoor Scanner”

    Enunciado:

    Darlene analiza si los servidores de Evil Corp están vulnerables.

    Usa el siguiente array:

    boolean[] vulnerables = {false, true, false, false, true, false, true, false};
    
    

    Muestra:

    • Cuántos servidores son vulnerables (true).
    • En qué posiciones están.

    Qué se hace

    • Recorremos el array de boolean
    • Si es true, contamos y mostramos la posición

    Código

    
    
    
    
    
    public class BackdoorScanner {
        public static void main(String[] args) {
    
            boolean[] vulnerables = {false, true, false, false, true, false, true, false};
    
            int contador = 0;
    
            System.out.print("Servidores vulnerables en posiciones: ");
            for (int i = 0; i < vulnerables.length; i++) {
                if (vulnerables[i]) {
                    contador++;
                    System.out.print(i + " ");
                }
            }
    
            System.out.println();
            System.out.println("Total vulnerables: " + contador);
        }
    }
    


    3. “Password Audit”

    Enunciado:

    Elliot encuentra las siguientes contraseñas antiguas de Evil Corp:

    String[] passwords = {"admin123", "e@mpl3", "supersecure99", "pass", "root@2020"};
    
    

    Indica:

    • Cuántas contienen el carácter @.
    • Cuántas tienen más de 8 caracteres.
    • Cuántas terminan en un número.
    • Cuál es la más larga.

    Qué se hace

    Para cada contraseña:

    • contains("@") → cuenta las que tienen @
    • length() > 8 → largas
    • “termina en número” → miramos el último carácter con charAt y comprobamos si es dígito
    • “la más larga” → guardamos la que tenga mayor longitud

    Código

    
    
    
    
    
    public class PasswordAudit {
        public static void main(String[] args) {
    
            String[] passwords = {"admin123", "e@mpl3", "supersecure99", "pass", "root@2020"};
    
            int conArroba = 0;
            int masDe8 = 0;
            int terminanEnNumero = 0;
    
            String masLarga = passwords[0];
    
            for (int i = 0; i < passwords.length; i++) {
                String p = passwords[i];
    
                if (p.contains("@")) conArroba++;
                if (p.length() > 8) masDe8++;
    
                char ultimo = p.charAt(p.length() - 1);
                if (Character.isDigit(ultimo)) terminanEnNumero++;
    
                if (p.length() > masLarga.length()) {
                    masLarga = p;
                }
            }
    
            System.out.println("Contraseñas con @: " + conArroba);
            System.out.println("Contraseñas con más de 8 caracteres: " + masDe8);
            System.out.println("Contraseñas que terminan en número: " + terminanEnNumero);
            System.out.println("La más larga es: " + masLarga + " (" + masLarga.length() + " caracteres)");
        }
    }
    


    4. “Hack the Gibson”

    Enunciado:

    Simula los niveles de éxito de los ataques de Elliot con el siguiente array:

    int[] intentos = {82, 13, 45, 79, 90, 5, 33, 72, 18, 65, 40, 100, 29, 10, 67, 55, 88, 60, 14, 3};
    
    

    Muestra:

    • El valor máximo y el mínimo.
    • Cuántos intentos fueron “exitosos” (más de 70).
    • Si todos son menores de 30, muestra “Mr Robot sospecha que estás desconectado”.

    Qué se hace

    • Máximo y mínimo: inicializamos con el primer elemento y comparamos
    • Exitosos: >70
    • “si todos son menores de 30”: bandera todosMenor30 (true al inicio, se rompe si encontramos uno >= 30)

    Código

    
    
    
    
    
    public class HackTheGibson {
        public static void main(String[] args) {
    
            int[] intentos = {82, 13, 45, 79, 90, 5, 33, 72, 18, 65, 40, 100, 29, 10, 67, 55, 88, 60, 14, 3};
    
            int max = intentos[0];
            int min = intentos[0];
            int exitosos = 0;
    
            boolean todosMenor30 = true;
    
            for (int i = 0; i < intentos.length; i++) {
                int v = intentos[i];
    
                if (v > max) max = v;
                if (v < min) min = v;
    
                if (v > 70) exitosos++;
    
                if (v >= 30) {
                    todosMenor30 = false;
                }
            }
    
            System.out.println("Máximo: " + max);
            System.out.println("Mínimo: " + min);
            System.out.println("Intentos exitosos (>70): " + exitosos);
    
            if (todosMenor30) {
                System.out.println("Mr Robot sospecha que estás desconectado");
            }
        }
    }
    


    5. “Logs del Servidor”

    Enunciado:

    Angela revisa los registros de acceso de un servidor:

    String[] logs = {"OK", "ERROR", "OK", "OK", "ERROR", "OK", "ERROR", "ERROR", "OK", "OK"};
    
    

    Cuenta:

    • Cuántos accesos fueron "OK".
    • Cuántos "ERROR".
    • Si hay más errores que accesos correctos, muestra “Servidor en peligro”.

    Qué se hace

    • Contar "OK" y "ERROR" usando equals
    • Comparar: si errores > ok → aviso

    Código

    
    
    
    
    
    public class LogsDelServidor {
        public static void main(String[] args) {
    
            String[] logs = {"OK", "ERROR", "OK", "OK", "ERROR", "OK", "ERROR", "ERROR", "OK", "OK"};
    
            int ok = 0;
            int error = 0;
    
            for (int i = 0; i < logs.length; i++) {
                if (logs[i].equals("OK")) ok++;
                else if (logs[i].equals("ERROR")) error++;
            }
    
            System.out.println("OK: " + ok);
            System.out.println("ERROR: " + error);
    
            if (error > ok) {
                System.out.println("Servidor en peligro");
            }
        }
    }
    


    6. “Temperaturas del Servidor”

    Enunciado:

    Durante un ataque, Elliot monitoriza las temperaturas del servidor:

    int[] temperaturas = {45, 49, 52, 57, 60, 59, 55, 48, 46, 50};
    
    

    Calcula:

    • La temperatura media.
    • Cuántas mediciones superan los 55 °C.
    • Si todas las temperaturas están por debajo de 60 °C, muestra “Sistema estable”; si alguna es 60 o más, muestra “¡Sobrecalentamiento detectado!”.

    Qué se hace

    • Media: suma / total
    • Contar >55
    • Comprobar si alguna es >=60 (bandera sobrecalentamiento)

    Código

    
    
    
    
    
    public class TemperaturasServidor {
        public static void main(String[] args) {
    
            int[] temperaturas = {45, 49, 52, 57, 60, 59, 55, 48, 46, 50};
    
            int suma = 0;
            int superan55 = 0;
    
            boolean sobrecalentamiento = false;
    
            for (int i = 0; i < temperaturas.length; i++) {
                int t = temperaturas[i];
    
                suma += t;
    
                if (t > 55) superan55++;
                if (t >= 60) sobrecalentamiento = true;
            }
    
            double media = (double) suma / temperaturas.length;
    
            System.out.printf("Temperatura media: %.2f%n", media);
            System.out.println("Mediciones que superan 55°C: " + superan55);
    
            if (!sobrecalentamiento) {
                System.out.println("Sistema estable");
            } else {
                System.out.println("¡Sobrecalentamiento detectado!");
            }
        }
    }
    


    7. “DDoS Simulator”

    Enunciado:

    Durante un ataque DDoS, se registran los siguientes tiempos de respuesta (en ms):

    int[] tiempos = {200, 540, 720, 150, 950, 330, 480, 510, 870, 610};
    
    

    Muestra:

    • La media, el máximo y el mínimo.
    • Si más del 60 % supera los 500 ms, muestra “Servidor saturado”.
    • Si menos del 10 % supera los 200 ms, muestra “Ataque fallido”.

    Qué se hace

    • Media, máximo, mínimo (igual que antes)
    • Contar cuántos superan 500 → para porcentaje
    • Si (superan500 / total) > 0.60 → “Servidor saturado”
    • Si (superan200 / total) < 0.10 → “Ataque fallido”
      • Nota: “supera 200” significa >200, no >=200.

    Código

    
    
    
    
    
    public class DDoSSimulator {
        public static void main(String[] args) {
    
            int[] tiempos = {200, 540, 720, 150, 950, 330, 480, 510, 870, 610};
    
            int suma = 0;
            int max = tiempos[0];
            int min = tiempos[0];
    
            int superan500 = 0;
            int superan200 = 0;
    
            for (int i = 0; i < tiempos.length; i++) {
                int t = tiempos[i];
    
                suma += t;
                if (t > max) max = t;
                if (t < min) min = t;
    
                if (t > 500) superan500++;
                if (t > 200) superan200++;
            }
    
            double media = (double) suma / tiempos.length;
    
            double porcentaje500 = (double) superan500 / tiempos.length;
            double porcentaje200 = (double) superan200 / tiempos.length;
    
            System.out.printf("Media: %.2f ms%n", media);
            System.out.println("Máximo: " + max + " ms");
            System.out.println("Mínimo: " + min + " ms");
    
            if (porcentaje500 > 0.60) {
                System.out.println("Servidor saturado");
            }
    
            if (porcentaje200 < 0.10) {
                System.out.println("Ataque fallido");
            }
        }
    }