Descuento de otoño
Universidad de Java
Aprendizaje
Cursos
Tareas
Cuestionarios y controles
Juegos
Ayuda
Horario para collejas
Becarios
Comunidad
Usuarios
Foro
Chat
Artículos
Casos de éxito
Actividades
Comentarios
Suscripciones
Tema claro
Artículo
  • Comentarios
  • Sobre nosotros
  • CS50
Comenzar
Empezar a aprender
  • Artículos
  • Autores
  • Todos los grupos
  • Lista de todos los artículos
JavaRush /Blog de Java /Random-ES /Creando un "Cuadrado Mágico" en Java
Сергей Цехмистренко
Nivel 15
Минск
  • 28 febrero 2021
  • 477 views
  • 0 comments

Creando un "Cuadrado Mágico" en Java

Publicado en el grupo Random-ES
Java-университет
Un cuadrado mágico de orden n es una matriz cuadrada de tamaño nxn, compuesta por los números 1, 2, 3, ..., n^2 de modo que las sumas de cada columna, cada fila y cada una de las dos diagonales grandes son iguales. . Lo primero que recordé fue Sudoku :) Creando un "Cuadrado Mágico" en Java - 1enlace de Wikipedia , para aquellos que no entienden. Después de experimentar creando mis propios algoritmos de llenado, llegué a la conclusión de que no podría hacerlo sin la ayuda de otras personas. Por lo tanto, después de pasar por una docena de enlaces, implementé 3 algoritmos, que en total implementan el llenado de cualquier matriz de dimensión "n". Al comienzo del código puede encontrar comentarios sobre los métodos que se utilizarán a continuación. Los enlaces a algoritmos y otros comentarios (¿útiles?) se pueden encontrar en el cuerpo de los métodos correspondientes. Estoy en Telegram: @sergey3ts Y Linkedin, por supuesto (Agrégate, esto es importante para mí :)
// magicSquareOfOddOrder(int n);       метод для n нечетной размерности (3, 7, 9, и тд)
 // magicSquareOfEvenOddOrder(int n);   метод для n четно-нечетной размерности (n кратно 2 но не крастно 4)
 // magicSquareOfEvenOddOrder(int n);   метод для n четн-четной размерности (n кратно и 2 и 4);
 // magicSquare(int n);                 общий метод, который определяет кратность n и вызывает соотв. метод

 // Вспомогательные методы
 // standardMatrixFillingAscending(n); заполняет матрицу от 1 по возростанию
 // standardMatrixFillingDescending(n); заполняет матрицу от n*n по убыванию

 // Извиняюсь за косяки в códigoе (непонятные переменные(возможно(нет(да)))) :)
