Skip to content

Add tests, remove main, add negativity test in Fibonacci.java #5645

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,7 @@
* [DPTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/dynamicprogramming/DPTest.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)
Expand Down
34 changes: 19 additions & 15 deletions src/main/java/com/thealgorithms/dynamicprogramming/Fibonacci.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

/**
* @author Varun Upadhyay (https://github.com/varunu28)
Expand All @@ -11,27 +10,19 @@ public final class Fibonacci {
private Fibonacci() {
}

private static final Map<Integer, Integer> 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<Integer, Integer> 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);
}
Expand All @@ -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<Integer, Integer> fib = new HashMap<>();

for (int i = 0; i <= n; i++) {
Expand All @@ -80,9 +75,13 @@ public static int fibBotUp(int n) {
* Time Complexity will be O(n)
* <p>
* 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;
}
Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
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); });
}
}