En este ejemplo, el programa genera un número aleatorio entre 1 y 100 y le da al usuario un máximo de 10 intentos para adivinar el número correcto. Cada vez que el usuario ingresa un número, el programa verifica si es mayor o menor que el número aleatorio y proporciona una pista.
Código Java (AdivinaNumero.java):
import java.util.Random;
import java.util.Scanner;
public class AdivinaNumero {
public static void main(String[] args) {
Random rand = new Random();
int numeroAleatorio = rand.nextInt(100) + 1; // Genera un numero aleatorio entre 1 y 100
Scanner sc = new Scanner(System.in);
int intentos = 0;
int numeroIngresado = 0;
while (intentos < 10) { // El usuario tiene un maximo de 10 intentos
System.out.print("Adivina el numero (entre 1 y 100): ");
numeroIngresado = sc.nextInt();
intentos++;
if (numeroIngresado == numeroAleatorio) { // Si el usuario adivina el numero, sale del loop
System.out.println("Felicidades! Adivinaste el numero en " + intentos + " intentos.");
break;
} else if (numeroIngresado < numeroAleatorio) {
System.out.println("El numero es mayor.");
} else {
System.out.println("El numero es menor.");
}
}
if (intentos == 10) { // Si el usuario agota sus 10 intentos, muestra el numero aleatorio
System.out.println("Lo siento, agotaste tus intentos. El numero era " + numeroAleatorio + ".");
}
}
}
Resultado:
Adivina el numero (entre 1 y 100): 50
El numero es menor.
Adivina el numero (entre 1 y 100): 25
El numero es mayor.
Adivina el numero (entre 1 y 100): 42
El numero es menor.
Adivina el numero (entre 1 y 100): 35
Felicidades! Adivinaste el numero en 4 intentos.
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
viernes, 14 de abril de 2023
Juegos I. Guess the number.
lunes, 27 de marzo de 2023
El autómata de clase 4. Patrón 110.
El autómata celular unidimensional basado en la regla 110 de Stephen Wolfram, es un sistema de evolución discreto que sigue reglas simples para generar patrones complejos a partir de una serie inicial de células.
El ejemplo de autómata de clase 4 aquí descrito, produce patrones complejos y no periódicos que pueden ser difíciles de predecir. Estos patrones pueden tener aplicaciones en la generación de números pseudoaleatorios, criptografía y en simulación de sistemas complejos.
Código Java (Regla110.java):
public class Regla110 {
public static void main(String[] args) {
int[] cells = new int[64];
cells[cells.length / 2] = 1;
int[] newCells = new int[cells.length];
for (int t = 0; t < 32; t++) {
printCells(cells);
for (int i = 1; i < cells.length - 1; i++) {
int left = cells[i - 1];
int center = cells[i];
int right = cells[i + 1];
newCells[i] = applyRule110(left, center, right);
}
System.arraycopy(newCells, 0, cells, 0, cells.length);
}
}
private static void printCells(int[] cells) {
for (int cell : cells) {
System.out.print(cell == 0 ? "." : "┼");
}
System.out.println();
}
private static int applyRule110(int left, int center, int right) {
int rule = (left << 2) | (center << 1) | right;
int rule110 = 0b01110110;
return (rule110 >> rule) & 1;
}
}
Resultado:
run:
................................┼...............................
...............................┼┼┼..............................
..............................┼..┼┼.............................
.............................┼┼┼┼.┼┼............................
............................┼...┼┼.┼┼...........................
...........................┼┼┼.┼.┼┼.┼┼..........................
..........................┼..┼┼┼┼.┼┼.┼┼.........................
.........................┼┼┼┼...┼┼.┼┼.┼┼........................
........................┼...┼┼.┼.┼┼.┼┼.┼┼.......................
.......................┼┼┼.┼.┼┼┼┼.┼┼.┼┼.┼┼......................
......................┼..┼┼┼┼...┼┼.┼┼.┼┼.┼┼.....................
.....................┼┼┼┼...┼┼.┼.┼┼.┼┼.┼┼.┼┼....................
....................┼...┼┼.┼.┼┼┼┼.┼┼.┼┼.┼┼.┼┼...................
...................┼┼┼.┼.┼┼┼┼...┼┼.┼┼.┼┼.┼┼.┼┼..................
..................┼..┼┼┼┼...┼┼.┼.┼┼.┼┼.┼┼.┼┼.┼┼.................
.................┼┼┼┼...┼┼.┼.┼┼┼┼.┼┼.┼┼.┼┼.┼┼.┼┼................
................┼...┼┼.┼.┼┼┼┼...┼┼.┼┼.┼┼.┼┼.┼┼.┼┼...............
...............┼┼┼.┼.┼┼┼┼...┼┼.┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼..............
..............┼..┼┼┼┼...┼┼.┼.┼┼┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.............
.............┼┼┼┼...┼┼.┼.┼┼┼┼...┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼............
............┼...┼┼.┼.┼┼┼┼...┼┼.┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼...........
...........┼┼┼.┼.┼┼┼┼...┼┼.┼.┼┼┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼..........
..........┼..┼┼┼┼...┼┼.┼.┼┼┼┼...┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.........
.........┼┼┼┼...┼┼.┼.┼┼┼┼...┼┼.┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼........
........┼...┼┼.┼.┼┼┼┼...┼┼.┼.┼┼┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.......
.......┼┼┼.┼.┼┼┼┼...┼┼.┼.┼┼┼┼...┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼......
......┼..┼┼┼┼...┼┼.┼.┼┼┼┼...┼┼.┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.....
.....┼┼┼┼...┼┼.┼.┼┼┼┼...┼┼.┼.┼┼┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼....
....┼...┼┼.┼.┼┼┼┼...┼┼.┼.┼┼┼┼...┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼...
...┼┼┼.┼.┼┼┼┼...┼┼.┼.┼┼┼┼...┼┼.┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼..
..┼..┼┼┼┼...┼┼.┼.┼┼┼┼...┼┼.┼.┼┼┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.
.┼┼┼┼...┼┼.┼.┼┼┼┼...┼┼.┼.┼┼┼┼...┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼┼.┼.
BUILD SUCCESSFUL (total time: 0 seconds)
martes, 14 de febrero de 2023
Espirales. Graficar Espiral de Fermat.
La espiral de Fermat es una curva logarítmica que se describe mediante una ecuación polar. Esta espiral se caracteriza por tener radios que se expanden logarítmicamente con respecto al ángulo polar. La ecuación de la espiral de Fermat es:
r = a * t^(1/n)
r: Distancia del origen a un punto en la espiral.
a: Constante positiva. Controla la tasa de expansión de los radios en la espiral.
t: Ángulo polar.
n: Exponente de la constante. Determina el grado de curvatura de la espiral y cómo se relaciona con el ángulo polar.
Código Java (FermatSpiral.java):
package fermatspiral;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Line2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class FermatSpiral extends JPanel {
private static final long serialVersionUID = 1L;
private static final int MAX_ITER = 512;
private static final double SCALE = 80;
private static final double A = 1;
private static final int N = 3;
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.translate(getWidth() / 2, getHeight() / 2);
float lineWidth = 0.1f;
double theta = 0;
double r;
g2d.setColor(Color.BLUE);
double x1 = 0, y1 = 0, x2, y2;
for (int i = 0; i < MAX_ITER; i++) {
r = A * Math.pow(theta, 1.0 / N);
x2 = SCALE * r * Math.cos(theta);
y2 = SCALE * r * Math.sin(theta);
g2d.setStroke(new BasicStroke(lineWidth));
g2d.draw(new Line2D.Double(x1, y1, x2, y2));
theta += 0.1;
lineWidth += 0.01;
x1 = x2;
y1 = y2;
}
}
public static void main(String[] args) {
JFrame frame = new JFrame("Spiral Fermat");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new FermatSpiral());
frame.setSize(new Dimension(800, 800));
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
Resultado:
domingo, 12 de febrero de 2023
Espirales. Graficar Espiral de Arquímedes.
La espiral de Arquímedes es una curva matemática que se genera mediante la rotación de una recta alrededor de un punto fijo.
Código Java (ArquimedesSpiral.java):
package arquimedesspiral;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class ArquimedesSpiral extends JComponent {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
int width = getWidth();
int height = getHeight();
g2d.translate(width / 2, height / 2);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
double t = 0.1;
double a = 5;
int x1 = 0;
int y1 = 0;
g2d.setColor(Color.BLUE);
for (int i = 0; i <= 500; i++) {
int x2 = (int) (a * t * Math.cos(t));
int y2 = (int) (a * t * Math.sin(t));
g2d.setStroke(new BasicStroke((float) i / 100));
g2d.drawLine(x1, y1, x2, y2);
x1 = x2;
y1 = y2;
t += 0.1;
}
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new ArquimedesSpiral());
frame.setSize(800, 800);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
Resultado:
Espirales. Graficar Espiral Logarítmica.
La espiral logarítmica es una curva matemática que se genera a partir de la relación logarítmica entre su distancia radial y su ángulo polar.
Código java (LogarithmicSpiral.java):
package logarithmicspiral;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class LogarithmicSpiral extends JComponent {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
int width = getWidth();
int height = getHeight();
g2d.translate(width / 2, height / 2);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
double theta = 0.5;
double a = 1;
double b = 0.12;
int x1 = 0;
int y1 = 0;
g2d.setColor(Color.BLUE);
for (int i = 0; i <= 500; i++) {
double r = a * Math.exp(b * theta);
int x2 = (int) (r * Math.cos(theta));
int y2 = (int) (r * Math.sin(theta));
g2d.setStroke(new BasicStroke((float) i / 100));
g2d.drawLine(x1, y1, x2, y2);
x1 = x2;
y1 = y2;
theta += 0.1;
}
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new LogarithmicSpiral());
frame.setSize(800, 800);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
Resultado:
sábado, 28 de enero de 2023
Permutaciones. Algoritmo lexicográfico.
El algoritmo lexicográfico es un algoritmo de generación de permutaciones que genera todas las permutaciones de un conjunto de elementos en orden lexicográfico. Es similar al algoritmo de Heap, pero en lugar de usar una estructura de datos específica, utiliza una técnica de backtracking para generar las permutaciones. Tiene una complejidad temporal de O(n! * n).
Código Java (LexicographicPermutation.java):
import java.util.Arrays;
public class LexicographicPermutation {
private static int[] elements = {1, 2, 3, 4, 5, 6, 7, 8};
private static boolean[] used = new boolean[elements.length];
public static void main(String[] args) {
lexicographicPermutation(new int[elements.length], 0);
}
private static void lexicographicPermutation(int[] permutation, int index) {
if (index == elements.length) {
System.out.println(Arrays.toString(permutation));
return;
}
for (int i = 0; i < elements.length; i++) {
if (!used[i]) {
used[i] = true;
permutation[index] = elements[i];
lexicographicPermutation(permutation, index + 1);
used[i] = false;
}
}
}
}
Resultado:
[1, 2, 3, 4]
[1, 2, 4, 3]
[1, 3, 2, 4]
[1, 3, 4, 2]
[1, 4, 2, 3]
[1, 4, 3, 2]
[2, 1, 3, 4]
[2, 1, 4, 3]
[2, 3, 1, 4]
[2, 3, 4, 1]
[2, 4, 1, 3]
[2, 4, 3, 1]
[3, 1, 2, 4]
[3, 1, 4, 2]
[3, 2, 1, 4]
[3, 2, 4, 1]
[3, 4, 1, 2]
[3, 4, 2, 1]
[4, 1, 2, 3]
[4, 1, 3, 2]
[4, 2, 1, 3]
[4, 2, 3, 1]
[4, 3, 1, 2]
[4, 3, 2, 1]
Permutaciones. Algoritmo de Heap.
Código Java (HeapPermutation.java):
import java.util.Arrays;
public class HeapPermutation {
private static int[] elements = {1, 2, 3, 4};
public static void main(String[] args) {
heapPermutation(elements.length);
}
private static void heapPermutation(int size) {
if (size == 1) {
System.out.println(Arrays.toString(elements));
return;
}
for (int i = 0; i < size; i++) {
heapPermutation(size - 1);
if (size % 2 == 1) {
int temp = elements[0];
elements[0] = elements[size - 1];
elements[size - 1] = temp;
} else {
int temp = elements[i];
elements[i] = elements[size - 1];
elements[size - 1] = temp;
}
}
}
}
Resultado:
[1, 2, 3, 4]
[2, 1, 3, 4]
[3, 1, 2, 4]
[1, 3, 2, 4]
[2, 3, 1, 4]
[3, 2, 1, 4]
[4, 2, 3, 1]
[2, 4, 3, 1]
[3, 4, 2, 1]
[4, 3, 2, 1]
[2, 3, 4, 1]
[3, 2, 4, 1]
[4, 1, 3, 2]
[1, 4, 3, 2]
[3, 4, 1, 2]
[4, 3, 1, 2]
[1, 3, 4, 2]
[3, 1, 4, 2]
[4, 1, 2, 3]
[1, 4, 2, 3]
[2, 4, 1, 3]
[4, 2, 1, 3]
[1, 2, 4, 3]
[2, 1, 4, 3]
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 (IV). 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)