Una forma sencilla y rápida de aprender JAVA, observando y deduciendo cómo se comporta el lenguaje a través de ejemplos prácticos.

Archivo del blog

miércoles, 28 de diciembre de 2022

Conversión de Infijo a Postfijo usando pilas (v.4). Mejorar formato de entrada.

Se incorpora mejoras en la función de limpieza y formateo que permite ajustar la calidad y la precisión de la expresión de entrada, eliminando cualquier elemento innecesario y corrigiendo posibles errores de formateo.


Código Java (InfijoPostfijo.java):

package infijopostfijo;

import java.util.Scanner;
import java.util.Stack;

public class InfijoPostfijo {

    public static void main(String[] args) {

        // Declaración de las pilas
        Stack<String> E = new Stack<>(); // Pila entrada
        Stack<String> P = new Stack<>(); // Pila temporal para operadores
        Stack<String> S = new Stack<>(); // Pila salida

        // Entrada de datos
        System.out.println("> Ingresa expresión algebraica a convertir:");
        Scanner leer = new Scanner(System.in);

        // Pasar expresión algebraica a la Pila de entrada (E)
        String[] arrayInfix = formato(leer.nextLine()).split(" ");
        for (int i = arrayInfix.length - 1; i >= 0; i--) {
            E.push(arrayInfix[i]);
        }

        // Conversor Infijo a Postfijo
        while (!E.isEmpty()) {
            switch (prioridad(E.peek())) {
                case 1 ->
                    P.push(E.pop());
                case 2 -> {
                    while (!P.peek().equals("(")) {
                        S.push(P.pop());
                    }
                    P.pop();
                    E.pop();
                }
                case 3, 4 -> {
                    while (prioridad(P.peek()) >= prioridad(E.peek())) {
                        S.push(P.pop());
                    }
                    P.push(E.pop());
                }
                case 5 ->
                    P.push(E.pop());
                default ->
                    S.push(E.pop());
            }
        }

        // Mostrar resultado:
        System.out.println("> Expresión en notación Postfija:\n" + S.toString().replaceAll("[\\]\\[,]", ""));

    }

    // Prioridad de los operadores
    private static int prioridad(String op) {
        return switch (op) {
            case "^" -> 5;
            case "*", "/" -> 4;
            case "+", "-" -> 3;
            case ")" -> 2;
            case "(" -> 1;
            default -> 99;
        };
    }

    // Formato expresión algebraica
    private static String formato(String expr) {
        expr = expr.trim();
        expr = expr.charAt(0) == '-' ? "0-" + expr.substring(1) : expr;
        expr = expr.replaceAll("\\(-(\\d)", "(0-$1");
        expr = expr.replaceAll("(\\d)\\(", "$1*(");
        expr = expr.replaceAll("\\)(\\d)", ")*$1");
        expr = expr.replaceAll("([\\+|\\-|\\*|\\/|\\(|\\)|\\^|])", " $1 ");
        expr = expr.replaceAll("\\s+", " ");
        return "( " + expr + " )";
    }

}


Resultado:

run:
> Ingresa expresión algebraica a convertir:
-4(56-3+5)/2-(45+34)+(-23*(-52)6+2)-1   
> Expresión en notación Postfija:
0 4 56 3 - 5 + * 2 / - 45 34 + - 0 23 0 52 - * 6 * - 2 + + 1 -
BUILD SUCCESSFUL (total time: 2 seconds)

martes, 27 de diciembre de 2022

Problema del viajante de comercio TSP (III.4). Cálculo mediante método Vecino Cercano.

El algoritmo de vecino más cercano funciona de la siguiente manera:

    .Se elige una ciudad de inicio.
    .Se selecciona la ciudad más cercana a la ciudad actual, y se añade al camino.
    .Se repite el proceso anterior hasta que se haya visitado todas las ciudades.
    .Se regresa al lugar de origen para completar el ciclo.

El algoritmo de vecino más cercano es una forma rápida y sencilla de encontrar una solución para el TSP, pero no garantiza que sea la solución óptima. En general, el algoritmo tiende a dar buenos resultados para problemas pequeños, pero puede no ser tan efectivo para problemas más grandes.


Código (TSP_MainVecinoCercano.java):

package tsp_mainvecinocercano;

import java.util.ArrayList;
import java.util.List;

public class TSP_MainVecinoCercano {

    public static void main(String[] args) {

        int n = 12;
        int[][] distances = new int[n][n];

        // Generar distancias aleatorias
        for (int i = 0; i < n; i++) {
            for (int j = i; j < n; j++) {
                if (i == j) {
                    distances[i][j] = 0;
                } else {
                    distances[i][j] = (int) (Math.random() * 999 + 1);
                    distances[j][i] = distances[i][j];
                }
            }
        }

        // Imprimir matriz de distancias
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                System.out.printf("%5d ", distances[i][j]);
            }
            System.out.println();
        }

        TSP_VecinoCercano tsp = new TSP_VecinoCercano(distances);
        List<Integer> path = tsp.findOptimalPath();

        // Pone nombre a los nodos siguiendo la secuencia del abcedario
        List<String> nodeNames = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            char letter = (char) ('A' + i);
            nodeNames.add(String.valueOf(letter));
        }

        // Imprimir ruta y distancia recorrida
        System.out.println("\n> Ruta:");
        path.forEach(node -> {
            System.out.print(nodeNames.get(node) + " ");
        });
        System.out.println("\n> La distancia total recorrida es:");
        int totalDistance = 0;
        for (int i = 0; i < path.size() - 1; i++) {
            int node1 = path.get(i);
            int node2 = path.get(i + 1);
            totalDistance += distances[node1][node2];
        }
        System.out.println(totalDistance);
    }

}


