BAEL-6813: Creating a Magic Square in Java (#14572)

This commit is contained in:
Graham Cox 2023-08-11 11:57:48 +01:00 committed by GitHub
parent 7e60be5c2b
commit 005d84d780
5 changed files with 292 additions and 0 deletions

View File

@ -0,0 +1,39 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>core-java-leetcode</artifactId>
<name>core-java-leetcode</name>
<packaging>jar</packaging>
<parent>
<groupId>com.baeldung</groupId>
<artifactId>parent-modules</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../../pom.xml</relativePath>
</parent>
<dependencies>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>${maven.compiler.source.version}</source>
<target>${maven.compiler.target.version}</target>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<maven.compiler.source.version>11</maven.compiler.source.version>
<maven.compiler.target.version>11</maven.compiler.target.version>
</properties>
</project>

View File

@ -0,0 +1,45 @@
package com.baeldung.leetcode.magicsquare;
import org.junit.jupiter.api.Test;
public class GenerationUnitTest {
@Test
public void testGenerate3x3() {
MagicSquare magicSquare = new MagicSquare(3);
System.out.println(magicSquare);
magicSquare.validate();
}
@Test
public void testGenerate9x9() {
MagicSquare magicSquare = new MagicSquare(9);
System.out.println(magicSquare);
magicSquare.validate();
}
@Test
public void testGenerate12x12() {
MagicSquare magicSquare = new MagicSquare(12);
System.out.println(magicSquare);
magicSquare.validate();
}
@Test
public void testGenerate10x10() {
MagicSquare magicSquare = new MagicSquare(10);
System.out.println(magicSquare);
magicSquare.validate();
}
@Test
public void testGenerate18x18() {
MagicSquare magicSquare = new MagicSquare(18);
System.out.println(magicSquare);
magicSquare.validate();
}
}

View File

@ -0,0 +1,186 @@
package com.baeldung.leetcode.magicsquare;
import org.junit.platform.commons.util.StringUtils;
import java.util.stream.IntStream;
public class MagicSquare {
private int[][] cells;
public MagicSquare(int n) {
this.cells = new int[n][];
for (int i = 0; i < n; ++i) {
this.cells[i] = new int[n];
}
if (n % 2 == 1) {
populateOdd();
} else if (n % 4 == 0) {
populateDoubleEven();
} else if (n >= 6) {
populateSingleEven();
}
}
private void populateOdd() {
int n = getN();
populateOddArea(0, 0, n, 0);
}
private void populateOddArea(int xOffset, int yOffset, int n, int numberOffset) {
int y = 0;
int x = (n - 1) / 2;
setCell(xOffset + x, yOffset + y, numberOffset + 1);
for (int number = 2; number <= n * n; ++number) {
int nextX = x + 1;
if (nextX == n) {
nextX = 0;
}
int nextY = y - 1;
if (nextY == -1) {
nextY = n - 1;
}
if (getCell(xOffset + nextX, yOffset + nextY) != 0) {
nextX = x;
nextY = y + 1;
if (nextY == n) {
nextY = 0;
}
}
setCell(xOffset + nextX, yOffset + nextY, numberOffset + number);
x = nextX;
y = nextY;
}
}
private void populateDoubleEven() {
int n = getN();
int number = 1;
for (int y = 0; y < n; ++y) {
for (int x = 0; x < n; ++x) {
boolean highlighted = false;
if ((y < n/4 || y >= 3*n/4) && (x >= n/4 && x < 3*n/4)) {
highlighted = true;
} else if ((x < n/4 || x >= 3*n/4) && (y >= n/4 && y < 3*n/4)) {
highlighted = true;
}
if (highlighted) {
setCell(x, y, (n * n) - number + 1);
} else {
setCell(x, y, number);
}
number += 1;
}
}
}
private void populateSingleEven() {
int n = getN();
int halfN = n/2;
int swapSize = (int) n/4;
populateOddArea(0, 0, halfN, 0);
populateOddArea(halfN, halfN, halfN, halfN * halfN);
populateOddArea(halfN, 0, halfN, (halfN * halfN) * 2);
populateOddArea(0, halfN, halfN, (halfN * halfN) * 3);
for (int x = 0; x < swapSize; ++x) {
swapCells(x, 0, x, halfN);
swapCells(x, halfN - 1, x, n - 1);
for (int y = 1; y < halfN - 1; ++y) {
swapCells(x + 1, y, x + 1, y + halfN);
}
}
for (int x = 0; x < swapSize - 1; ++x) {
for (int y = 0; y < halfN; ++y) {
swapCells(n - x - 1, y, n - x - 1, y + halfN);
}
}
}
private void swapCells(int x1, int y1, int x2, int y2) {
int cell1 = getCell(x1, y1);
int cell2 = getCell(x2, y2);
setCell(x1, y1, cell2);
setCell(x2, y2, cell1);
}
public int getN() {
return cells.length;
}
public int getCell(int x, int y) {
return cells[x][y];
}
public void setCell(int x, int y, int value) {
cells[x][y] = value;
}
public void validate() {
int n = getN();
int expectedValue = ((n * n * n) + n) / 2;
// Diagonals
if (IntStream.range(0, n).map(i -> getCell(i, i)).sum() != expectedValue) {
throw new IllegalStateException("Leading diagonal is not the expected value");
}
if (IntStream.range(0, n).map(i -> getCell(i, n - i - 1)).sum() != expectedValue) {
throw new IllegalStateException("Trailing diagonal is not the expected value");
}
// Rows
IntStream.range(0, n).forEach(y -> {
if (IntStream.range(0, n).map(x -> getCell(x, y)).sum() != expectedValue) {
throw new IllegalStateException("Row is not the expected value");
}
});
// Cols
IntStream.range(0, n).forEach(x -> {
if (IntStream.range(0, n).map(y -> getCell(x, y)).sum() != expectedValue) {
throw new IllegalStateException("Column is not the expected value");
}
});
}
public String toString() {
int n = getN();
int largestNumberLength = Integer.toString(n * n).length();
String formatString = " %0" + largestNumberLength + "d ";
StringBuilder sb = new StringBuilder();
for (int y = 0; y < n; ++y) {
for (int x = 0; x < n; ++x) {
int value = getCell(x, y);
if (value == 0) {
sb.append(" ");
sb.append(".".repeat(largestNumberLength));
sb.append(" ");
} else {
sb.append(String.format(formatString, value));
}
}
sb.append("\n");
}
return sb.toString();
}
}

View File

@ -0,0 +1,21 @@
package com.baeldung.leetcode.magicsquare;
import org.junit.jupiter.api.Test;
public class ValidationUnitTest {
@Test
public void testValidate3x3() {
MagicSquare magicSquare = new MagicSquare(3);
magicSquare.setCell(0, 0, 8);
magicSquare.setCell(1, 0, 1);
magicSquare.setCell(2, 0, 6);
magicSquare.setCell(0, 1, 3);
magicSquare.setCell(1, 1, 5);
magicSquare.setCell(2, 1, 7);
magicSquare.setCell(0, 2, 4);
magicSquare.setCell(1, 2, 9);
magicSquare.setCell(2, 2, 2);
magicSquare.validate();
}
}

View File

@ -108,6 +108,7 @@
<module>core-java-lang-operators-2</module>
<module>core-java-lang-syntax</module>
<module>core-java-lang-syntax-2</module>
<module>core-java-leetcode</module>
<module>core-java-locale</module>
<module>core-java-networking</module>
<module>core-java-networking-2</module>