From 4c1ba0f2e16cad5d165694f51045bb54eba8d665 Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Sun, 13 Oct 2024 12:26:35 +0530 Subject: [PATCH 1/4] feat: Add `CelebrityFinder` new algorithm with Junit tests --- .../thealgorithms/stacks/CelebrityFinder.java | 40 +++++++++++++++++++ .../stacks/CelebrityFinderTest.java | 28 +++++++++++++ 2 files changed, 68 insertions(+) create mode 100644 src/main/java/com/thealgorithms/stacks/CelebrityFinder.java create mode 100644 src/test/java/com/thealgorithms/stacks/CelebrityFinderTest.java diff --git a/src/main/java/com/thealgorithms/stacks/CelebrityFinder.java b/src/main/java/com/thealgorithms/stacks/CelebrityFinder.java new file mode 100644 index 000000000000..0f730d089a3e --- /dev/null +++ b/src/main/java/com/thealgorithms/stacks/CelebrityFinder.java @@ -0,0 +1,40 @@ +package com.thealgorithms.stacks; + +/** + * Solves the celebrity problem using a stack-based algorithm. + * + *

Celebrity is someone known by everyone but doesn't know anyone else. + *

Applications: Graph theory and social network analysis. + * + * @author Hardvan + */ +public final class CelebrityFinder { + private CelebrityFinder() { + } + + /** + * Finds the celebrity in the given party matrix. + * + * @param party A 2D matrix where party[i][j] is 1 if i knows j, otherwise 0. + * @return The index of the celebrity, or -1 if there is no celebrity. + */ + public static int findCelebrity(int[][] party) { + int n = party.length; + int candidate = 0; + + // Find a potential celebrity + for (int i = 1; i < n; i++) { + if (party[candidate][i] == 1) { + candidate = i; + } + } + + // Verify the candidate + for (int i = 0; i < n; i++) { + if (i != candidate && (party[candidate][i] == 1 || party[i][candidate] == 0)) { + return -1; + } + } + return candidate; + } +} diff --git a/src/test/java/com/thealgorithms/stacks/CelebrityFinderTest.java b/src/test/java/com/thealgorithms/stacks/CelebrityFinderTest.java new file mode 100644 index 000000000000..21d16e6407db --- /dev/null +++ b/src/test/java/com/thealgorithms/stacks/CelebrityFinderTest.java @@ -0,0 +1,28 @@ +package com.thealgorithms.stacks; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +import org.junit.jupiter.api.Test; + +public class CelebrityFinderTest { + + @Test + public void testCelebrityExists() { + int[][] party = { + {0, 1, 1}, + {0, 0, 1}, + {0, 0, 0} + }; + assertEquals(2, CelebrityFinder.findCelebrity(party)); + } + + @Test + public void testNoCelebrity() { + int[][] party = { + {0, 1, 0}, + {1, 0, 1}, + {1, 1, 0} + }; + assertEquals(-1, CelebrityFinder.findCelebrity(party)); + } +} From 77f2e9c465e65a8005f0249d979c5a5c978d018f Mon Sep 17 00:00:00 2001 From: Hardvan Date: Sun, 13 Oct 2024 06:56:52 +0000 Subject: [PATCH 2/4] Update directory --- DIRECTORY.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/DIRECTORY.md b/DIRECTORY.md index af956a1a26ed..1859f51fab99 100644 --- a/DIRECTORY.md +++ b/DIRECTORY.md @@ -26,9 +26,11 @@ * [BcdConversion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/BcdConversion.java) * [BinaryPalindromeCheck](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/BinaryPalindromeCheck.java) * [BitSwap](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/BitSwap.java) + * [BooleanAlgebraGates](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/BooleanAlgebraGates.java) * [ClearLeftmostSetBit](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/ClearLeftmostSetBit.java) * [CountLeadingZeros](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/CountLeadingZeros.java) * [CountSetBits](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/CountSetBits.java) + * [FindNthBit](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/FindNthBit.java) * [GrayCodeConversion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/GrayCodeConversion.java) * [HammingDistance](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/HammingDistance.java) * [HigherLowerPowerOfTwo](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/bitmanipulation/HigherLowerPowerOfTwo.java) @@ -55,6 +57,7 @@ * [CompositeLFSR](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/a5/CompositeLFSR.java) * [LFSR](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/a5/LFSR.java) * [Utils](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/a5/Utils.java) + * [ADFGVXCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/ADFGVXCipher.java) * [AES](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/AES.java) * [AESEncryption](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/AESEncryption.java) * [AffineCipher](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/ciphers/AffineCipher.java) @@ -134,6 +137,7 @@ * [FordFulkerson](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/FordFulkerson.java) * [Graphs](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/Graphs.java) * [HamiltonianCycle](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/HamiltonianCycle.java) + * [JohnsonsAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/JohnsonsAlgorithm.java) * [KahnsAlgorithm](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/KahnsAlgorithm.java) * [Kosaraju](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/Kosaraju.java) * [Kruskal](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/datastructures/graphs/Kruskal.java) @@ -341,6 +345,7 @@ * [EulersFunction](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/EulersFunction.java) * [Factorial](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/Factorial.java) * [FactorialRecursion](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FactorialRecursion.java) + * [FastExponentiation](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FastExponentiation.java) * [FastInverseSqrt](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FastInverseSqrt.java) * [FFT](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FFT.java) * [FFTBluestein](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/maths/FFTBluestein.java) @@ -584,6 +589,7 @@ * [WiggleSort](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/sorts/WiggleSort.java) * stacks * [BalancedBrackets](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/BalancedBrackets.java) + * [CelebrityFinder](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/CelebrityFinder.java) * [DecimalToAnyUsingStack](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/DecimalToAnyUsingStack.java) * [DuplicateBrackets](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/DuplicateBrackets.java) * [InfixToPostfix](https://github.com/TheAlgorithms/Java/blob/master/src/main/java/com/thealgorithms/stacks/InfixToPostfix.java) @@ -658,9 +664,11 @@ * [BcdConversionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/BcdConversionTest.java) * [BinaryPalindromeCheckTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/BinaryPalindromeCheckTest.java) * [BitSwapTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/BitSwapTest.java) + * [BooleanAlgebraGatesTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/BooleanAlgebraGatesTest.java) * [ClearLeftmostSetBitTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/ClearLeftmostSetBitTest.java) * [CountLeadingZerosTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/CountLeadingZerosTest.java) * [CountSetBitsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/CountSetBitsTest.java) + * [FindNthBitTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/FindNthBitTest.java) * [GrayCodeConversionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/GrayCodeConversionTest.java) * [HammingDistanceTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/HammingDistanceTest.java) * [HigherLowerPowerOfTwoTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/bitmanipulation/HigherLowerPowerOfTwoTest.java) @@ -684,6 +692,7 @@ * [A5CipherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/a5/A5CipherTest.java) * [A5KeyStreamGeneratorTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/a5/A5KeyStreamGeneratorTest.java) * [LFSRTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/a5/LFSRTest.java) + * [ADFGVXCipherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/ADFGVXCipherTest.java) * [AESEncryptionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/AESEncryptionTest.java) * [AffineCipherTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/AffineCipherTest.java) * [AtbashTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/ciphers/AtbashTest.java) @@ -752,6 +761,7 @@ * [FloydWarshallTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/FloydWarshallTest.java) * [FordFulkersonTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/FordFulkersonTest.java) * [HamiltonianCycleTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/HamiltonianCycleTest.java) + * [JohnsonsAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/JohnsonsAlgorithmTest.java) * [KosarajuTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/KosarajuTest.java) * [TarjansAlgorithmTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/TarjansAlgorithmTest.java) * [WelshPowellTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/datastructures/graphs/WelshPowellTest.java) @@ -904,6 +914,7 @@ * [EulersFunctionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/EulersFunctionTest.java) * [FactorialRecursionTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FactorialRecursionTest.java) * [FactorialTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FactorialTest.java) + * [FastExponentiationTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FastExponentiationTest.java) * [FastInverseSqrtTests](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FastInverseSqrtTests.java) * [FFTTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FFTTest.java) * [FibonacciJavaStreamsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/maths/FibonacciJavaStreamsTest.java) @@ -1108,6 +1119,7 @@ * [WiggleSortTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/sorts/WiggleSortTest.java) * stacks * [BalancedBracketsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/BalancedBracketsTest.java) + * [CelebrityFinderTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/CelebrityFinderTest.java) * [DecimalToAnyUsingStackTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/DecimalToAnyUsingStackTest.java) * [DuplicateBracketsTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/DuplicateBracketsTest.java) * [InfixToPostfixTest](https://github.com/TheAlgorithms/Java/blob/master/src/test/java/com/thealgorithms/stacks/InfixToPostfixTest.java) From c201cfd9d51b1098af05a1d7b2ef1560c122f1d7 Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Sun, 13 Oct 2024 12:32:36 +0530 Subject: [PATCH 3/4] Fix --- .../thealgorithms/stacks/CelebrityFinderTest.java | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/test/java/com/thealgorithms/stacks/CelebrityFinderTest.java b/src/test/java/com/thealgorithms/stacks/CelebrityFinderTest.java index 21d16e6407db..a4f901f0d5de 100644 --- a/src/test/java/com/thealgorithms/stacks/CelebrityFinderTest.java +++ b/src/test/java/com/thealgorithms/stacks/CelebrityFinderTest.java @@ -8,21 +8,13 @@ public class CelebrityFinderTest { @Test public void testCelebrityExists() { - int[][] party = { - {0, 1, 1}, - {0, 0, 1}, - {0, 0, 0} - }; + int[][] party = {{0, 1, 1}, {0, 0, 1}, {0, 0, 0}}; assertEquals(2, CelebrityFinder.findCelebrity(party)); } @Test public void testNoCelebrity() { - int[][] party = { - {0, 1, 0}, - {1, 0, 1}, - {1, 1, 0} - }; + int[][] party = {{0, 1, 0}, {1, 0, 1}, {1, 1, 0}}; assertEquals(-1, CelebrityFinder.findCelebrity(party)); } } From 564bae00b681dc0e35bab0bf96a6e2da31060bd1 Mon Sep 17 00:00:00 2001 From: Hardik Pawar Date: Tue, 15 Oct 2024 12:07:33 +0530 Subject: [PATCH 4/4] Add suggested changes --- .../thealgorithms/stacks/CelebrityFinder.java | 28 +++++++++---- .../stacks/CelebrityFinderTest.java | 39 ++++++++++++++----- 2 files changed, 50 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/thealgorithms/stacks/CelebrityFinder.java b/src/main/java/com/thealgorithms/stacks/CelebrityFinder.java index 0f730d089a3e..67ac861ef82b 100644 --- a/src/main/java/com/thealgorithms/stacks/CelebrityFinder.java +++ b/src/main/java/com/thealgorithms/stacks/CelebrityFinder.java @@ -1,5 +1,7 @@ package com.thealgorithms.stacks; +import java.util.Stack; + /** * Solves the celebrity problem using a stack-based algorithm. * @@ -13,24 +15,34 @@ private CelebrityFinder() { } /** - * Finds the celebrity in the given party matrix. + * Finds the celebrity in the given party matrix using a stack-based algorithm. * * @param party A 2D matrix where party[i][j] is 1 if i knows j, otherwise 0. * @return The index of the celebrity, or -1 if there is no celebrity. */ public static int findCelebrity(int[][] party) { - int n = party.length; - int candidate = 0; - // Find a potential celebrity - for (int i = 1; i < n; i++) { - if (party[candidate][i] == 1) { - candidate = i; + // Push all people onto the stack + Stack stack = new Stack<>(); + for (int i = 0; i < party.length; i++) { + stack.push(i); + } + + // Find the potential celebrity by comparing pairs + while (stack.size() > 1) { + int person1 = stack.pop(); + int person2 = stack.pop(); + + if (party[person1][person2] == 1) { + stack.push(person2); // person1 knows person2, so person2 might be the celebrity + } else { + stack.push(person1); // person1 doesn't know person2, so person1 might be the celebrity } } // Verify the candidate - for (int i = 0; i < n; i++) { + int candidate = stack.pop(); + for (int i = 0; i < party.length; i++) { if (i != candidate && (party[candidate][i] == 1 || party[i][candidate] == 0)) { return -1; } diff --git a/src/test/java/com/thealgorithms/stacks/CelebrityFinderTest.java b/src/test/java/com/thealgorithms/stacks/CelebrityFinderTest.java index a4f901f0d5de..da0217940c2c 100644 --- a/src/test/java/com/thealgorithms/stacks/CelebrityFinderTest.java +++ b/src/test/java/com/thealgorithms/stacks/CelebrityFinderTest.java @@ -2,19 +2,40 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -import org.junit.jupiter.api.Test; +import java.util.stream.Stream; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; public class CelebrityFinderTest { - @Test - public void testCelebrityExists() { - int[][] party = {{0, 1, 1}, {0, 0, 1}, {0, 0, 0}}; - assertEquals(2, CelebrityFinder.findCelebrity(party)); + @ParameterizedTest + @MethodSource("providePartyMatrices") + public void testCelebrityFinder(int[][] party, int expected) { + assertEquals(expected, CelebrityFinder.findCelebrity(party)); } - @Test - public void testNoCelebrity() { - int[][] party = {{0, 1, 0}, {1, 0, 1}, {1, 1, 0}}; - assertEquals(-1, CelebrityFinder.findCelebrity(party)); + private static Stream providePartyMatrices() { + return Stream.of( + // Test case 1: Celebrity exists + Arguments.of(new int[][] {{0, 1, 1}, {0, 0, 1}, {0, 0, 0}}, 2), + + // Test case 2: No celebrity + Arguments.of(new int[][] {{0, 1, 0}, {1, 0, 1}, {1, 1, 0}}, -1), + + // Test case 3: Everyone knows each other, no celebrity + Arguments.of(new int[][] {{0, 1, 1}, {1, 0, 1}, {1, 1, 0}}, -1), + + // Test case 4: Single person, they are trivially a celebrity + Arguments.of(new int[][] {{0}}, 0), + + // Test case 5: All know the last person, and they know no one + Arguments.of(new int[][] {{0, 1, 1, 1}, {0, 0, 1, 1}, {0, 0, 0, 1}, {0, 0, 0, 0}}, 3), + + // Test case 6: Larger party with no celebrity + Arguments.of(new int[][] {{0, 1, 1, 0}, {1, 0, 0, 1}, {0, 1, 0, 1}, {1, 1, 1, 0}}, -1), + + // Test case 7: Celebrity at the start of the matrix + Arguments.of(new int[][] {{0, 0, 0}, {1, 0, 1}, {1, 1, 0}}, 0)); } }