Código 2 (TSP_VecinoCercano.java):

package tsp_mainvecinocercano;

import java.util.ArrayList;
import java.util.List;

public class TSP_VecinoCercano {

    private final int[][] distances;

    public TSP_VecinoCercano(int[][] distances) {
        this.distances = distances;
    }

    public List<Integer> findOptimalPath() {
        List<Integer> path = new ArrayList<>();
        path.add(0); // Empezamos en el nodo 0

        int currentNode = 0;
        for (int i = 0; i < distances.length - 1; i++) {
            int minDistance = Integer.MAX_VALUE;
            int nextNode = -1;
            for (int j = 0; j < distances.length; j++) {
                if (distances[currentNode][j] < minDistance && !path.contains(j)) {
                    minDistance = distances[currentNode][j];
                    nextNode = j;
                }
            }
            path.add(nextNode);
            currentNode = nextNode;
        }

        // Volvemos al nodo de origen
        path.add(0);

        return path;
    }

}


Resultado:

run:
    0   138   758   967   823   983   914   935   369   522   282   990
  138     0   997   828   997   770   963   398   590   668   312   716
  758   997     0   849   945   774   952    47   859    52   438   582
  967   828   849     0   556   800   501   589   928   149   409   912
  823   997   945   556     0   856   172   696   375   240   335   887
  983   770   774   800   856     0   213    39   549   694   102    65
  914   963   952   501   172   213     0   164    79   243   646   907
  935   398    47   589   696    39   164     0   205   571   392   504
  369   590   859   928   375   549    79   205     0   167   253   203
  522   668    52   149   240   694   243   571   167     0   475   578
  282   312   438   409   335   102   646   392   253   475     0   314
  990   716   582   912   887    65   907   504   203   578   314     0

> Ruta:
A B K F H C J D G I L E A
> La distancia total recorrida es:
3332
BUILD SUCCESSFUL (total time: 0 seconds)

lunes, 26 de diciembre de 2022

Conversión de Infijo a Postfijo usando pilas (v.3). Añadir operador de potencia ^.

En esta nueva versión añadimos el operador de potencia ^ que faltaba.
Hay que tener en cuenta que el operador de potencia ^ tiene una prioridad muy alta en las expresiones matemáticas, lo que significa que se evalúa antes que los otros operadores.


Código Java (InfijoPostfijo,java):

package infijopostfijo;

import java.util.Scanner;
import java.util.Stack;

public class InfijoPostfijo {

    public static void main(String[] args) {

        // Declaración de las pilas
        Stack<String> E = new Stack<>(); // Pila entrada
        Stack<String> P = new Stack<>(); // Pila temporal para operadores
        Stack<String> S = new Stack<>(); // Pila salida

        // Entrada de datos
        System.out.println("> Ingresa expresión algebraica a convertir:");
        Scanner leer = new Scanner(System.in);

        // Pasar expresión algebraica a la Pila de entrada (E)
        String[] arrayInfix = formato(leer.nextLine()).split(" ");
        for (int i = arrayInfix.length - 1; i >= 0; i--) {
            E.push(arrayInfix[i]);
        }

        // Conversor Infijo a Postfijo
        while (!E.isEmpty()) {
            switch (prioridad(E.peek())) {
                case 1 -> P.push(E.pop());
                case 2 -> {
                    while (!P.peek().equals("(")) {
                        S.push(P.pop());
                    }
                    P.pop();
                    E.pop();
                }
                case 3, 4 -> {
                    while (prioridad(P.peek()) >= prioridad(E.peek())) {
                        S.push(P.pop());
                    }
                    P.push(E.pop());
                }                
                case 5 -> P.push(E.pop());                
                default -> S.push(E.pop());
            }
        }

        // Mostrar resultado:
        System.out.println("> Resultado en notación postfija:\n" + S.toString().replaceAll("[\\]\\[,]", ""));
        
    }

    // Prioridad de los operadores
    private static int prioridad(String op) {
        return switch (op) {
            case "^" -> 5;
            case "*", "/" -> 4;
            case "+", "-" -> 3;
            case ")" -> 2;
            case "(" -> 1;
            default -> 99;
        };
    }

    // Formato expresión algebraica
    private static String formato(String s) {
        return "( " + s.replaceAll("([\\+|\\-|\\*|\\/|\\(|\\)|\\^|])", " $1 ").replaceAll("\\s+", " ") + " )";
    }
}


Resultado:

run:
> Ingresa expresión algebraica a convertir:
(((34/2)+(43-5-32))^2*2+45-3+(34*2)/5)-1
> Resultado en notación postfija:
 34 2 / 43 5 - 32 - + 2 ^ 2 * 45 + 3 - 34 2 * 5 / + 1 -
BUILD SUCCESSFUL (total time: 3 seconds)

domingo, 25 de diciembre de 2022

Conversión de Infijo a Postfijo usando pilas (v.2)

Código java (InfijoPostfijo.java):

package infijopostfijo;

import java.util.Scanner;
import java.util.Stack;

public class InfijoPostfijo {

