From c848babd226e9a182608165c771be44ad145aecc Mon Sep 17 00:00:00 2001
From: yuvashreenarayanan3
<85839447+yuvashreenarayanan3@users.noreply.github.com>
Date: Sun, 26 May 2024 17:20:32 +0000
Subject: [PATCH 1/4] Related to #5164 (Redesign of ArrayCombination)
---
.../backtracking/ArrayCombination.java | 41 ++++++++----
.../backtracking/ArrayCombinationTest.java | 66 +++++++++----------
2 files changed, 59 insertions(+), 48 deletions(-)
diff --git a/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java b/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java
index a0b886e6be8a..c39e4048f8ad 100644
--- a/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java
+++ b/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java
@@ -1,5 +1,6 @@
package com.thealgorithms.backtracking;
+import java.util.ArrayList;
import java.util.List;
import java.util.TreeSet;
@@ -8,25 +9,37 @@
* @author TheClerici (git-TheClerici)
*/
public final class ArrayCombination {
- private ArrayCombination() {
+ private ArrayCombination() {
}
- private static int length;
/**
- * Find all combinations of 1..n by creating an array and using backtracking in Combination.java
- * @param n max value of the array.
- * @param k length of combination
- * @return a list of all combinations of length k. If k == 0, return null.
+ * Find all combinations of 1..n using backtracking.
+ *
+ * @param n Max value of the elements.
+ * @param k Length of the combination.
+ * @return A list of all combinations of length k.
+ * Returns an empty list if k is 0 or n is less than k.
*/
- public static List> combination(int n, int k) {
- if (n <= 0) {
- return null;
+ public static List> combination(int n, int k) {
+ if (k <= 0 || n < k) {
+ return new ArrayList<>(); // Return empty list for invalid input
}
- length = k;
- Integer[] arr = new Integer[n];
- for (int i = 1; i <= n; i++) {
- arr[i - 1] = i;
+
+ List> combinations = new ArrayList<>();
+ combine(combinations, new ArrayList<>(), 1, n, k);
+ return combinations;
+ }
+
+ private static void combine(List> combinations, List current, int start, int n, int k) {
+ if (current.size() == k) { // Base case: combination found
+ combinations.add(new ArrayList<>(current)); // Copy to avoid modification
+ return;
+ }
+
+ for (int i = start; i <= n; i++) {
+ current.add(i);
+ combine(combinations, current, i + 1, n, k); // Recursive call
+ current.remove(current.size() - 1); // Backtrack
}
- return Combination.combination(arr, length);
}
}
diff --git a/src/test/java/com/thealgorithms/backtracking/ArrayCombinationTest.java b/src/test/java/com/thealgorithms/backtracking/ArrayCombinationTest.java
index 23fa5d54574c..e3bad572fac9 100644
--- a/src/test/java/com/thealgorithms/backtracking/ArrayCombinationTest.java
+++ b/src/test/java/com/thealgorithms/backtracking/ArrayCombinationTest.java
@@ -1,51 +1,49 @@
package com.thealgorithms.backtracking;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertNull;
+import java.util.ArrayList;
import java.util.List;
-import java.util.TreeSet;
-import org.junit.jupiter.api.Test;
+
+import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertEquals;
public class ArrayCombinationTest {
@Test
- void testNBeingZeroOrLess() {
- List> zeroResult = ArrayCombination.combination(0, 1);
- List> negativeResult = ArrayCombination.combination(-1, 1);
- assertNull(zeroResult);
- assertNull(negativeResult);
+ public void testCombination() {
+ // Test case 1: n = 4, k = 2
+ List> expected = new ArrayList<>();
+ expected.add(List.of(1, 2));
+ expected.add(List.of(1, 3));
+ expected.add(List.of(1, 4));
+ expected.add(List.of(2, 3));
+ expected.add(List.of(2, 4));
+ expected.add(List.of(3, 4));
+
+ List> actual = ArrayCombination.combination(4, 2);
+
+ assertEquals(expected, actual);
}
@Test
- void testNoLengthElement() {
- List> result = ArrayCombination.combination(2, 0);
- assertNull(result);
- }
+ public void testEmptyCombination() {
+ // Test case 2: n = 4, k = 0 (invalid input)
+ List> expected = new ArrayList<>();
+ List> actual = ArrayCombination.combination(4, 0);
- @Test
- void testLengthOne() {
- List> result = ArrayCombination.combination(2, 1);
- assert result != null;
- assertEquals(1, result.get(0).iterator().next());
- assertEquals(2, result.get(1).iterator().next());
+ assertEquals(expected, actual);
}
@Test
- void testLengthTwo() {
- List> result = ArrayCombination.combination(2, 2);
- assert result != null;
- Integer[] arr = result.get(0).toArray(new Integer[2]);
- assertEquals(1, arr[0]);
- assertEquals(2, arr[1]);
- }
+ public void testSingleElementCombinations() {
+ // Test case 3: n = 3, k = 1
+ List> expected = new ArrayList<>();
+ expected.add(List.of(1));
+ expected.add(List.of(2));
+ expected.add(List.of(3));
- @Test
- void testLengthFive() {
- List> result = ArrayCombination.combination(10, 5);
- assert result != null;
- Integer[] arr = result.get(0).toArray(new Integer[5]);
- assertEquals(1, arr[0]);
- assertEquals(5, arr[4]);
+ List> actual = ArrayCombination.combination(3, 1);
+
+ assertEquals(expected, actual);
}
-}
+}
\ No newline at end of file
From 4b1d743770338f9423f8008f76f515162c3e23d6 Mon Sep 17 00:00:00 2001
From: yuvashreenarayanan3
<85839447+yuvashreenarayanan3@users.noreply.github.com>
Date: Sun, 26 May 2024 17:35:11 +0000
Subject: [PATCH 2/4] Checkstyle fix
---
.../com/thealgorithms/backtracking/ArrayCombination.java | 1 -
.../com/thealgorithms/backtracking/ArrayCombinationTest.java | 5 ++---
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java b/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java
index c39e4048f8ad..17d4df5d06ef 100644
--- a/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java
+++ b/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java
@@ -2,7 +2,6 @@
import java.util.ArrayList;
import java.util.List;
-import java.util.TreeSet;
/**
* Finds all permutations of 1...n of length k
diff --git a/src/test/java/com/thealgorithms/backtracking/ArrayCombinationTest.java b/src/test/java/com/thealgorithms/backtracking/ArrayCombinationTest.java
index e3bad572fac9..f2005a74a7cd 100644
--- a/src/test/java/com/thealgorithms/backtracking/ArrayCombinationTest.java
+++ b/src/test/java/com/thealgorithms/backtracking/ArrayCombinationTest.java
@@ -1,10 +1,9 @@
package com.thealgorithms.backtracking;
-
import java.util.ArrayList;
import java.util.List;
-import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class ArrayCombinationTest {
@@ -46,4 +45,4 @@ public void testSingleElementCombinations() {
assertEquals(expected, actual);
}
-}
\ No newline at end of file
+}
From a991febe9830e9082a117a07843777a5928936bb Mon Sep 17 00:00:00 2001
From: yuvashreenarayanan3
<85839447+yuvashreenarayanan3@users.noreply.github.com>
Date: Sun, 26 May 2024 17:39:23 +0000
Subject: [PATCH 3/4] Clang_format
---
.../java/com/thealgorithms/backtracking/ArrayCombination.java | 4 ++--
.../com/thealgorithms/backtracking/ArrayCombinationTest.java | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java b/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java
index 17d4df5d06ef..22969cbcf55b 100644
--- a/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java
+++ b/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java
@@ -8,7 +8,7 @@
* @author TheClerici (git-TheClerici)
*/
public final class ArrayCombination {
- private ArrayCombination() {
+ private ArrayCombination() {
}
/**
@@ -30,7 +30,7 @@ public static List> combination(int n, int k) {
}
private static void combine(List> combinations, List current, int start, int n, int k) {
- if (current.size() == k) { // Base case: combination found
+ if (current.size() == k) { // Base case: combination found
combinations.add(new ArrayList<>(current)); // Copy to avoid modification
return;
}
diff --git a/src/test/java/com/thealgorithms/backtracking/ArrayCombinationTest.java b/src/test/java/com/thealgorithms/backtracking/ArrayCombinationTest.java
index f2005a74a7cd..8d78d6623276 100644
--- a/src/test/java/com/thealgorithms/backtracking/ArrayCombinationTest.java
+++ b/src/test/java/com/thealgorithms/backtracking/ArrayCombinationTest.java
@@ -1,10 +1,10 @@
package com.thealgorithms.backtracking;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+
import java.util.ArrayList;
import java.util.List;
-
import org.junit.jupiter.api.Test;
-import static org.junit.jupiter.api.Assertions.assertEquals;
public class ArrayCombinationTest {
From 82aab4e19c49ebfafefd416c3071c2c1a8798e43 Mon Sep 17 00:00:00 2001
From: vil02
Date: Wed, 10 Jul 2024 19:11:18 +0200
Subject: [PATCH 4/4] refactor: cleanup
---
.../backtracking/ArrayCombination.java | 20 ++++---
.../backtracking/ArrayCombinationTest.java | 54 ++++++++-----------
2 files changed, 30 insertions(+), 44 deletions(-)
diff --git a/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java b/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java
index 22969cbcf55b..a064decc0eb7 100644
--- a/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java
+++ b/src/main/java/com/thealgorithms/backtracking/ArrayCombination.java
@@ -4,28 +4,26 @@
import java.util.List;
/**
- * Finds all permutations of 1...n of length k
- * @author TheClerici (git-TheClerici)
+ * Finds all combinations of 0...n-1 of length k
*/
public final class ArrayCombination {
private ArrayCombination() {
}
/**
- * Find all combinations of 1..n using backtracking.
+ * Finds all combinations of length k of 0..n-1 using backtracking.
*
- * @param n Max value of the elements.
+ * @param n Number of the elements.
* @param k Length of the combination.
* @return A list of all combinations of length k.
- * Returns an empty list if k is 0 or n is less than k.
*/
public static List> combination(int n, int k) {
- if (k <= 0 || n < k) {
- return new ArrayList<>(); // Return empty list for invalid input
+ if (n < 0 || k < 0 || k > n) {
+ throw new IllegalArgumentException("Wrong input.");
}
List> combinations = new ArrayList<>();
- combine(combinations, new ArrayList<>(), 1, n, k);
+ combine(combinations, new ArrayList<>(), 0, n, k);
return combinations;
}
@@ -35,10 +33,10 @@ private static void combine(List> combinations, List curr
return;
}
- for (int i = start; i <= n; i++) {
+ for (int i = start; i < n; i++) {
current.add(i);
- combine(combinations, current, i + 1, n, k); // Recursive call
- current.remove(current.size() - 1); // Backtrack
+ combine(combinations, current, i + 1, n, k);
+ current.removeLast(); // Backtrack
}
}
}
diff --git a/src/test/java/com/thealgorithms/backtracking/ArrayCombinationTest.java b/src/test/java/com/thealgorithms/backtracking/ArrayCombinationTest.java
index 8d78d6623276..a4ff7fe892d5 100644
--- a/src/test/java/com/thealgorithms/backtracking/ArrayCombinationTest.java
+++ b/src/test/java/com/thealgorithms/backtracking/ArrayCombinationTest.java
@@ -1,48 +1,36 @@
package com.thealgorithms.backtracking;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import com.thealgorithms.maths.BinomialCoefficient;
import java.util.ArrayList;
import java.util.List;
-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 ArrayCombinationTest {
-
- @Test
- public void testCombination() {
- // Test case 1: n = 4, k = 2
- List> expected = new ArrayList<>();
- expected.add(List.of(1, 2));
- expected.add(List.of(1, 3));
- expected.add(List.of(1, 4));
- expected.add(List.of(2, 3));
- expected.add(List.of(2, 4));
- expected.add(List.of(3, 4));
-
- List> actual = ArrayCombination.combination(4, 2);
-
- assertEquals(expected, actual);
+ @ParameterizedTest
+ @MethodSource("regularInputs")
+ void testCombination(int n, int k, List> expected) {
+ assertEquals(expected.size(), BinomialCoefficient.binomialCoefficient(n, k));
+ assertEquals(expected, ArrayCombination.combination(n, k));
}
- @Test
- public void testEmptyCombination() {
- // Test case 2: n = 4, k = 0 (invalid input)
- List> expected = new ArrayList<>();
- List> actual = ArrayCombination.combination(4, 0);
-
- assertEquals(expected, actual);
+ @ParameterizedTest
+ @MethodSource("wrongInputs")
+ void testCombinationThrows(int n, int k) {
+ assertThrows(IllegalArgumentException.class, () -> ArrayCombination.combination(n, k));
}
- @Test
- public void testSingleElementCombinations() {
- // Test case 3: n = 3, k = 1
- List> expected = new ArrayList<>();
- expected.add(List.of(1));
- expected.add(List.of(2));
- expected.add(List.of(3));
-
- List> actual = ArrayCombination.combination(3, 1);
+ private static Stream regularInputs() {
+ return Stream.of(Arguments.of(0, 0, List.of(new ArrayList())), Arguments.of(1, 0, List.of(new ArrayList())), Arguments.of(1, 1, List.of(List.of(0))), Arguments.of(3, 0, List.of(new ArrayList())), Arguments.of(3, 1, List.of(List.of(0), List.of(1), List.of(2))),
+ Arguments.of(4, 2, List.of(List.of(0, 1), List.of(0, 2), List.of(0, 3), List.of(1, 2), List.of(1, 3), List.of(2, 3))));
+ }
- assertEquals(expected, actual);
+ private static Stream wrongInputs() {
+ return Stream.of(Arguments.of(-1, 0), Arguments.of(0, -1), Arguments.of(2, 100));
}
}