Categoría: Programación

  • 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");
            }
        }
    }
    
  • R8 [Solución]- El Escalafón Mágico de Hogwarts

    R8 [Solución]- 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.

    1) Casa.java (enum)

    La enum sirve para tener un conjunto cerrado de valores (solo esas casas), evitando Strings sueltos.

    
    
    
    
    
    package modelo;
    
    public enum Casa {
        GRYFFINDOR,
        SLYTHERIN,
        RAVENCLAW,
        HUFFLEPUFF
    }
    

    2) Mago.java (clase base)

    Qué aporta esta clase

    • Define lo común a todos: nombre, nivel, vida, mana, casa.
    • Aplica un bonus inicial según la casa.
    • Tiene métodos base (entrenar, descansar, ficha, lanzarHechizo).
    • lanzarHechizo NO es abstracto: por defecto hace algo simple.
    
    
    
    
    
    package modelo;
    
    public class Mago {
    
        protected String nombre;
        protected int nivel; // 1..100
        protected int vida;  // 0..100
        protected int mana;  // 0..100
        protected Casa casa;
    
        public Mago(String nombre, Casa casa) {
            this.nombre = nombre;
            this.casa = casa;
    
            // Valores base
            this.nivel = 1;
            this.vida = 100;
            this.mana = 100;
    
            aplicarBonusCasa();
        }
    
        private void aplicarBonusCasa() {
            // Bonus simples y fáciles de ver en consola
            switch (casa) {
                case GRYFFINDOR:
                    vida += 10; // más resistencia
                    break;
                case SLYTHERIN:
                    mana += 10; // más “energía mágica”
                    break;
                case RAVENCLAW:
                    nivel += 1; // aprende más rápido (nivel inicial superior)
                    break;
                case HUFFLEPUFF:
                    vida += 5;
                    mana += 5; // equilibrio
                    break;
            }
            // Normalizamos límites
            vida = clamp(vida, 0, 100);
            mana = clamp(mana, 0, 100);
            nivel = clamp(nivel, 1, 100);
        }
    
        public void entrenar() {
            // Entrenar sube nivel, pero cansa
            nivel += 1;
            mana -= 5;
            vida -= 2;
    
            nivel = clamp(nivel, 1, 100);
            mana = clamp(mana, 0, 100);
            vida = clamp(vida, 0, 100);
        }
    
        public void descansar() {
            // Descansar recupera recursos
            mana += 10;
            vida += 10;
    
            mana = clamp(mana, 0, 100);
            vida = clamp(vida, 0, 100);
        }
    
        public String ficha() {
            return nombre + " | Casa: " + casa +
                   " | Nivel: " + nivel +
                   " | Vida: " + vida +
                   " | Mana: " + mana;
        }
    
        /**
         * Lanza un hechizo genérico. Las clases hijas lo mejoran.
         * Devuelve el "daño" (o 0 si no se puede).
         */
        public int lanzarHechizo(String hechizo) {
            int coste = 5;
            if (!gastarMana(coste)) return 0;
            return 3; // daño base genérico
        }
    
        protected boolean gastarMana(int cantidad) {
            if (mana < cantidad) {
                return false;
            }
            mana -= cantidad;
            mana = clamp(mana, 0, 100);
            return true;
        }
    
        public void recibirDaño(int daño) {
            vida -= daño;
            vida = clamp(vida, 0, 100);
        }
    
        protected int clamp(int valor, int min, int max) {
            if (valor < min) return min;
            if (valor > max) return max;
            return valor;
        }
    }
    

    3) Aprendiz.java

    Idea clave

    • Un Aprendiz tiene torpeza, así que puede fallar.
    • Aprende con practicarBasico().
    • Sobrescribe lanzarHechizo para permitir solo hechizos básicos.
    
    
    
    
    
    package modelo;
    
    import java.util.Random;
    
    public class Aprendiz extends Mago {
    
        protected int torpeza; // 0..100 (más torpeza = más fallos)
        protected Random rnd = new Random();
    
        public Aprendiz(String nombre, Casa casa) {
            super(nombre, casa);
    
            torpeza = 40;
    
            // Ajuste según casa (sencillo y visible)
            if (casa == Casa.RAVENCLAW) torpeza -= 10;   // más “cabeza”
            if (casa == Casa.HUFFLEPUFF) torpeza -= 5;   // constancia
            if (casa == Casa.SLYTHERIN) torpeza += 5;    // “se la juega más”
            torpeza = clamp(torpeza, 0, 100);
        }
    
        public void practicarBasico() {
            // Practicar reduce torpeza (mejora)
            if (!gastarMana(3)) return;
    
            torpeza -= 2;
            torpeza = clamp(torpeza, 0, 100);
    
            // Practicar también puede subir un poquito el nivel
            if (nivel < 100) nivel += 1;
        }
    
        @Override
        public int lanzarHechizo(String hechizo) {
            // Coste base
            if (!gastarMana(5)) return 0;
    
            // Probabilidad de fallo basada en torpeza
            int tirada = rnd.nextInt(100); // 0..99
            if (tirada < torpeza) {
                // falló
                return 0;
            }
    
            // Hechizos permitidos
            if (hechizo.equalsIgnoreCase("Lumos")) return 5;
            if (hechizo.equalsIgnoreCase("Alohomora")) return 7;
    
            // Si escribe otro, no lo conoce
            return 0;
        }
    
        public int getTorpeza() {
            return torpeza;
        }
    
        public void setTorpeza(int torpeza) {
            this.torpeza = clamp(torpeza, 0, 100);
        }
    }
    

    4) Hechicero.java

    Idea clave

    • Hereda de Aprendiz, pero ahora tiene controlVarita.
    • Puede hacer hechizos más potentes.
    • Los fallos deberían ser menos frecuentes: usamos torpeza pero “rebajada”.
    
    
    
    
    
    package modelo;
    
    import java.util.Random;
    
    public class Hechicero extends Aprendiz {
    
        protected int controlVarita; // 0..100
        protected Random rnd2 = new Random();
    
        public Hechicero(String nombre, Casa casa) {
            super(nombre, casa);
    
            controlVarita = 50;
    
            // Ravenclaw suele destacar en control
            if (casa == Casa.RAVENCLAW) controlVarita += 10;
            if (casa == Casa.GRYFFINDOR) controlVarita += 5;
    
            controlVarita = clamp(controlVarita, 0, 100);
        }
    
        public void estudiarEnBiblioteca() {
            if (!gastarMana(6)) return;
    
            controlVarita += 3;
            controlVarita = clamp(controlVarita, 0, 100);
    
            nivel += 1;
            nivel = clamp(nivel, 1, 100);
        }
    
        @Override
        public int lanzarHechizo(String hechizo) {
            if (!gastarMana(7)) return 0;
    
            // Los Hechiceros fallan menos: torpeza influye menos
            int torpezaEfectiva = clamp(torpeza - (controlVarita / 5), 0, 100);
            int tirada = rnd2.nextInt(100);
            if (tirada < torpezaEfectiva) return 0;
    
            // Hechizos
            if (hechizo.equalsIgnoreCase("Lumos")) return 6;
            if (hechizo.equalsIgnoreCase("Alohomora")) return 8;
            if (hechizo.equalsIgnoreCase("Expelliarmus")) return 12;
            if (hechizo.equalsIgnoreCase("Stupefy")) return 18;
    
            return 0;
        }
    
        public int getControlVarita() {
            return controlVarita;
        }
    }
    

    5) Auror.java

    Idea clave

    • Un Auror es “modo combate”: tiene experiencia y puede arrestar.
    • Añadimos métodos propios: patrullar() y arrestar(...).
    
    
    
    
    
    package modelo;
    
    public class Auror extends Hechicero {
    
        private int experienciaCombate; // 0..100
        private int arrestos;
    
        public Auror(String nombre, Casa casa) {
            super(nombre, casa);
    
            experienciaCombate = 40;
            arrestos = 0;
    
            if (casa == Casa.GRYFFINDOR) experienciaCombate += 10; // valentía
            if (casa == Casa.SLYTHERIN) experienciaCombate += 5;   // ambición táctica
            experienciaCombate = clamp(experienciaCombate, 0, 100);
        }
    
        public void patrullar() {
            if (!gastarMana(8)) return;
    
            experienciaCombate += 4;
            experienciaCombate = clamp(experienciaCombate, 0, 100);
    
            nivel += 1;
            nivel = clamp(nivel, 1, 100);
        }
    
        public boolean arrestar(Aprendiz objetivo) {
            // Regla: solo si está débil
            if (objetivo == null) return false;
    
            // Como vida es protected en Mago, podemos leerla aquí directamente:
            if (objetivo.vida <= 20) {
                arrestos++;
                return true;
            }
            return false;
        }
    
        @Override
        public int lanzarHechizo(String hechizo) {
            if (!gastarMana(9)) return 0;
    
            // Auror: daño mejorado por experienciaCombate
            if (hechizo.equalsIgnoreCase("Stupefy")) {
                return 20 + (experienciaCombate / 10);
            }
    
            // Protego: “defensa” simple -> recupera vida (no daño)
            if (hechizo.equalsIgnoreCase("Protego")) {
                vida += 10;
                vida = clamp(vida, 0, 100);
                return 0;
            }
    
            // Otros hechizos como en Hechicero (reutilizamos lógica)
            return super.lanzarHechizo(hechizo);
        }
    
        public int getArrestos() {
            return arrestos;
        }
    }
    

    6) Profesor.java

    Idea clave

    • Un Profesor enseña: puede reducir torpeza y subir nivel del alumno.
    • Sus hechizos son “eficientes”: consumen menos mana o fallan menos.
    
    
    
    
    
    package modelo;
    
    public class Profesor extends Hechicero {
    
        private String asignatura;
        private int prestigio; // 0..100
    
        public Profesor(String nombre, Casa casa, String asignatura) {
            super(nombre, casa);
            this.asignatura = asignatura;
    
            prestigio = 60;
            if (casa == Casa.SLYTHERIN) prestigio += 5;
            if (casa == Casa.RAVENCLAW) prestigio += 10;
            prestigio = clamp(prestigio, 0, 100);
        }
    
        public void enseñar(Aprendiz alumno) {
            if (alumno == null) return;
            if (!gastarMana(6)) return;
    
            // Enseñar reduce torpeza y sube nivel
            alumno.setTorpeza(alumno.getTorpeza() - 8);
            alumno.nivel = clamp(alumno.nivel + 1, 1, 100);
        }
    
        public void evaluar() {
            if (!gastarMana(4)) return;
            prestigio += 2;
            prestigio = clamp(prestigio, 0, 100);
        }
    
        @Override
        public int lanzarHechizo(String hechizo) {
            // Profesor: coste menor y resultados más estables
            int coste = 6;
            if (!gastarMana(coste)) return 0;
    
            // “Daño controlado”
            if (hechizo.equalsIgnoreCase("Expelliarmus")) return 14;
            if (hechizo.equalsIgnoreCase("Stupefy")) return 17;
            if (hechizo.equalsIgnoreCase("Lumos")) return 5;
            if (hechizo.equalsIgnoreCase("Alohomora")) return 7;
    
            return 0;
        }
    
        public String getAsignatura() {
            return asignatura;
        }
    }
    

    7) Main.java (sin listas de Mago, tipos concretos)

    package app;
    
    import modelo.*;
    
    public class Main {
    
        public static void main(String[] args) {
    
            Aprendiz harry = new Aprendiz("Harry", Casa.GRYFFINDOR);
            Aprendiz hermione = new Aprendiz("Hermione", Casa.RAVENCLAW);
    
            Hechicero draco = new Hechicero("Draco", Casa.SLYTHERIN);
            Hechicero luna = new Hechicero("Luna", Casa.HUFFLEPUFF);
    
            Auror kingsley = new Auror("Kingsley", Casa.HUFFLEPUFF);
            Profesor snape = new Profesor("Snape", Casa.SLYTHERIN, "Pociones");
    
            System.out.println("=== FICHAS INICIALES ===");
            System.out.println(harry.ficha());
            System.out.println(hermione.ficha());
            System.out.println(draco.ficha());
            System.out.println(luna.ficha());
            System.out.println(kingsley.ficha());
            System.out.println(snape.ficha());
    
            System.out.println("\n=== RONDA 1: PRACTICAR Y ESTUDIAR ===");
            harry.practicarBasico();
            hermione.practicarBasico();
            draco.estudiarEnBiblioteca();
            luna.estudiarEnBiblioteca();
            kingsley.patrullar();
            snape.evaluar();
    
            System.out.println(harry.ficha());
            System.out.println(hermione.ficha());
            System.out.println(draco.ficha());
            System.out.println(luna.ficha());
            System.out.println(kingsley.ficha());
            System.out.println(snape.ficha());
    
            System.out.println("\n=== RONDA 2: DUELO SIMPLE (daño a vida) ===");
            int d1 = draco.lanzarHechizo("Stupefy");
            harry.recibirDaño(d1);
            System.out.println("Draco lanza Stupefy a Harry. Daño: " + d1);
            System.out.println("Harry -> " + harry.ficha());
    
            int d2 = harry.lanzarHechizo("Lumos");
            draco.recibirDaño(d2);
            System.out.println("Harry lanza Lumos a Draco (sí, es cutre). Daño: " + d2);
            System.out.println("Draco -> " + draco.ficha());
    
            System.out.println("\n=== RONDA 3: PROFESOR EN ACCIÓN ===");
            snape.enseñar(harry);
            System.out.println("Snape enseña a Harry (baja torpeza y sube nivel).");
            System.out.println("Harry -> " + harry.ficha());
    
            System.out.println("\n=== RONDA 4: AUROR Y PROTEGO ===");
            int d3 = kingsley.lanzarHechizo("Stupefy");
            luna.recibirDaño(d3);
            System.out.println("Kingsley lanza Stupefy a Luna. Daño: " + d3);
            System.out.println("Luna -> " + luna.ficha());
    
            kingsley.lanzarHechizo("Protego");
            System.out.println("Kingsley usa Protego (se cura un poco).");
            System.out.println("Kingsley -> " + kingsley.ficha());
    
            System.out.println("\n=== RONDA 5: INTENTO DE ARRESTO ===");
            // Bajamos a propósito la vida de Hermione para probar arresto
            hermione.recibirDaño(85);
            System.out.println("Hermione queda débil: " + hermione.ficha());
    
            boolean arresto = kingsley.arrestar(hermione);
            System.out.println("¿Kingsley arresta a Hermione? " + arresto);
            System.out.println("Arrestos de Kingsley: " + kingsley.getArrestos());
        }
    }
    
    Aquí el alumnado ve claramente la herencia: cada clase tiene lo suyo.
    
    
    
    
    

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