From 974cc6b4795759e0d4b0004e3cf09ecb188fa17f Mon Sep 17 00:00:00 2001 From: Chahat Date: Sat, 17 Jan 2026 16:49:26 -0600 Subject: [PATCH 1/2] feat: added Bell Numbers algorithm using Aitken's Array --- .../com/thealgorithms/maths/BellNumbers.java | 59 +++++++++++++++++++ .../thealgorithms/maths/BellNumbersTest.java | 53 +++++++++++++++++ 2 files changed, 112 insertions(+) create mode 100644 src/main/java/com/thealgorithms/maths/BellNumbers.java create mode 100644 src/test/java/com/thealgorithms/maths/BellNumbersTest.java diff --git a/src/main/java/com/thealgorithms/maths/BellNumbers.java b/src/main/java/com/thealgorithms/maths/BellNumbers.java new file mode 100644 index 000000000000..0be9bee88081 --- /dev/null +++ b/src/main/java/com/thealgorithms/maths/BellNumbers.java @@ -0,0 +1,59 @@ +package com.thealgorithms.maths; + +/** + * The Bell numbers count the number of partitions of a set. + * The n-th Bell number is the number of ways a set of n elements can be partitioned + * into nonempty subsets. + * + *

+ * This implementation uses the Bell Triangle (Aitken's array) method. + * Time Complexity: O(n^2) + * Space Complexity: O(n^2) + *

+ * + * @author Chahat Sandhu, singhc7 + * @see Bell Number (Wikipedia) + */ +public final class BellNumbers { + + private BellNumbers() { + } + + /** + * Calculates the n-th Bell number using the Bell Triangle. + * + * @param n the index of the Bell number (must be non-negative) + * @return the n-th Bell number + * @throws IllegalArgumentException if n is negative or n > 25 + */ + public static long compute(int n) { + if (n < 0) { + throw new IllegalArgumentException("n must be non-negative"); + } + if (n == 0) { + return 1; + } + if (n > 25) { + throw new IllegalArgumentException("n must be <= 25. For larger n, use BigInteger implementation."); + } + + // We use a 2D array to visualize the Bell Triangle + long[][] bellTriangle = new long[n + 1][n + 1]; + + // Base case: The triangle starts with 1 + bellTriangle[0][0] = 1; + + for (int i = 1; i <= n; i++) { + // Rule 1: The first number in a new row is the LAST number of the previous row + bellTriangle[i][0] = bellTriangle[i - 1][i - 1]; + + // Rule 2: Fill the rest of the row by adding the previous neighbor and the upper-left neighbor + for (int j = 1; j <= i; j++) { + bellTriangle[i][j] = bellTriangle[i][j - 1] + bellTriangle[i - 1][j - 1]; + } + } + + // The Bell number B_n is the first number in the n-th row + return bellTriangle[n][0]; + } +} \ No newline at end of file diff --git a/src/test/java/com/thealgorithms/maths/BellNumbersTest.java b/src/test/java/com/thealgorithms/maths/BellNumbersTest.java new file mode 100644 index 000000000000..e08e0b89aab8 --- /dev/null +++ b/src/test/java/com/thealgorithms/maths/BellNumbersTest.java @@ -0,0 +1,53 @@ +package com.thealgorithms.maths; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.Test; + +class BellNumbersTest { + + @Test + void testStandardCases() { + // Base cases and small numbers + assertEquals(1, BellNumbers.compute(0)); + assertEquals(1, BellNumbers.compute(1)); + assertEquals(2, BellNumbers.compute(2)); + assertEquals(5, BellNumbers.compute(3)); + assertEquals(15, BellNumbers.compute(4)); + assertEquals(52, BellNumbers.compute(5)); + } + + @Test + void testMediumNumber() { + // B10 = 115,975 + assertEquals(115975, BellNumbers.compute(10)); + // B15 = 1,382,958,545 + assertEquals(1382958545L, BellNumbers.compute(15)); + } + + @Test + void testLargeNumber() { + // B20 = 51,724,158,235,372 + // We use the 'L' suffix to tell Java this is a long literal + assertEquals(51724158235372L, BellNumbers.compute(20)); + } + + @Test + void testMaxLongCapacity() { + // B25 is the largest Bell number that fits in a Java long (signed 64-bit) + // B25 = 4,638,590,332,229,999,353 + assertEquals(4638590332229999353L, BellNumbers.compute(25)); + } + + @Test + void testNegativeInput() { + assertThrows(IllegalArgumentException.class, () -> BellNumbers.compute(-1)); + } + + @Test + void testOverflowProtection() { + // We expect an exception if the user asks for the impossible + assertThrows(IllegalArgumentException.class, () -> BellNumbers.compute(26)); + } +} \ No newline at end of file From 921057f2f07b2e6a32e453075d63221de20545e1 Mon Sep 17 00:00:00 2001 From: Chahat Date: Sat, 17 Jan 2026 17:08:49 -0600 Subject: [PATCH 2/2] style: applied clang-format fixes --- src/main/java/com/thealgorithms/maths/BellNumbers.java | 2 +- src/test/java/com/thealgorithms/maths/BellNumbersTest.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/thealgorithms/maths/BellNumbers.java b/src/main/java/com/thealgorithms/maths/BellNumbers.java index 0be9bee88081..d4dc1014f48b 100644 --- a/src/main/java/com/thealgorithms/maths/BellNumbers.java +++ b/src/main/java/com/thealgorithms/maths/BellNumbers.java @@ -56,4 +56,4 @@ public static long compute(int n) { // The Bell number B_n is the first number in the n-th row return bellTriangle[n][0]; } -} \ No newline at end of file +} diff --git a/src/test/java/com/thealgorithms/maths/BellNumbersTest.java b/src/test/java/com/thealgorithms/maths/BellNumbersTest.java index e08e0b89aab8..8dd83cf0f7a9 100644 --- a/src/test/java/com/thealgorithms/maths/BellNumbersTest.java +++ b/src/test/java/com/thealgorithms/maths/BellNumbersTest.java @@ -50,4 +50,4 @@ void testOverflowProtection() { // We expect an exception if the user asks for the impossible assertThrows(IllegalArgumentException.class, () -> BellNumbers.compute(26)); } -} \ No newline at end of file +}