From 3a805f1fad132596eaf3d0490410a1e3baa72fcd Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Tue, 8 Oct 2024 15:52:18 +0530 Subject: [PATCH 1/3] Add tests, remove `main`, add negativity test in `Fibonacci.java` --- .../dynamicprogramming/Fibonacci.java | 34 ++++--- .../dynamicprogramming/FibonacciTest.java | 97 +++++++++++++++++++ 2 files changed, 116 insertions(+), 15 deletions(-) create mode 100644 src/test/java/com/thealgorithms/dynamicprogramming/FibonacciTest.java diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/Fibonacci.java b/src/main/java/com/thealgorithms/dynamicprogramming/Fibonacci.java index 5855030fc65c..0d6aff2bbef3 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/Fibonacci.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/Fibonacci.java @@ -2,7 +2,6 @@ import java.util.HashMap; import java.util.Map; -import java.util.Scanner; /** * @author Varun Upadhyay (https://github.com/varunu28) @@ -11,27 +10,19 @@ public final class Fibonacci { private Fibonacci() { } - private static final Map CACHE = new HashMap<>(); - - public static void main(String[] args) { - // Methods all returning [0, 1, 1, 2, 3, 5, ...] for n = [0, 1, 2, 3, 4, 5, ...] - Scanner sc = new Scanner(System.in); - int n = sc.nextInt(); - - System.out.println(fibMemo(n)); - System.out.println(fibBotUp(n)); - System.out.println(fibOptimized(n)); - System.out.println(fibBinet(n)); - sc.close(); - } + static final Map CACHE = new HashMap<>(); /** * This method finds the nth fibonacci number using memoization technique * * @param n The input n for which we have to determine the fibonacci number * Outputs the nth fibonacci number + * @throws IllegalArgumentException if n is negative */ public static int fibMemo(int n) { + if (n < 0) { + throw new IllegalArgumentException("Input n must be non-negative"); + } if (CACHE.containsKey(n)) { return CACHE.get(n); } @@ -52,8 +43,12 @@ public static int fibMemo(int n) { * * @param n The input n for which we have to determine the fibonacci number * Outputs the nth fibonacci number + * @throws IllegalArgumentException if n is negative */ public static int fibBotUp(int n) { + if (n < 0) { + throw new IllegalArgumentException("Input n must be non-negative"); + } Map fib = new HashMap<>(); for (int i = 0; i <= n; i++) { @@ -80,9 +75,13 @@ public static int fibBotUp(int n) { * Time Complexity will be O(n) *

* Whereas , the above functions will take O(n) Space. + * @throws IllegalArgumentException if n is negative * @author Shoaib Rayeen (https://github.com/shoaibrayeen) */ public static int fibOptimized(int n) { + if (n < 0) { + throw new IllegalArgumentException("Input n must be non-negative"); + } if (n == 0) { return 0; } @@ -105,9 +104,14 @@ public static int fibOptimized(int n) { * = 1.6180339887... Now, let's look at Binet's formula: Sn = Φⁿ–(– Φ⁻ⁿ)/√5 We first calculate * the squareRootof5 and phi and store them in variables. Later, we apply Binet's formula to get * the required term. Time Complexity will be O(1) + * @param n The input n for which we have to determine the fibonacci number + * Outputs the nth fibonacci number + * @throws IllegalArgumentException if n is negative */ - public static int fibBinet(int n) { + if (n < 0) { + throw new IllegalArgumentException("Input n must be non-negative"); + } double squareRootOf5 = Math.sqrt(5); double phi = (1 + squareRootOf5) / 2; return (int) ((Math.pow(phi, n) - Math.pow(-phi, -n)) / squareRootOf5); diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/FibonacciTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/FibonacciTest.java new file mode 100644 index 000000000000..01138d6c2a95 --- /dev/null +++ b/src/test/java/com/thealgorithms/dynamicprogramming/FibonacciTest.java @@ -0,0 +1,97 @@ +package com.thealgorithms.dynamicprogramming; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +public class FibonacciTest { + + @BeforeEach + void setUp() { + // Clear the cache before each test to avoid interference + Fibonacci.CACHE.clear(); + } + + @Test + void testFibMemo() { + // Test memoization method + assertEquals(0, Fibonacci.fibMemo(0)); + assertEquals(1, Fibonacci.fibMemo(1)); + assertEquals(1, Fibonacci.fibMemo(2)); + assertEquals(2, Fibonacci.fibMemo(3)); + assertEquals(3, Fibonacci.fibMemo(4)); + assertEquals(5, Fibonacci.fibMemo(5)); + assertEquals(8, Fibonacci.fibMemo(6)); + assertEquals(13, Fibonacci.fibMemo(7)); + assertEquals(21, Fibonacci.fibMemo(8)); + assertEquals(34, Fibonacci.fibMemo(9)); + assertEquals(55, Fibonacci.fibMemo(10)); + } + + @Test + void testFibBotUp() { + // Test bottom-up method + assertEquals(0, Fibonacci.fibBotUp(0)); + assertEquals(1, Fibonacci.fibBotUp(1)); + assertEquals(1, Fibonacci.fibBotUp(2)); + assertEquals(2, Fibonacci.fibBotUp(3)); + assertEquals(3, Fibonacci.fibBotUp(4)); + assertEquals(5, Fibonacci.fibBotUp(5)); + assertEquals(8, Fibonacci.fibBotUp(6)); + assertEquals(13, Fibonacci.fibBotUp(7)); + assertEquals(21, Fibonacci.fibBotUp(8)); + assertEquals(34, Fibonacci.fibBotUp(9)); + assertEquals(55, Fibonacci.fibBotUp(10)); + } + + @Test + void testFibOptimized() { + // Test optimized Fibonacci method + assertEquals(0, Fibonacci.fibOptimized(0)); + assertEquals(1, Fibonacci.fibOptimized(1)); + assertEquals(1, Fibonacci.fibOptimized(2)); + assertEquals(2, Fibonacci.fibOptimized(3)); + assertEquals(3, Fibonacci.fibOptimized(4)); + assertEquals(5, Fibonacci.fibOptimized(5)); + assertEquals(8, Fibonacci.fibOptimized(6)); + assertEquals(13, Fibonacci.fibOptimized(7)); + assertEquals(21, Fibonacci.fibOptimized(8)); + assertEquals(34, Fibonacci.fibOptimized(9)); + assertEquals(55, Fibonacci.fibOptimized(10)); + } + + @Test + void testFibBinet() { + // Test Binet's formula method + assertEquals(0, Fibonacci.fibBinet(0)); + assertEquals(1, Fibonacci.fibBinet(1)); + assertEquals(1, Fibonacci.fibBinet(2)); + assertEquals(2, Fibonacci.fibBinet(3)); + assertEquals(3, Fibonacci.fibBinet(4)); + assertEquals(5, Fibonacci.fibBinet(5)); + assertEquals(8, Fibonacci.fibBinet(6)); + assertEquals(13, Fibonacci.fibBinet(7)); + assertEquals(21, Fibonacci.fibBinet(8)); + assertEquals(34, Fibonacci.fibBinet(9)); + assertEquals(55, Fibonacci.fibBinet(10)); + } + + @Test + void testNegativeInput() { + // Test negative input; Fibonacci is not defined for negative numbers + assertThrows(IllegalArgumentException.class, () -> { + Fibonacci.fibMemo(-1); + }); + assertThrows(IllegalArgumentException.class, () -> { + Fibonacci.fibBotUp(-1); + }); + assertThrows(IllegalArgumentException.class, () -> { + Fibonacci.fibOptimized(-1); + }); + assertThrows(IllegalArgumentException.class, () -> { + Fibonacci.fibBinet(-1); + }); + } +} From f726d75d0e10a59737b0308d13608de2e87cddcc Mon Sep 17 00:00:00 2001 From: Hardvan Date: Tue, 8 Oct 2024 10:22:40 +0000 Subject: [PATCH 2/3] Update directory --- DIRECTORY.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index 228735aa8ea9..0b06986abb3c 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -267,6 +267,7 @@ * [SumOfSubset](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/SumOfSubset.java) * [Tribonacci](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/Tribonacci.java) * [UniquePaths](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/UniquePaths.java) + * [UniqueSubsequencesCount](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/UniqueSubsequencesCount.java) * [WildcardMatching](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/WildcardMatching.java) * [WineProblem](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/dynamicprogramming/WineProblem.java) * geometry @@ -773,6 +774,7 @@ * [ClimbStairsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/ClimbStairsTest.java) * [EditDistanceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/EditDistanceTest.java) * [EggDroppingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/EggDroppingTest.java) + * [FibonacciTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/FibonacciTest.java) * [KnapsackMemoizationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackMemoizationTest.java) * [KnapsackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/KnapsackTest.java) * [LevenshteinDistanceTests](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/LevenshteinDistanceTests.java) @@ -794,6 +796,7 @@ * [SumOfSubsetTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/SumOfSubsetTest.java) * [TribonacciTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/TribonacciTest.java) * [UniquePathsTests](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/UniquePathsTests.java) + * [UniqueSubsequencesCountTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/UniqueSubsequencesCountTest.java) * [WildcardMatchingTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/WildcardMatchingTest.java) * geometry * [GrahamScanTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/geometry/GrahamScanTest.java) From 275a087911a983955ae26976618320c2da91ee39 Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Tue, 8 Oct 2024 15:58:52 +0530 Subject: [PATCH 3/3] Fix --- .../dynamicprogramming/FibonacciTest.java | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/test/java/com/thealgorithms/dynamicprogramming/FibonacciTest.java b/src/test/java/com/thealgorithms/dynamicprogramming/FibonacciTest.java index 01138d6c2a95..166e20c3083f 100644 --- a/src/test/java/com/thealgorithms/dynamicprogramming/FibonacciTest.java +++ b/src/test/java/com/thealgorithms/dynamicprogramming/FibonacciTest.java @@ -81,17 +81,9 @@ void testFibBinet() { @Test void testNegativeInput() { // Test negative input; Fibonacci is not defined for negative numbers - assertThrows(IllegalArgumentException.class, () -> { - Fibonacci.fibMemo(-1); - }); - assertThrows(IllegalArgumentException.class, () -> { - Fibonacci.fibBotUp(-1); - }); - assertThrows(IllegalArgumentException.class, () -> { - Fibonacci.fibOptimized(-1); - }); - assertThrows(IllegalArgumentException.class, () -> { - Fibonacci.fibBinet(-1); - }); + assertThrows(IllegalArgumentException.class, () -> { Fibonacci.fibMemo(-1); }); + assertThrows(IllegalArgumentException.class, () -> { Fibonacci.fibBotUp(-1); }); + assertThrows(IllegalArgumentException.class, () -> { Fibonacci.fibOptimized(-1); }); + assertThrows(IllegalArgumentException.class, () -> { Fibonacci.fibBinet(-1); }); } }