    public static void main(String[] args) {

        // Declaración de las pilas
        Stack<String> E = new Stack<>(); // Pila entrada
        Stack<String> P = new Stack<>(); // Pila temporal para operadores
        Stack<String> S = new Stack<>(); // Pila salida

        // Entrada de datos
        System.out.println("> Ingresa una expresión algebraica: ");
        Scanner leer = new Scanner(System.in);

        // Pasar expresión algebraica a la Pila de entrada (E)
        String[] arrayInfix = formato(leer.nextLine()).split(" ");
        for (int i = arrayInfix.length - 1; i >= 0; i--) {
            E.push(arrayInfix[i]);
        }

        // Conversor Infijo a Postfijo
        while (!E.isEmpty()) {
            switch (prioridad(E.peek())) {
                case 1 -> P.push(E.pop());
                case 2 -> {
                    while (!P.peek().equals("(")) {
                        S.push(P.pop());
                    }
                    P.pop();
                    E.pop();
                }
                case 3, 4 -> {
                    while (prioridad(P.peek()) >= prioridad(E.peek())) {
                        S.push(P.pop());
                    }
                    P.push(E.pop());
                }                
                default -> S.push(E.pop());
            }
        }

        // Mostrar resultado:
        System.out.println("> Expresión Postfija:\n" + S.toString().replaceAll("[\\]\\[,]", ""));

    }

    // Prioridad de los operadores
    private static int prioridad(String op) {
        return switch (op) {
            case "*", "/" -> 4;
            case "+", "-" -> 3;
            case ")" -> 2;
            case "(" -> 1;
            default -> 99;
        };
    }

    // Formato expresión algebraica
    private static String formato(String s) {
        return "( " + s.replaceAll("([\\+|\\-|\\*|\\/|\\(|\\)])", " $1 ").replaceAll("\\s+", " ") + " )";
    }
}


Resultado:

run:
> Ingresa una expresión algebraica:
2*(23+6)-1
> Expresión Postfija:
2 23 6 + * 1 -
BUILD SUCCESSFUL (total time: 7 seconds)

Validación DNI de España.

Código java (AI_DniValidator.java):

package ai_dnivalidator;

import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class AI_DniValidator {

    private static final String DNI_PATTERN = "^[0-9]{8}[A-Z]$";

    public static boolean isValid(String dni) {
        Pattern pattern = Pattern.compile(DNI_PATTERN);
        Matcher matcher = pattern.matcher(dni);
        if (!matcher.matches()) {
            return false;
        }
        String letras = "TRWAGMYFPDXBNJZSQVHLCKE";
        int modulo = Integer.parseInt(dni.substring(0, 8)) % 23;
        char letraEsperada = letras.charAt(modulo);
        char letraObtenida = dni.charAt(8);
        return letraEsperada == letraObtenida;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("Ingresa un DNI: ");
        String dni = scanner.nextLine().toUpperCase();
        System.out.println(isValid(dni) ? "DNI válido" : "DNI inválido");
    }

}


Resultado:

run:
Ingresa un DNI: 12345678z
DNI válido
BUILD SUCCESSFUL (total time: 5 seconds)

sábado, 24 de diciembre de 2022

 Dibujar fractal de Mandelbrot

Un fractal de Mandelbrot es una imagen matemática que se crea a partir de una fórmula iterativa y se representa gráficamente en un plano complejo. Cada punto del plano se asigna un color en función de la cantidad de iteraciones que se necesitan para que el valor del número complejo alcance un cierto umbral.


Código java (AI_MandelbrotG.java):

package ai_mandelbrotg;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class AI_MandelbrotG extends JPanel {

    public static int WIDTH = 480;
    public static int HEIGHT = 300;
    public static final int MAX_ITERATIONS = 64;

    @Override
    public void paintComponent(Graphics graphics) {
        super.paintComponent(graphics);

        for (int x = 0; x < WIDTH; x++) {
            for (int y = 0; y < HEIGHT; y++) {

                // Calcula el valor de c para el punto (x, y)
                double cReal = (x - WIDTH / 2) * 4.0 / WIDTH;
                double cImag = (y - HEIGHT / 2) * 4.0 / WIDTH;

                // Calcula el valor de z para el punto (x, y)
                double zReal = 0;
                double zImag = 0;

                // Itera hasta encontrar el valor de z para el punto (x, y)
                int iterations = 0;
                while (zReal * zReal + zImag * zImag < 4 && iterations < MAX_ITERATIONS) {
                    double zRealTemp = zReal * zReal - zImag * zImag + cReal;
                    zImag = 2 * zReal * zImag + cImag;
                    zReal = zRealTemp;
                    iterations++;
                }

                // Establece el color para el punto (x, y) en función del número de iteraciones
                int colorValue = 255 * iterations / MAX_ITERATIONS;
                graphics.setColor(new Color(colorValue, colorValue, colorValue));
                graphics.drawLine(x, y, x, y);
            }
        }
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame("Fractal de Mandelbrot");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        AI_MandelbrotG panel = new AI_MandelbrotG();
        panel.setPreferredSize(new Dimension(WIDTH, HEIGHT));
        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
    }

}


Resultado:



viernes, 23 de diciembre de 2022

Crear curva Bézier. Uso de método curveTo de GeneralPath.

Un ejemplo de cómo utilizar el método curveTo de GeneralPath para crear una curva Bézier.
 

Código (Bezier.java): 

package bezier;

