Skip to content

feat: Two new algos 👍 TowerofHanoi.java and GenerateUniqueSubset.java added #5546

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

Closed
wants to merge 26 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
37bb532
LinkedList added
Tuhinm2002 Oct 1, 2024
17d0ca3
LinkedList added
Tuhinm2002 Oct 1, 2024
ee3cacb
feat: recursion subsets added
Tuhinm2002 Oct 1, 2024
9e5057b
Update and rename SubsetsTest.java to GenerateSubsetsTest.java
Tuhinm2002 Oct 2, 2024
e49a414
Update and rename Subsets.java to GenerateSubsets.java
Tuhinm2002 Oct 2, 2024
89687c8
Update GenerateSubsets.java
Tuhinm2002 Oct 2, 2024
eceb162
Update GenerateSubsetsTest.java
Tuhinm2002 Oct 2, 2024
6d840a2
Update GenerateSubsets.java
Tuhinm2002 Oct 2, 2024
5043123
Update GenerateSubsets.java
Tuhinm2002 Oct 2, 2024
61a81c9
Update GenerateSubsets.java
Tuhinm2002 Oct 2, 2024
d3d154e
Update GenerateSubsetsTest.java
Tuhinm2002 Oct 2, 2024
25874a9
Update GenerateSubsets.java
Tuhinm2002 Oct 2, 2024
ba81599
Update GenerateSubsetsTest.java
Tuhinm2002 Oct 2, 2024
c14d684
Merge branch 'master' into master
Tuhinm2002 Oct 2, 2024
0d202a6
Merge branch 'master' into master
siriak Oct 2, 2024
b11a6be
Merge branch 'TheAlgorithms:master' into master
Tuhinm2002 Oct 2, 2024
b3c0ee6
feat: new recursion algo added
Tuhinm2002 Oct 3, 2024
4775400
Merge branch 'TheAlgorithms:master' into master
Tuhinm2002 Oct 3, 2024
316ae83
Update GenerateSubsets.java
Tuhinm2002 Oct 3, 2024
3722690
Update GenerateUniqueSubsetsTest.java
Tuhinm2002 Oct 3, 2024
a3e34f7
Update TowerOfHanoiTest.java
Tuhinm2002 Oct 3, 2024
283f35b
Update GenerateUniqueSubsets.java
Tuhinm2002 Oct 3, 2024
09fba41
Merge branch 'master' into master
Tuhinm2002 Oct 4, 2024
68a7efe
Merge branch 'master' into master
Tuhinm2002 Oct 4, 2024
1b0c0b8
Merge branch 'master' into master
Tuhinm2002 Oct 4, 2024
52715aa
Merge branch 'master' into master
Tuhinm2002 Oct 5, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
import java.util.ArrayList;
import java.util.List;

/**
* Finds all permutations of given array
* @author Tuhin Mondal (<a href="https://github.com/tuhinm2002">Git-Tuhin Mondal</a>)
*/

public final class GenerateSubsets {

private GenerateSubsets() {
Expand Down
Original file line number Diff line number Diff line change
@@ -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 (<a href="https://github.com/tuhinm2002">Git-Tuhin Mondal</a>)
*/

public final class GenerateUniqueSubsets {

private GenerateUniqueSubsets() {
throw new UnsupportedOperationException("Utility class");
}

public static List<String> subsetRecursion(String str) {
Set<String> ans = doRecursion("", str);
List<String> a = new ArrayList<>(ans.stream().toList());
Collections.sort(a);
return a;
}

private static Set<String> doRecursion(String p, String up) {
if (up.isEmpty()) {
Set<String> list = new HashSet<>();
list.add(p);
return list;
}

// Taking the character
char ch = up.charAt(0);
// Adding the character in the recursion
Set<String> left = doRecursion(p + ch, up.substring(1));
// Not adding the character in the recursion
Set<String> right = doRecursion(p, up.substring(1));

left.addAll(right);

return left;
}
}
32 changes: 32 additions & 0 deletions src/main/java/com/thealgorithms/Recursion/TowerOfHanoi.java
Original file line number Diff line number Diff line change
@@ -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 (<a href="https://github.com/tuhinm2002">Git-Tuhin Mondal</a>)
*/

public final class TowerOfHanoi {
private TowerOfHanoi() {
throw new UnsupportedOperationException("Utility class");
}

public static List<String> towerOfHanoi(int n) {
List<String> arr = new ArrayList<>();
recursionApproach(n, 'A', 'B', 'C', arr);
return arr;
}

public static void recursionApproach(int n, char a, char b, char c, List<String> 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);
}
}
4 changes: 2 additions & 2 deletions src/main/java/com/thealgorithms/ciphers/DES.java
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<T> other) {
return other.elements.containsAll(elements);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<T> other) {
Set<Pair<T>> union = new HashSet<>(elements);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<T> otherSet) {
return otherSet.setA.containsAll(setA) && otherSet.setR.containsAll(setR);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand All @@ -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];
Expand Down Expand Up @@ -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) {
Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand Down Expand Up @@ -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++) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}
Expand All @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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<String> 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<String> ans = GenerateUniqueSubsets.subsetRecursion(str);
assertArrayEquals(ans.toArray(), expected);
}

@Test
void subsetRecursionTestThree() {
String str = "aaa";
String[] expected = new String[] {"", "a", "aa", "aaa"};

List<String> ans = GenerateUniqueSubsets.subsetRecursion(str);
assertArrayEquals(ans.toArray(), expected);
}
}
42 changes: 42 additions & 0 deletions src/test/java/com/thealgorithms/Recursion/TowerOfHanoiTest.java
Original file line number Diff line number Diff line change
@@ -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<String> 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<String> 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<String> actual = TowerOfHanoi.towerOfHanoi(n);
assertArrayEquals(expected, actual.toArray());
}
}