public class MatrixSolution16 {
    public static void main(String[] args) {
        magicSquare(6);
    }
   public static int [][] magicSquare(int n) {
        if (n % 2 !=0) return magicSquareOfOddOrder(n);             // метод для n нечетной размерности (3, 7, 9, и тд)
        else if (n % 4 != 0) return magicSquareOfEvenOddOrder(n);   // метод для n четно-нечетной размерности (n кратно 2 но не кратно 4)
        return magicSquareOfEvenOddOrder(n);                        // метод для n четн-четной размерности (n кратно и 2 и 4);
    }
   private static int[][] magicSquareOfOddOrder(int n) {
        // "Сиамский метод" - один из самых просты для восприятия
        // https://ru.xcv.wiki/wiki/Siamese_method
        // Оставлю без комментариев (gif по ссылке наглядно показывает Cómo он работает)
        // código не сложный
        int[][] matrix = new int[n][n];
        for (int i = 0; i < n; i++) {
            Arrays.fill(matrix[i], 0);
        }
        int count = 1, y = 0, x = matrix.length/2;
        while (true){
            matrix[y][x] = count;

            count++;
            if (((y == 0) && (x >= n-1)) && (matrix[n-1][0] != 0)){
                y++;
            }
            else {
                y--;
                if (y < 0) {
                    y = n - 1;
                }
                x++;
                if (x == n) {
                    x = 0;
                }
                if(matrix[y][x]!=0){
                    y+=2;
                    x--;
                }
            }

            if(count==n*n+1) break;
        }
        return matrix;
    }
   private static int[][] magicSquareOfEvenOddOrder(int n) {
        // Метод "анонима" спасибо человеку, который его придумал
        // Вот enlace на подробное описание метода http://www.klassikpoez.narod.ru/mojmetod.htm
        // Оставлю этот código без комментариев уж очень он большой
        // Надеюсь прочитав описание метода сможете понять(o нет?)
        int half = n/2;

        int[][] matrix = new int[n][n];
        int[][] tempMatrix;
        tempMatrix = magicSquareOfOddOrder(half);

        // 1/4 матрицы
        for (int i = 0; i < half; i++) {
            for (int j = 0; j < half; j++) {
                matrix[i][j] = tempMatrix[i][j];
            }
        }
        // 2/4 матрицы
        for (int i = 0; i < half; i++) {
            for (int j = half; j < n; j++) {
                int x = j-half;
                matrix[i][j] = (tempMatrix[i][x]+2*half*half);
            }
        }
        // 3/4 матрицы
        for (int i = half; i < n; i++) {
            for (int j = 0; j < half; j++) {
                int x = i-half;

                matrix[i][j] = (tempMatrix[x][j]+3*half*half);
            }
        }
        // 4/4 матрицы
        for (int i = half; i < n; i++) {
            for (int j = half; j < n; j++) {
                int x = i-half, y = j-half;
                matrix[i][j] = (tempMatrix[x][y]+half*half);
            }
        }
        int move = 0;
        for (int i = 6; i < n; i++) {
            if((i%4!=0)&&(i%2==0)) move++;
        }
        for (int j = matrix.length/2-move; j <= matrix.length/2+move-1; j++) {
            for (int i = 0; i < tempMatrix.length; i++) {

                int key = matrix[i][j];
                matrix[i][j] = matrix[half+i][j];
                matrix[half+i][j] = key;
            }
        }
        for (int j = 0; j <= 1; j++) {
            if (j == 0) {
                int key = matrix[0][0];
                matrix[0][0] = matrix[half][0];
                matrix[half][0] = key;
            }
            if (j == 1) {
                int key = matrix[half - 1][0];
                matrix[half - 1][0] = matrix[n - 1][0];
                matrix[n - 1][0] = key;
            }
        }
        for (int j = half+1; j < n-1; j++) {
            for (int i = 1; i < half-1; i++) {
                int key = matrix[i][1];
                matrix[i][1] = matrix[half+i][1];
                matrix[half+i][1] = key;
            }
        }
        return matrix;
    }
    private static int[][] evenMatrixSquare(int n){
        // Метод Раус-Болла хорошое описание нашел тут:
        // https://rep.bntu.by/bitstream/handle/data/62327/Magicheskie_kvadraty.pdf?sequence=1&isAllowed=y
        // Страница 8, 9
        int[][] matrix = WorkWithMatrix.standardMatrixFillingAscending(n);
        int[][] tempMatrix = WorkWithMatrix.standardMatrixFillingDescending(n);

        int size = 4;    // Размерность каждого квадрата (4х4 тафтология)
                         // можно заменить простой цифрой
        int x = 0;       // x, y - движение по кадратам (посмотрите Cómo изменяются в ходе программы)
        int y = 0;
        for (int i = 0; i < (n*n/16); i++) {                // Смотрим сколько квадратов 4х4 помещается в матрице nxn
            if (x == (int)Math.sqrt(n*n/16)) {              // x, y переменные для движения по квадратам 4х4
                                                            // х проходит по первому ряду квадратов, достигая последнего
                                                            // обнуляется, а y увеличивается
                x = 0;
                y++;
            }
            // x и y должны лишь обеспечивать проход по квадратам
            for (int j = 0; j < 4; j++) {
                matrix[size*y+j][size*x+j] = tempMatrix[size*y+j][size*x+j];  // главная диагональ квадратов 4х4
                matrix[size*y+j][size*x+size-1-j] = tempMatrix[size*y+j][size*x+size-1-j]; // побочная диагональ
            }
            x++;
        }
        return matrix;
    }
}
Telegram
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION
Aprender
  • Курси програмування
  • Registro
  • Curso de Java
  • Ayuda con las tareas
  • Precios
  • Proyectos de juegos
Comunidad
  • Usuarios
  • Artículos
  • Foro
  • Chat
  • Casos de éxito
  • Actividades
Empresa
  • Información sobre nosotros
  • Contactos
  • Comentarios
  • Preguntas frecuentes
  • Soporte
JavaRush JavaRush es un curso por Internet para aprender programación en Java desde cero. Este curso es la manera perfecta para que los principiantes dominen Java. Ofrece más de 1200 tareas con comprobación instantánea y contenidos teóricos esenciales sobre los fundamentos de Java. Para ayudarte a triunfar en tu formación, hemos implementado una serie de características motivadoras: controles, proyectos de programación y contenidos sobre aprendizaje eficiente y para tu carrera profesional como desarrollador Java.
Síguenos
Los programadores no nacen, se hacen © 2025 JavaRush
Descargar aplicación
  • Google Play
  • App Store
Mastercard Visa
Los programadores no nacen, se hacen © 2025 JavaRush