import java.awt.BasicStroke;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.GeneralPath;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Bezier extends JPanel {

    @Override
    public void paintComponent(Graphics g) {

        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setStroke(new BasicStroke(4.0f));

        int ancho = getWidth();
        int alto = getHeight();
        int x1 = ancho / 4;
        int y1 = alto / 4;
        int x2 = 3 * ancho / 4;
        int y2 = alto / 4;
        int x3 = ancho / 4;
        int y3 = 3 * alto / 4;
        int x4 = 3 * ancho / 4;
        int y4 = 3 * alto / 4;
        GeneralPath path = new GeneralPath();
        path.moveTo(x1, y1);
        path.curveTo(x2, y2, x3, y3, x4, y4);
        g2d.setColor(Color.BLUE);
        g2d.draw(path);
    }

    public static void main(String[] args) {
        JFrame ventana = new JFrame("Curva Bézier");
        ventana.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        ventana.add(new
Bezier());
        ventana.setSize(256, 256);
        ventana.setVisible(true);
    }
}


Resultado:



jueves, 27 de octubre de 2022

Mezlar, ordenar, rotar e invertir un listado. Uso "Collections".

Código (EjemploColecciones.java):

package ejemplocolecciones;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class EjemploColecciones {

    public static void main(String[] args) {
        List<Integer> cuadrante = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        //mostrar
        System.out.println("lista inicial:\n" + cuadrante);
        //mezclar
        Collections.shuffle(cuadrante);
        System.out.println("\nmezclar:\n" + cuadrante);
        //ordenar
        Collections.sort(cuadrante);
        System.out.println("\nordenar\n" + cuadrante);
        //rotar hacia la derecha
        Collections.rotate(cuadrante, 1);
        System.out.println("\ndesplazar hacia la derecha:\n" + cuadrante);
        //rotar hacia la izquierda
        Collections.rotate(cuadrante, -1);
        System.out.println("\ndesplazar hacia la izquierda:\n" + cuadrante);
        //invertir
        Collections.reverse(cuadrante);
        System.out.println("\ninvertir:\n" + cuadrante);
    }

}


Resultado:

run:
lista inicial:
[1, 2, 3, 4, 5, 6, 7, 8, 9]

mezclar:
[7, 9, 8, 6, 1, 5, 4, 2, 3]

ordenar
[1, 2, 3, 4, 5, 6, 7, 8, 9]

desplazar hacia la derecha:
[9, 1, 2, 3, 4, 5, 6, 7, 8]

desplazar hacia la izquierda:
[1, 2, 3, 4, 5, 6, 7, 8, 9]

invertir:
[9, 8, 7, 6, 5, 4, 3, 2, 1]
BUILD SUCCESSFUL (total time: 0 seconds)

Rotar elementos de una lista. Uso de "Collections.rotate".

El siguiente algoritmo desplaza una posición los elementos de una lista.


Código (ListaRotar.java):

package listarotar;

import java.util.List;
import java.util.Arrays;
import java.util.Collections;

public class ListaRotar {

    public static void main(String[] args) {
        List<Integer> cuadrante = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        for (int i = 0; i < 9; i++) {
            Collections.rotate(cuadrante, 1);
            System.out.println(cuadrante);
        }
    }

}


Resultado:

run:
[9, 1, 2, 3, 4, 5, 6, 7, 8]
[8, 9, 1, 2, 3, 4, 5, 6, 7]
[7, 8, 9, 1, 2, 3, 4, 5, 6]
[6, 7, 8, 9, 1, 2, 3, 4, 5]
[5, 6, 7, 8, 9, 1, 2, 3, 4]
[4, 5, 6, 7, 8, 9, 1, 2, 3]
[3, 4, 5, 6, 7, 8, 9, 1, 2]
[2, 3, 4, 5, 6, 7, 8, 9, 1]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
BUILD SUCCESSFUL (total time: 0 seconds)

domingo, 23 de octubre de 2022

Cola circular. Uso de Queue.

Una cola circular es una estructura de datos que almacena elementos en una lista (en este caso LinkedList) y que permite acceder a los datos por uno de los dos extremos de la lista. Un elemento se inserta en la cola (parte final) y se suprime/elimina por la parte frontal.


 

Código (colas.java):

package colas;

import java.util.LinkedList;
import java.util.Queue;

public class Colas {

    public static void main(String[] args) {
        Queue<Integer> cola = new LinkedList<>();
        llenar(cola);
        desplazar(cola);
    }

    //llenar cola
    private static void llenar(Queue<Integer> cola) {
        for (int i = 1; i < 10; i++) {
            cola.add(i);
        }
    }

    //correr una posición <-
    private static void desplazar(Queue<Integer> cola) {
        mostrar(cola);
        for (int i = 1; i < 9; i++) {
            cola.add(cola.poll());
            mostrar(cola);
        }
    }

    private static void mostrar(Queue<Integer>
cola) {
        System.out.println(
cola);
    }

}


Resultado:

run:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
[2, 3, 4, 5, 6, 7, 8, 9, 1]
[3, 4, 5, 6, 7, 8, 9, 1, 2]
[4, 5, 6, 7, 8, 9, 1, 2, 3]
[5, 6, 7, 8, 9, 1, 2, 3, 4]
[6, 7, 8, 9, 1, 2, 3, 4, 5]
[7, 8, 9, 1, 2, 3, 4, 5, 6]
[8, 9, 1, 2, 3, 4, 5, 6, 7]
[9, 1, 2, 3, 4, 5, 6, 7, 8]
BUILD SUCCESSFUL (total time: 0 seconds)

