diff --git a/src/main/java/com/thealgorithms/matrix/SpiralMatrixII.java b/src/main/java/com/thealgorithms/matrix/SpiralMatrixII.java new file mode 100644 index 000000000000..287d22b4a968 --- /dev/null +++ b/src/main/java/com/thealgorithms/matrix/SpiralMatrixII.java @@ -0,0 +1,52 @@ +/** + * Spiral Matrix II + * Generates an n x n matrix filled with numbers from 1 to n^2 in spiral order. + * + * @see LeetCode – Spiral Matrix II + * @see Wikipedia – Spiral Matrix + */ +package com.thealgorithms.matrix; +public class SpiralMatrixII { + + public int[][] generateMatrix(int n) { + + int[][] matrix = new int[n][n]; + + int top = 0; + int bottom = n - 1; + + int left = 0; + int right = n - 1; + + int num = 1; + + while (top <= bottom && left <= right) { + + for (int i = left; i <= right; i++) { + matrix[top][i] = num++; + } + top++; + + for (int i = top; i <= bottom; i++) { + matrix[i][right] = num++; + } + right--; + + if (top <= bottom) { + for (int i = right; i >= left; i--) { + matrix[bottom][i] = num++; + } + bottom--; + } + + if (left <= right) { + for (int i = bottom; i >= top; i--) { + matrix[i][left] = num++; + } + left++; + } + } + + return matrix; + } +} diff --git a/src/main/java/com/thealgorithms/stacks/BasicCalculatorUsingStack.java b/src/main/java/com/thealgorithms/stacks/BasicCalculatorUsingStack.java new file mode 100644 index 000000000000..bf04309f73e4 --- /dev/null +++ b/src/main/java/com/thealgorithms/stacks/BasicCalculatorUsingStack.java @@ -0,0 +1,90 @@ +package com.thealgorithms.stacks; + +import java.util.Stack; + +/** + * Utility class to evaluate a basic arithmetic expression containing + * non-negative integers, '+', '-', parentheses '(', ')', and spaces. + * + *

The evaluation is done using two stacks: + * one for operands and one for operators. + * + *

This class cannot be instantiated.

+ */ +public final class BasicCalculatorUsingStack { + + private BasicCalculatorUsingStack() { + } + + /** + * Evaluates a mathematical expression. + * + * @param expression the input expression + * @return the evaluated result + * @throws IllegalArgumentException if the expression is null or empty + */ + public static int evaluate(String expression) { + if (expression == null || expression.isEmpty()) { + throw new IllegalArgumentException("Expression must not be null or empty."); + } + + Stack operands = new Stack<>(); + Stack operators = new Stack<>(); + + for (int i = 0; i < expression.length(); i++) { + char current = expression.charAt(i); + + if (current == ' ') { + continue; + } + + if (Character.isDigit(current)) { + int number = 0; + while (i < expression.length() && Character.isDigit(expression.charAt(i))) { + number = number * 10 + (expression.charAt(i) - '0'); + i++; + } + i--; + operands.push(number); + } else if (current == '(') { + operators.push(current); + } else if (current == ')') { + while (!operators.isEmpty() && operators.peek() != '(') { + applyOperation(operands, operators); + } + operators.pop(); // remove '(' + } else if (current == '+' || current == '-') { + if (isUnaryMinus(expression, i)) { + operands.push(0); + } + while (!operators.isEmpty() && operators.peek() != '(') { + applyOperation(operands, operators); + } + operators.push(current); + } + } + + while (!operators.isEmpty()) { + applyOperation(operands, operators); + } + + return operands.pop(); + } + + private static void applyOperation(Stack operands, Stack operators) { + int b = operands.pop(); + int a = operands.pop(); + char operator = operators.pop(); + operands.push(operator == '+' ? a + b : a - b); + } + + private static boolean isUnaryMinus(String expression, int index) { + int j = index - 1; + while (j >= 0 && expression.charAt(j) == ' ') { + j--; + } + return j < 0 || expression.charAt(j) == '(' + || expression.charAt(j) == '+' + || expression.charAt(j) == '-'; + } +} diff --git a/src/main/java/com/thealgorithms/stacks/BasicCalculatorUsingStackTest.java b/src/main/java/com/thealgorithms/stacks/BasicCalculatorUsingStackTest.java new file mode 100644 index 000000000000..b179df876228 --- /dev/null +++ b/src/main/java/com/thealgorithms/stacks/BasicCalculatorUsingStackTest.java @@ -0,0 +1,42 @@ +package com.thealgorithms.stacks; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +class BasicCalculatorUsingStackTest { + + @Test + void testSimpleAddition() { + assertEquals(5, BasicCalculatorUsingStack.evaluate("2 + 3")); + } + + @Test + void testSimpleSubtraction() { + assertEquals(1, BasicCalculatorUsingStack.evaluate("3 - 2")); + } + + @Test + void testWithParentheses() { + assertEquals(23, BasicCalculatorUsingStack.evaluate("(1 + (4 + 5 + 2) - 3) + (6 + 8)")); + } + + @Test + void testUnaryMinus() { + assertEquals(-2, BasicCalculatorUsingStack.evaluate("-2")); + assertEquals(1, BasicCalculatorUsingStack.evaluate("1 - (-2)")); + } + + @Test + void testSpacesInExpression() { + assertEquals(3, BasicCalculatorUsingStack.evaluate(" 2 + 1 ")); + } + + @Test + void testInvalidExpression() { + IllegalArgumentException exception = + assertThrows(IllegalArgumentException.class, () -> BasicCalculatorUsingStack.evaluate("")); + assertEquals("Expression must not be null or empty.", exception.getMessage()); + } +} diff --git a/src/test/java/com/thealgorithms/matrix/SpiralMatrixIITest.java b/src/test/java/com/thealgorithms/matrix/SpiralMatrixIITest.java new file mode 100644 index 000000000000..f25d452d8f97 --- /dev/null +++ b/src/test/java/com/thealgorithms/matrix/SpiralMatrixIITest.java @@ -0,0 +1,53 @@ +package com.thealgorithms.matrix; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import org.junit.jupiter.api.Test; + +class SpiralMatrixIITest { + + // Instantiate the class to test + SpiralMatrixII spiral = new SpiralMatrixII(); + + @Test + void testNEquals3() { + int[][] expected = { + {1, 2, 3}, + {8, 9, 4}, + {7, 6, 5} + }; + int[][] actual = spiral.generateMatrix(3); + + // Compare each row + for (int i = 0; i < expected.length; i++) { + assertArrayEquals(expected[i], actual[i], "Row " + i + " is incorrect for n=3"); + } + } + + @Test + void testNEquals4() { + int[][] expected = { + {1, 2, 3, 4}, + {12, 13, 14, 5}, + {11, 16, 15, 6}, + {10, 9, 8, 7} + }; + int[][] actual = spiral.generateMatrix(4); + + for (int i = 0; i < expected.length; i++) { + assertArrayEquals(expected[i], actual[i], "Row " + i + " is incorrect for n=4"); + } + } + + @Test + void testNEquals2() { + int[][] expected = { + {1, 2}, + {4, 3} + }; + int[][] actual = spiral.generateMatrix(2); + + for (int i = 0; i < expected.length; i++) { + assertArrayEquals(expected[i], actual[i], "Row " + i + " is incorrect for n=2"); + } + } +}