diff --git a/src/main/java/com/thealgorithms/Recursion/GenerateSubsets.java b/src/main/java/com/thealgorithms/Recursion/GenerateSubsets.java index 417bf1307790..5eefe3eee671 100644 --- a/src/main/java/com/thealgorithms/Recursion/GenerateSubsets.java +++ b/src/main/java/com/thealgorithms/Recursion/GenerateSubsets.java @@ -5,6 +5,11 @@ import java.util.ArrayList; import java.util.List; +/** + * Finds all permutations of given array + * @author Tuhin Mondal (Git-Tuhin Mondal) + */ + public final class GenerateSubsets { private GenerateSubsets() { diff --git a/src/main/java/com/thealgorithms/Recursion/GenerateUniqueSubsets.java b/src/main/java/com/thealgorithms/Recursion/GenerateUniqueSubsets.java new file mode 100644 index 000000000000..9c8cffa59df8 --- /dev/null +++ b/src/main/java/com/thealgorithms/Recursion/GenerateUniqueSubsets.java @@ -0,0 +1,47 @@ +package com.thealgorithms.Recursion; + +// program to find unique power set of a string + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Finds all permutations of given array + * @author Tuhin Mondal (Git-Tuhin Mondal) + */ + +public final class GenerateUniqueSubsets { + + private GenerateUniqueSubsets() { + throw new UnsupportedOperationException("Utility class"); + } + + public static List subsetRecursion(String str) { + Set ans = doRecursion("", str); + List a = new ArrayList<>(ans.stream().toList()); + Collections.sort(a); + return a; + } + + private static Set doRecursion(String p, String up) { + if (up.isEmpty()) { + Set list = new HashSet<>(); + list.add(p); + return list; + } + + // Taking the character + char ch = up.charAt(0); + // Adding the character in the recursion + Set left = doRecursion(p + ch, up.substring(1)); + // Not adding the character in the recursion + Set right = doRecursion(p, up.substring(1)); + + left.addAll(right); + + return left; + } +} diff --git a/src/main/java/com/thealgorithms/Recursion/TowerOfHanoi.java b/src/main/java/com/thealgorithms/Recursion/TowerOfHanoi.java new file mode 100644 index 000000000000..f127ef74161d --- /dev/null +++ b/src/main/java/com/thealgorithms/Recursion/TowerOfHanoi.java @@ -0,0 +1,32 @@ +package com.thealgorithms.Recursion; + +import java.util.ArrayList; +import java.util.List; + +/** + * Finds all permutations of given array + * @author Tuhin Mondal (Git-Tuhin Mondal) + */ + +public final class TowerOfHanoi { + private TowerOfHanoi() { + throw new UnsupportedOperationException("Utility class"); + } + + public static List towerOfHanoi(int n) { + List arr = new ArrayList<>(); + recursionApproach(n, 'A', 'B', 'C', arr); + return arr; + } + + public static void recursionApproach(int n, char a, char b, char c, List list) { + if (n == 1) { + list.add("Take disk 1 from rod " + a + " to rod " + b); + return; + } + + recursionApproach(n - 1, a, c, b, list); + list.add("Take disk " + n + " from rod " + a + " to rod " + b); + recursionApproach(n - 1, c, b, a, list); + } +} diff --git a/src/main/java/com/thealgorithms/ciphers/DES.java b/src/main/java/com/thealgorithms/ciphers/DES.java index 7f3eed70f3c2..6e7064920bcc 100644 --- a/src/main/java/com/thealgorithms/ciphers/DES.java +++ b/src/main/java/com/thealgorithms/ciphers/DES.java @@ -32,7 +32,7 @@ public void setKey(String key) { this.key = key; } - // Permutation table to convert initial 64-bit key to 56 bit key + // GeneratePermutations table to convert initial 64-bit key to 56 bit key private static final int[] PC1 = {57, 49, 41, 33, 25, 17, 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, 27, 19, 11, 3, 60, 52, 44, 36, 63, 55, 47, 39, 31, 23, 15, 7, 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, 13, 5, 28, 20, 12, 4}; // Lookup table used to shift the initial key, in order to generate the subkeys @@ -66,7 +66,7 @@ public void setKey(String key) { private static final int[][][] S = {S1, S2, S3, S4, S5, S6, S7, S8}; - // Permutation table, used in the Feistel function post s-box usage + // GeneratePermutations table, used in the Feistel function post s-box usage static final int[] PERMUTATION = {16, 7, 20, 21, 29, 12, 28, 17, 1, 15, 23, 26, 5, 18, 31, 10, 2, 8, 24, 14, 32, 27, 3, 9, 19, 13, 30, 6, 22, 11, 4, 25}; // Table used for final inversion of the message box after 16 rounds of Feistel Function diff --git a/src/main/java/com/thealgorithms/datastructures/crdt/GSet.java b/src/main/java/com/thealgorithms/datastructures/crdt/GSet.java index 2b8959ed0136..36ba84636209 100644 --- a/src/main/java/com/thealgorithms/datastructures/crdt/GSet.java +++ b/src/main/java/com/thealgorithms/datastructures/crdt/GSet.java @@ -44,10 +44,10 @@ public boolean lookup(T e) { } /** - * Compares the G-Set with another G-Set to check if it is a subset. + * Compares the G-Set with another G-Set to check if it is a subsetRecursion. * * @param other the other G-Set to compare with - * @return true if the current G-Set is a subset of the other, false otherwise + * @return true if the current G-Set is a subsetRecursion of the other, false otherwise */ public boolean compare(GSet other) { return other.elements.containsAll(elements); diff --git a/src/main/java/com/thealgorithms/datastructures/crdt/LWWElementSet.java b/src/main/java/com/thealgorithms/datastructures/crdt/LWWElementSet.java index 2c6ce8a427d1..289e95c38769 100644 --- a/src/main/java/com/thealgorithms/datastructures/crdt/LWWElementSet.java +++ b/src/main/java/com/thealgorithms/datastructures/crdt/LWWElementSet.java @@ -88,10 +88,10 @@ public boolean lookup(Element e) { } /** - * Compares the LWWElementSet with another LWWElementSet to check if addSet and removeSet are a subset. + * Compares the LWWElementSet with another LWWElementSet to check if addSet and removeSet are a subsetRecursion. * * @param other The LWWElementSet to compare. - * @return True if the set is subset, false otherwise. + * @return True if the set is subsetRecursion, false otherwise. */ public boolean compare(LWWElementSet other) { return other.addSet.keySet().containsAll(addSet.keySet()) && other.removeSet.keySet().containsAll(removeSet.keySet()); diff --git a/src/main/java/com/thealgorithms/datastructures/crdt/ORSet.java b/src/main/java/com/thealgorithms/datastructures/crdt/ORSet.java index a4cc2ffdd4a6..894be3df4146 100644 --- a/src/main/java/com/thealgorithms/datastructures/crdt/ORSet.java +++ b/src/main/java/com/thealgorithms/datastructures/crdt/ORSet.java @@ -132,10 +132,10 @@ private String generateUniqueTag() { } /** - * Compares this Add-Wins OR-Set with another OR-Set to check if elements and tombstones are a subset. + * Compares this Add-Wins OR-Set with another OR-Set to check if elements and tombstones are a subsetRecursion. * * @param other the other OR-Set to compare - * @return true if the sets are subset, false otherwise + * @return true if the sets are subsetRecursion, false otherwise */ public boolean compare(ORSet other) { Set> union = new HashSet<>(elements); diff --git a/src/main/java/com/thealgorithms/datastructures/crdt/TwoPSet.java b/src/main/java/com/thealgorithms/datastructures/crdt/TwoPSet.java index c0ce17b2802b..b434f2686a05 100644 --- a/src/main/java/com/thealgorithms/datastructures/crdt/TwoPSet.java +++ b/src/main/java/com/thealgorithms/datastructures/crdt/TwoPSet.java @@ -61,7 +61,7 @@ public void remove(T element) { * Compares the current 2P-Set with another 2P-Set. * * @param otherSet The other 2P-Set to compare with. - * @return True if both SetA and SetR are subset, otherwise false. + * @return True if both SetA and SetR are subsetRecursion, otherwise false. */ public boolean compare(TwoPSet otherSet) { return otherSet.setA.containsAll(setA) && otherSet.setR.containsAll(setR); diff --git a/src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithm.java b/src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithm.java index dcdb08ad133e..d47d7c7c5793 100644 --- a/src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithm.java +++ b/src/main/java/com/thealgorithms/datastructures/graphs/BoruvkaAlgorithm.java @@ -60,7 +60,7 @@ static class Graph { } /** - * Represents a subset for Union-Find operations + * Represents a subsetRecursion for Union-Find operations */ private static class Component { int parent; @@ -89,7 +89,7 @@ private static class BoruvkaState { /** * Adds the cheapest edges to the result list and performs Union operation on the subsets. * - * @param cheapest Array containing the cheapest edge for each subset. + * @param cheapest Array containing the cheapest edge for each subsetRecursion. */ void merge(final Edge[] cheapest) { for (int i = 0; i < graph.vertex; ++i) { @@ -115,9 +115,9 @@ boolean hasMoreEdgesToAdd() { } /** - * Computes the cheapest edges for each subset in the Union-Find structure. + * Computes the cheapest edges for each subsetRecursion in the Union-Find structure. * - * @return an array containing the cheapest edge for each subset. + * @return an array containing the cheapest edge for each subsetRecursion. */ private Edge[] computeCheapestEdges() { Edge[] cheapest = new Edge[graph.vertex]; @@ -153,11 +153,11 @@ private static Component[] initializeComponents(final Graph graph) { } /** - * Finds the parent of the subset using path compression + * Finds the parent of the subsetRecursion using path compression * * @param components array of subsets - * @param i index of the subset - * @return the parent of the subset + * @param i index of the subsetRecursion + * @return the parent of the subsetRecursion */ static int find(final Component[] components, final int i) { if (components[i].parent != i) { @@ -170,8 +170,8 @@ static int find(final Component[] components, final int i) { * Performs the Union operation for Union-Find * * @param components array of subsets - * @param x index of the first subset - * @param y index of the second subset + * @param x index of the first subsetRecursion + * @param y index of the second subsetRecursion */ static void union(Component[] components, final int x, final int y) { final int xroot = find(components, x); diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/MinimumSumPartition.java b/src/main/java/com/thealgorithms/dynamicprogramming/MinimumSumPartition.java index 52308c23cf1c..7e910a40f229 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/MinimumSumPartition.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/MinimumSumPartition.java @@ -3,8 +3,8 @@ import java.util.Arrays; /* -Given an array of non-negative integers , partition the array in two subset that -difference in sum of elements for both subset minimum. +Given an array of non-negative integers , partition the array in two subsetRecursion that +difference in sum of elements for both subsetRecursion minimum. Return the minimum difference in sum of these subsets you can achieve. Input: array[] = {1, 6, 11, 4} @@ -35,7 +35,7 @@ public static int minimumSumPartition(final int[] array) { boolean[] dp = new boolean[sum / 2 + 1]; dp[0] = true; // Base case , don't select any element from array - // Find the closest sum of subset array that we can achieve which is closest to half of sum of full array + // Find the closest sum of subsetRecursion array that we can achieve which is closest to half of sum of full array int closestPartitionSum = 0; for (int i = 0; i < array.length; i++) { diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/PartitionProblem.java b/src/main/java/com/thealgorithms/dynamicprogramming/PartitionProblem.java index 49c4a0a3a008..8613e5ddbdbe 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/PartitionProblem.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/PartitionProblem.java @@ -3,7 +3,7 @@ * * Description: The partition problem is a classic problem in computer science * that asks whether a given set can be partitioned into two subsets such that - * the sum of elements in each subset is the same. + * the sum of elements in each subsetRecursion is the same. * * Example: * Consider nums = {1, 2, 3} @@ -24,17 +24,17 @@ private PartitionProblem() { /** * Test if a set of integers can be partitioned into two subsets such that the sum of elements - * in each subset is the same. + * in each subsetRecursion is the same. * * @param nums the array contains integers. - * @return {@code true} if two subset exists, otherwise {@code false}. + * @return {@code true} if two subsetRecursion exists, otherwise {@code false}. */ public static boolean partition(int[] nums) { // calculate the sum of all the elements in the array int sum = Arrays.stream(nums).sum(); // it will return true if the sum is even and the array can be divided into two - // subarrays/subset with equal sum. and here i reuse the SubsetSum class from dynamic + // subarrays/subsetRecursion with equal sum. and here i reuse the SubsetSum class from dynamic // programming section to check if there is exists a subsetsum into nums[] array same as the // given sum return (sum & 1) == 0 && SubsetSum.subsetSum(nums, sum / 2); diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/SubsetCount.java b/src/main/java/com/thealgorithms/dynamicprogramming/SubsetCount.java index 0c5bc2c5884d..91a8b19c752d 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/SubsetCount.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/SubsetCount.java @@ -15,12 +15,12 @@ private SubsetCount() { * Method to find out the number of subsets present in the given array with a sum equal to * target. Time Complexity is O(n*target) and Space Complexity is O(n*target) * @param arr is the input array on which subsets are to searched - * @param target is the sum of each element of the subset taken together + * @param target is the sum of each element of the subsetRecursion taken together * */ public static int getCount(int[] arr, int target) { /* - * Base Cases - If target becomes zero, we have reached the required sum for the subset + * Base Cases - If target becomes zero, we have reached the required sum for the subsetRecursion * If we reach the end of the array arr then, either if target==arr[end], then we add one to * the final count Otherwise we add 0 to the final count */ @@ -50,7 +50,7 @@ public static int getCount(int[] arr, int target) { * same problem This approach is a bit better in terms of Space Used Time Complexity is * O(n*target) and Space Complexity is O(target) * @param arr is the input array on which subsets are to searched - * @param target is the sum of each element of the subset taken together + * @param target is the sum of each element of the subsetRecursion taken together */ public static int getCountSO(int[] arr, int target) { int n = arr.length; diff --git a/src/main/java/com/thealgorithms/dynamicprogramming/SubsetSum.java b/src/main/java/com/thealgorithms/dynamicprogramming/SubsetSum.java index 3dd41d2fdc0f..e8c6f97006bb 100644 --- a/src/main/java/com/thealgorithms/dynamicprogramming/SubsetSum.java +++ b/src/main/java/com/thealgorithms/dynamicprogramming/SubsetSum.java @@ -5,22 +5,22 @@ private SubsetSum() { } /** - * Test if a set of integers contains a subset that sums to a given integer. + * Test if a set of integers contains a subsetRecursion that sums to a given integer. * * @param arr the array containing integers. - * @param sum the target sum of the subset. - * @return {@code true} if a subset exists that sums to the given value, otherwise {@code false}. + * @param sum the target sum of the subsetRecursion. + * @return {@code true} if a subsetRecursion exists that sums to the given value, otherwise {@code false}. */ public static boolean subsetSum(int[] arr, int sum) { int n = arr.length; boolean[][] isSum = new boolean[n + 1][sum + 1]; - // Initialize the first column to true since a sum of 0 can always be achieved with an empty subset. + // Initialize the first column to true since a sum of 0 can always be achieved with an empty subsetRecursion. for (int i = 0; i <= n; i++) { isSum[i][0] = true; } - // Fill the subset sum matrix + // Fill the subsetRecursion sum matrix for (int i = 1; i <= n; i++) { for (int j = 1; j <= sum; j++) { if (arr[i - 1] <= j) { diff --git a/src/test/java/com/thealgorithms/Recursion/GenerateUniqueSubsetsTest.java b/src/test/java/com/thealgorithms/Recursion/GenerateUniqueSubsetsTest.java new file mode 100644 index 000000000000..ceaa5081f0c5 --- /dev/null +++ b/src/test/java/com/thealgorithms/Recursion/GenerateUniqueSubsetsTest.java @@ -0,0 +1,36 @@ +package com.thealgorithms.Recursion; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import java.util.List; +import org.junit.jupiter.api.Test; + +public final class GenerateUniqueSubsetsTest { + + @Test + void subsetRecursionTestOne() { + String str = "aba"; + String[] expected = new String[] {"", "a", "aa", "ab", "aba", "b", "ba"}; + + List ans = GenerateUniqueSubsets.subsetRecursion(str); + assertArrayEquals(ans.toArray(), expected); + } + + @Test + void subsetRecursionTestTwo() { + String str = "abba"; + String[] expected = new String[] {"", "a", "aa", "ab", "aba", "abb", "abba", "b", "ba", "bb", "bba"}; + + List ans = GenerateUniqueSubsets.subsetRecursion(str); + assertArrayEquals(ans.toArray(), expected); + } + + @Test + void subsetRecursionTestThree() { + String str = "aaa"; + String[] expected = new String[] {"", "a", "aa", "aaa"}; + + List ans = GenerateUniqueSubsets.subsetRecursion(str); + assertArrayEquals(ans.toArray(), expected); + } +} diff --git a/src/test/java/com/thealgorithms/Recursion/TowerOfHanoiTest.java b/src/test/java/com/thealgorithms/Recursion/TowerOfHanoiTest.java new file mode 100644 index 000000000000..404c195ae400 --- /dev/null +++ b/src/test/java/com/thealgorithms/Recursion/TowerOfHanoiTest.java @@ -0,0 +1,42 @@ +package com.thealgorithms.Recursion; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; + +import java.util.List; +import org.junit.jupiter.api.Test; + +public final class TowerOfHanoiTest { + + @Test + void hanoiTowerTestOne() { + + int n = 5; + String[] expected = {"Take disk 1 from rod A to rod B", "Take disk 2 from rod A to rod C", "Take disk 1 from rod B to rod C", "Take disk 3 from rod A to rod B", "Take disk 1 from rod C to rod A", "Take disk 2 from rod C to rod B", "Take disk 1 from rod A to rod B", + "Take disk 4 from rod A to rod C", "Take disk 1 from rod B to rod C", "Take disk 2 from rod B to rod A", "Take disk 1 from rod C to rod A", "Take disk 3 from rod B to rod C", "Take disk 1 from rod A to rod B", "Take disk 2 from rod A to rod C", "Take disk 1 from rod B to rod C", + "Take disk 5 from rod A to rod B", "Take disk 1 from rod C to rod A", "Take disk 2 from rod C to rod B", "Take disk 1 from rod A to rod B", "Take disk 3 from rod C to rod A", "Take disk 1 from rod B to rod C", "Take disk 2 from rod B to rod A", "Take disk 1 from rod C to rod A", + "Take disk 4 from rod C to rod B", "Take disk 1 from rod A to rod B", "Take disk 2 from rod A to rod C", "Take disk 1 from rod B to rod C", "Take disk 3 from rod A to rod B", "Take disk 1 from rod C to rod A", "Take disk 2 from rod C to rod B", "Take disk 1 from rod A to rod B"}; + + List actual = TowerOfHanoi.towerOfHanoi(n); + assertArrayEquals(expected, actual.toArray()); + } + + @Test + void hanoiTowerTestTwo() { + + int n = 3; + String[] expected = {"Take disk 1 from rod A to rod B", "Take disk 2 from rod A to rod C", "Take disk 1 from rod B to rod C", "Take disk 3 from rod A to rod B", "Take disk 1 from rod C to rod A", "Take disk 2 from rod C to rod B", "Take disk 1 from rod A to rod B"}; + + List actual = TowerOfHanoi.towerOfHanoi(n); + assertArrayEquals(expected, actual.toArray()); + } + + @Test + void hanoiTowerTestThree() { + + int n = 1; + String[] expected = {"Take disk 1 from rod A to rod B"}; + + List actual = TowerOfHanoi.towerOfHanoi(n); + assertArrayEquals(expected, actual.toArray()); + } +}