domingo, 16 de octubre de 2022

Mezclar elementos de una lista. Uso de "Collections.shuffle".

Código (GenSudoku.java):

package gensudoku;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class GenSudoku {

    public static void main(String[] args) {
        List<Integer> valores = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        System.out.println("valores no mezclados: " + valores);
        Collections.shuffle(valores);
        System.out.println("valores si mezclados: " + valores);
    }

}


Resultado:

valores no mezclados: [1, 2, 3, 4, 5, 6, 7, 8, 9]
valores si mezclados: [3, 9, 2, 8, 4, 5, 7, 1, 6]

sábado, 15 de octubre de 2022

Arrastrar un gráfico con el mouse dentro de jFrame.

Código Java (ArrastrarGrafico.java):

package arrastrargrafico;

import javax.swing.WindowConstants;
import javax.swing.JFrame;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseEvent;

public class ArrastrarGrafico extends Canvas implements MouseMotionListener {

    private int xRectangulo = 0;
    private int yRectangulo = 0;
    private final int anchoRectangulo = 64;
    private final int altoRectangulo = 64;
    private int xAnteriorRaton;
    private int yAnteriorRaton;
    private boolean arrastrando = false;

    public static void main(String[] args) {
        JFrame v = new JFrame("Arrastrar Grafico");
        ArrastrarGrafico c = new ArrastrarGrafico();
        v.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        v.getContentPane().add(c);
        v.setVisible(true);
        v.pack();
    }

    public ArrastrarGrafico() {
        addMouseMotionListener(this);
    }

    private boolean estaDentro(MouseEvent e) {
        return (e.getX() > xRectangulo)
                && (e.getX() < (xRectangulo + anchoRectangulo))
                && (e.getY() > yRectangulo)
                && (e.getY() < (yRectangulo + altoRectangulo));
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(512, 512);
    }

    @Override
    public void paint(Graphics g) {
        g.setColor(Color.BLUE);
        g.fillRect(xRectangulo, yRectangulo, anchoRectangulo, altoRectangulo);
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        if (!arrastrando) {
            if (estaDentro(e)) {
                xAnteriorRaton = e.getX();
                yAnteriorRaton = e.getY();
                arrastrando = true;
            }
        } else {
            xRectangulo = (xRectangulo + e.getX()) - xAnteriorRaton;
            yRectangulo = (yRectangulo + e.getY()) - yAnteriorRaton;
            xAnteriorRaton = e.getX();
            yAnteriorRaton = e.getY();
            repaint();
        }
    }

    @Override
    public void mouseMoved(MouseEvent e) {
        arrastrando = false;
    }

}


Resultado:


miércoles, 12 de octubre de 2022

Conversor a código Braille. Uso de HashMap con matriz.

Braille es un sistema de lectura y escritura táctil pensado para personas ciegas.
Un carácter en Braile se puede representar por una matriz de puntos de tamaño 2x3.
Este algoritmo lo que hace es convertir una frase a código en Braille.


Código1 (CodigoBraille.java):

package codigobraille;

public class CodigoBraille {
    public static void main(String[] args) {
        Braille m = new Braille();
        m.braille();
    }
}


Código2 (Braille.java):

package codigobraille;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Scanner;
import javax.imageio.ImageIO;

public class Braille {

    HashMap<String, Boolean[][]> tablaCodigoBraille = new HashMap<>();

    public void braille() {
        tablaCodigoBraille = getTablaM();
        System.out.println("Escriba un mensaje a convertir a braille:");
        Scanner input = new Scanner(System.in);
        String mensaje = input.nextLine();

        //tamaño lienzo
        int res_x = 1024;
        int res_y = 1024;

        BufferedImage imagen = new BufferedImage(res_x, res_y, BufferedImage.TYPE_INT_RGB);
        Lienzo.Dibujar((Graphics2D) imagen.getGraphics(), res_x, res_y, mensaje, tablaCodigoBraille);
        try {
            ImageIO.write(imagen, "png", new File("Braille.png"));
        } catch (IOException e) {
        }
    }

    private static HashMap<String, Boolean[][]> getTablaM() {

        //tabla código braille español +- (2x3)
        HashMap<String, Boolean[][]> par = new HashMap<>();
        par.put(" ", new Boolean[][]{
            {false, false},
            {false, false},
            {false, false}});
        par.put("A", new Boolean[][]{
            {true, false},
            {false, false},
            {false, false}});
        par.put("B", new Boolean[][]{
            {true, false},
            {true, false},
            {false, false}});
        par.put("C", new Boolean[][]{
            {true, true},
            {false, false},
            {false, false}});
        par.put("D", new Boolean[][]{
            {true, true},
            {false, true},
            {false, false}});
        par.put("E", new Boolean[][]{
            {true, false},
            {false, true},
            {false, false}});
        par.put("F", new Boolean[][]{
            {true, true},
            {true, false},
            {false, false}});
        par.put("G", new Boolean[][]{
            {true, true},
            {true, true},
            {false, false}});
        par.put("H", new Boolean[][]{
            {true, false},
            {true, true},
            {false, false}});
        par.put("I", new Boolean[][]{
            {false, true},
            {true, false},
            {false, false}});
        par.put("J", new Boolean[][]{
            {false, true},
            {true, true},
            {false, false}});
        par.put("K", new Boolean[][]{
            {true, false},
            {false, false},
            {true, false}});
        par.put("L", new Boolean[][]{
            {true, false},
            {true, false},
            {true, false}});
        par.put("M", new Boolean[][]{
            {true, true},
            {false, false},
            {true, false}});
        par.put("N", new Boolean[][]{
            {true, true},
            {false, true},
            {true, false}});
        par.put("O", new Boolean[][]{
            {true, false},
            {false, true},
            {true, false}});
        par.put("P", new Boolean[][]{
            {true, true},
            {true, false},
            {true, false}});
        par.put("Q", new Boolean[][]{
            {true, true},
            {true, true},
            {true, false}});
        par.put("R", new Boolean[][]{
            {true, false},
            {true, true},
            {true, false}});
        par.put("S", new Boolean[][]{
            {false, true},
            {true, false},
            {true, false}});
        par.put("T", new Boolean[][]{
            {false, true},
            {true, true},
            {true, false}});
        par.put("U", new Boolean[][]{
            {true, false},
            {false, false},
            {true, true}});
        par.put("V", new Boolean[][]{
            {true, false},
            {true, false},
            {true, true}});
        par.put("W", new Boolean[][]{
            {false, true},
            {true, true},
            {false, true}});
        par.put("X", new Boolean[][]{
            {true, true},
            {false, false},
            {true, true}});
        par.put("Y", new Boolean[][]{
            {true, true},
            {false, true},
            {true, true}});
        par.put("Z", new Boolean[][]{
            {true, false},
            {false, true},
            {true, true}});
        par.put("&", new Boolean[][]{
            {true, true},
            {true, false},
            {true, true}});
        par.put(".", new Boolean[][]{
            {false, false},
            {false, false},
            {true, false}});
        par.put(",", new Boolean[][]{
            {false, false},
            {true, false},
            {false, false}});
        par.put("?", new Boolean[][]{
            {false, false},
            {true, false},
            {false, true}});
        par.put(":", new Boolean[][]{
            {false, false},
            {true, true},
            {false, false}});
        par.put(";", new Boolean[][]{
            {false, false},
            {true, false},
            {true, false}});
        par.put("!", new Boolean[][]{
            {false, false},
            {true, true},
            {true, false}});
        par.put("\"", new Boolean[][]{
            {false, false},
            {true, false},
            {true, true}});
        par.put("(", new Boolean[][]{
            {true, false},
            {true, false},
            {false, true}});
        par.put(")", new Boolean[][]{
            {false, true},
            {false, true},
            {true, false}});
        par.put("-", new Boolean[][]{
            {false, false},
            {false, false},
            {true, true}});
        par.put("*", new Boolean[][]{
            {false, false},
            {false, true},
            {true, false}});
        return par;
    }
}


Código3 (Lienzo.java):

package codigobraille;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.util.HashMap;

class Lienzo {

    static void Dibujar(Graphics2D g, int x, int y, String msg, HashMap<String, Boolean[][]> map) {

        //tamaño bloque
        int tCuadroX = 16;
        int tCuadroY = 16;
        int t = 10; //tamaño punto

        Boolean tmp[][] = new Boolean[3][2];

        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        //fondo blanco
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, x, y);

        //dibujar escritura Braille
        g.setColor(Color.black);
        int horizontal = 1, vertical = 3, limit = 0;
        for (int k = 0; k < msg.length(); k++) {
            //dibujar el caracter en braile
            tmp = map.get("" + msg.toUpperCase().charAt(k));
            for (int i = 0; i < 2; i++) {
                for (int j = 0; j < 3; j++) {
                    if (tmp[j][i]) {
                        g.fillOval(tCuadroX * (i + horizontal), tCuadroY * (j + vertical), t, t);
                    }
                }
            }            
            //ha llegado al limite de linea?
            if (limit++ >= 21) {
                horizontal = 1;
                vertical += 6;
                limit = 0;
            } else {
                horizontal += 3;
            }
        }
    }

}


Resultado:

run:
Escriba un mensaje a convertir a braille:
En un lugar de la Mancha, de cuyo nombre no quiero acordarme, no hace mucho tiempo que vivia un hidalgo de los de lanza en astillero, adarga antigua, rocin flaco y galgo corredor. (DON QUIJOTE DE LA MANCHA)
BUILD SUCCESSFUL (total time: 3 seconds)


sábado, 8 de octubre de 2022

Emitir notas musicales en formato sintetizado (midi).

Código (PruebaSonidoMidi.java):

package pruebasonidomidi;

import javax.sound.midi.MidiChannel;
import javax.sound.midi.MidiSystem;
import javax.sound.midi.Synthesizer;

public class PruebaSonidoMidi {

    public static void main(String[] args) {

        try {
            Synthesizer synth = MidiSystem.getSynthesizer();
            synth.open();
            MidiChannel[] channels = synth.getChannels();
            for (int i = 5; i < 100; i++) {
                channels[0].noteOn(i, 50);
                Thread.sleep(200);
            }
            synth.close();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}


domingo, 2 de octubre de 2022

Conversor a código Morse. Uso de HashMap.

Este algoritmo lo que hace es convertir una frase a código morse. Para ello hace uso de HashMap (un mapa de estructura de datos) para acceder a una "tabla" de códigos morse.
Una de las ventajas de uso de HashMap es que ofrece un acceso a datos más rápido que usando un arreglo.


Código 1 (CodigoMorse2.java):

package codigomorse2;

public class CodigoMorse2 {
    public static void main(String[] args) {
        Morse m = new Morse();
        m.morse();
    }
}


Código 2 (Morse.java):

package codigomorse2;

import java.util.HashMap;
import java.util.Scanner;

public class Morse {

    HashMap<String, String> tablaCodigoMorse = new HashMap<>();

    public void morse() {

        tablaCodigoMorse = getTabla();

        //añadir nuevos códigos morse a la tabla
        tablaCodigoMorse.put(" ", " ");
        tablaCodigoMorse.put(".", ".-.-.-");
        
        System.out.println("Escriba un mensaje a convertir:");
        Scanner input = new Scanner(System.in);
        String mensaje = input.nextLine();
        String strMorse = conversorStrToMorse(mensaje);

        //resultado
        System.out.println("\nEn morse:\n" + strMorse);

    }

    private String conversorStrToMorse(String frase) {
        String arrTmp[] = frase.split("");
        String morse = "";
        for (String arrTmp1 : arrTmp) {
            morse += tablaCodigoMorse.get(arrTmp1.toUpperCase()) + " ";
        }
        return morse;
    }

    private static HashMap<String, String> getTabla() {
        //tabla código morse internacional
        HashMap<String, String> par = new HashMap<>();
        par.put("A", ".-");
        par.put("B", "-...");
        par.put("C", "-.-.");
        par.put("D", "-..");
        par.put("E", ".");
        par.put("F", "..-.");
        par.put("G", "--.");
        par.put("H", "....");
        par.put("I", "..");
        par.put("J", ".---");
        par.put("K", "-.-");
        par.put("L", ".-..");
        par.put("M", "--");
        par.put("N", "-.");
        par.put("O", "---");
        par.put("P", ".--.");
        par.put("Q", "--.-");
        par.put("R", ".-.");
        par.put("S", "...");
        par.put("T", "-");
        par.put("U", "..-");
        par.put("V", "...-");
        par.put("W", ".--");
        par.put("X", "-..-");
        par.put("Y", "-.--");
        par.put("Z", "--..");
        par.put("0", "-----");
        par.put("1", ".----");
        par.put("2", "..---");
        par.put("3", "...--");
        par.put("4", "....-");
        par.put("5", ".....");
        par.put("6", "-....");
        par.put("7", "--...");
        par.put("8", "---..");
        par.put("9", "----.");
        return par;
    }

}


Resultado:

run:
Escriba un mensaje a convertir:
Esto es una prueba de codigo morse.

En morse:
. ... - ---   . ...   ..- -. .-   .--. .-. ..- . -... .-   -.. .   -.-. --- -.. .. --. ---   -- --- .-. ... . .-.-.-
BUILD SUCCESSFUL (total time: 15 seconds)


domingo, 25 de septiembre de 2022

Almacenar información alfanumérica en matriz gráfica. Tipo código Qr.

Código 1 (CodigoQR.java):

package codigoqr;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import javax.imageio.ImageIO;

public class CodigoQR {

    public static void main(String[] args) {

        //QR Bin
        String xyn = " abcdefghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUWXYZ0123456789!#$%&'()*+,-./:;<=>?@[]^_`{|}~";
        List<String> miLista = new ArrayList<>(Arrays.asList(xyn.split("")));
        String binaryString;
        String strCodigo;
        int pos;

        //input código de 8 caracteres        
        System.out.println("Introduce código (8 caracteres mínimo): ");
        Scanner input = new Scanner(System.in);
        strCodigo = input.nextLine();
        if (strCodigo.length() < 8) {
            strCodigo = "        " + strCodigo;
        } else if (strCodigo.length() > 8) {
            System.out.println("Sólo se registrarán los 8 primeros caracteres.");
        }

        //limitar a 8 carácteres máximo.
        strCodigo = strCodigo.substring(0, 8);
        System.out.println("Código registrado <" + strCodigo + ">");

        //generar código QR *** se puede eliminar Lista y Arrays?
        Boolean map[][] = new Boolean[8][8];
        for (int i = 0; i < map.length; i++) {
            pos = miLista.indexOf("" + strCodigo.charAt(i));

            //pasar a formato "binario"
            binaryString = "00000000" + Integer.toString(pos, 2);

            //pasar a formato 00000ABC
            binaryString = binaryString.substring(binaryString.length() - 8);

            //pasar a matriz boleana
            for (int j = 0; j < map.length; j++) {
                map[i][j] = binaryString.charAt(j) != '0';
            }
        }

        //dibujar código pre-QR (.png)
        int res_x = 256;
        int res_y = 256;
        BufferedImage imagen = new BufferedImage(res_x, res_y, BufferedImage.TYPE_INT_RGB);
        Lienzo.Dibujar((Graphics2D) imagen.getGraphics(), res_x, res_y, map);
        try {
            ImageIO.write(imagen, "png", new File("CodigoQR.png"));
        } catch (IOException e) {
        }
        
    }
}


Código 2 (Lienzo.java):

package codigoqr;

import java.awt.Color;
import java.awt.Graphics2D;

class Lienzo {

    static void Dibujar(Graphics2D g, int x, int y, Boolean[][] map) {

        //tamaño bloque
        int tCuadroX = x / 8;

        //fondo blanco
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, x, y);

        //dibujar bloques muro
        g.setColor(Color.black);
        for (int i = 0; i < map.length; i++) {
            for (int j = 0; j < map.length; j++) {
                if (map[j][i]) {
                    g.fillRect(tCuadroX * i, tCuadroX * j, tCuadroX, tCuadroX);
                }
            }
        }

        //rejilla
        g.setColor(Color.blue);
        for (int i = 0; i < x; i = i + tCuadroX) {
            g.drawLine(0, i, x, i); //horizontal
            g.drawLine(i, 0, i, x); //vertical
        }

    }
    
}


Resultado:

run:
Introduce código (8 caracteres mínimo):
E*7r@yHj0yHvwRI
Sólo se registrarán los 8 primeros caracteres.
Código registrado <E*7r@yHj>
BUILD SUCCESSFUL (total time: 3 seconds)




miércoles, 14 de septiembre de 2022

Circular a plano. Algoritmo sin uso práctico conocido.

Este algoritmo no tiene ningún uso práctico, sólo sirve para fines didácticos y apredizaje.
La premisa consiste en dibujar un máximo de dos pixeles por línea horizontal, línea vertical y línea diagonal.


Código 1 (Circular_a_Plano.java):

package circular_a_plano;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class Circular_a_Plano {

    public static void main(String[] args) {

        Boolean[][] map = new Boolean[32][32];

        //inicializar matrix
        for (int i = 0; i < map.length; i++) {
            for (int j = 0; j < map.length; j++) {
                map[j][i] = false;
            }
        }

        map[0][0] = true;
        map[1][1] = true;

        boolean X_libre = true, Y_libre = true;
        boolean Dx_libre = true;
        for (int y = 0; y < map.length; y++) {
            for (int x = 0; x < map.length; x++) {
                X_libre = comprobarX(y, map);
                Y_libre = comprobarY(x, map);
                Dx_libre = comprobarDx(x, y, map);

                if (X_libre && Y_libre && Dx_libre) {
                    map[x][y] = true;
                }
            }
        }
        
        Resultados(map);

        //tamaño lienzo
        int res_x = 1024;
        int res_y = 1024;

        BufferedImage imagen = new BufferedImage(res_x, res_y, BufferedImage.TYPE_INT_RGB);
        Lienzo.Dibujar((Graphics2D) imagen.getGraphics(), res_x, res_y, map);
        try {
            ImageIO.write(imagen, "png", new File("Laberinto.png"));
        } catch (IOException e) {
        }
    }

    private static boolean comprobarX(int y, Boolean[][] map) {
        //comprobación i
        int cont = 0;
        boolean libre = true;
        for (int i = 0; i < map.length; i++) {
            if (map[i][y]) {
                cont++;
            }
            if (cont >= 2) {
                libre = false;
                break;
            }
        }
        return libre;
    }

    private static boolean comprobarY(int x, Boolean[][] map) {
        //comprobación j
        int cont = 0;
        boolean libre = true;
        for (int i = 0; i < map.length; i++) {
            if (map[x][i]) {
                cont++;
            }
            if (cont >= 2) {
                libre = false;
                break;
            }
        }
        return libre;
    }

    private static boolean comprobarDx(int x, int y, Boolean[][] map) {
        //comprobación j
        int cont = 0;
        boolean libre = true;
        int aux = 0;
        if (x <= y) {
            aux = y - x;
            for (int i = 0; i < map.length - aux; i++) {
                if (map[i][aux + i]) {
                    cont++;
                }
            }
            if (cont >= 2) {
                libre = false; //¿funciona?
            }
        }
        if (x >= y) {
            aux = x - y;
            for (int i = 0; i < map.length - aux; i++) {
                if (map[aux + i][i]) {
                    cont++;
                }
            }
            if (cont >= 2) {
                libre = false; //¿funciona?
            }
        }
        return libre;
    }

    private static boolean comprobarDy(int x, int y, Boolean[][] map) {
        int cont = 0;
        int aux = 0;
        boolean libre = true;
        if (x < y) { //if x<y parcial resolve...
            for (int i = x - aux; i < map.length; i++) {
                if (map[i][(y + aux - cont)] || map[y - cont][i]) {
                    cont++;
                }
                if (cont >= 2) {
                    libre = false;
                    break;
                }
            }
        }
        return libre;
    }

    private static void Resultados(Boolean[][] map) {
        System.out.println("Resultado:\n");
        String libre = "";
        for (int i = 0; i < map.length; i++) {
            for (int j = 0; j < map.length; j++) {
                if (map[j][i]) {
                    libre = libre + "█";
                } else {
                    libre = libre + "·";
                }
            }
            libre = libre + ("\n");
        }
        System.out.println(libre);
    }

}


Código 2 (Lienzo.java):

package circular_a_plano;

import java.awt.Color;
import java.awt.Graphics2D;

class Lienzo {

    static void Dibujar(Graphics2D g, int x, int y, Boolean[][] map) {

        //tamaño bloque
        int tCuadroX = x / map.length;

        //fondo blanco
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, x, y);

        //rejilla
        g.setColor(Color.blue);
        for (int i = 0; i < x; i = i + tCuadroX) {
            g.drawLine(0, i, x, i); //horizontal
            g.drawLine(i, 0, i, x); //vertical
        }

        //dibujar bloques muro
        g.setColor(Color.black);
        for (int j = 0; j < map.length; j++) {
            for (int i = 0; i < map.length; i++) {
                if (map[i][j]) {
                    g.fillRect(tCuadroX * i, tCuadroX * j, tCuadroX, tCuadroX);
                }
            }
        }
    }

}


Resultado:


Con la tecnología de Blogger.