From b19b9691dfb1410e3cc617114cb6472428b33ea6 Mon Sep 17 00:00:00 2001 From: Stanley Halka Date: Sun, 13 Nov 2016 17:51:23 -0800 Subject: [PATCH 1/6] initial commit for partitioning palindromes problem --- src/main/java/PartitioningPalindromes.java | 12 +++ .../java/PartitioningPalindromesTest.java | 96 +++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 src/main/java/PartitioningPalindromes.java create mode 100644 src/test/java/PartitioningPalindromesTest.java diff --git a/src/main/java/PartitioningPalindromes.java b/src/main/java/PartitioningPalindromes.java new file mode 100644 index 0000000..962c519 --- /dev/null +++ b/src/main/java/PartitioningPalindromes.java @@ -0,0 +1,12 @@ +import java.util.LinkedList; +import java.util.List; + +class PartitioningPalindromes { + /** + * Given a string, print all palindromic partitions. + */ + public static List> partition(String input) { + List> palindromes = new LinkedList>(); + return palindromes; + } +} diff --git a/src/test/java/PartitioningPalindromesTest.java b/src/test/java/PartitioningPalindromesTest.java new file mode 100644 index 0000000..147a5a4 --- /dev/null +++ b/src/test/java/PartitioningPalindromesTest.java @@ -0,0 +1,96 @@ +import org.junit.Assert; +import org.junit.Test; + +import java.util.Arrays; +import java.util.List; + +public class PartitioningPalindromesTest { + + public void compareExpectedWithActual(List> expected, List> actual) { + Assert.assertTrue("Size between expected and actual needs to match", expected.size() == actual.size()); + for (List expectedPartitioning : expected) { + String errorMessage = "Failed to find: '" + expectedPartitioning + "' in actuals"; + Assert.assertTrue(errorMessage, actual.contains(expectedPartitioning)); + } + } + + @Test + public void testCase1() { + String input = "fff"; + List> expected = Arrays.asList( + Arrays.asList("f", "f", "f"), + Arrays.asList("f", "ff"), + Arrays.asList("ff", "f"), + Arrays.asList("fff") + ); + List> actual = PartitioningPalindromes.partition(input); + compareExpectedWithActual(expected, actual); + } + + @Test + public void testCase2() { + String input = "racecar"; + List> expected = Arrays.asList( + Arrays.asList("r", "a", "c", "e", "c", "a", "r"), + Arrays.asList("r", "a", "cec", "a", "r"), + Arrays.asList("r", "aceca", "r"), + Arrays.asList("racecar") + ); + List> actual = PartitioningPalindromes.partition(input); + compareExpectedWithActual(expected, actual); + } + + @Test + public void testCase3() { + String input = "abbcccdddd"; + // this problem is an example of combinatorial explosion + List> expected = Arrays.asList( + // varying the 'd' piece of input only + Arrays.asList("b", "b", "c", "c", "c", "d", "d", "d", "d"), + Arrays.asList("b", "b", "c", "c", "c", "d", "d", "dd"), + Arrays.asList("b", "b", "c", "c", "c", "d", "ddd"), + Arrays.asList("b", "b", "c", "c", "c", "dddd"), + // varying the 'c' piece of input only + Arrays.asList("b", "b", "c", "cc", "d", "d", "d", "d"), + Arrays.asList("b", "b", "cc", "c", "d", "d", "d", "d"), + Arrays.asList("b", "b", "ccc", "d", "d", "d", "d"), + // varying the 'b' piece of input only + Arrays.asList("bb", "c", "c", "c", "d", "d", "d", "d"), + + // varying the 'd' piece of input with change to 'ccc' + Arrays.asList("b", "b", "c", "cc", "d", "d", "d", "d"), + Arrays.asList("b", "b", "c", "cc", "d", "d", "dd"), + Arrays.asList("b", "b", "c", "cc", "d", "ddd"), + Arrays.asList("b", "b", "c", "cc", "dddd"), + // varying the 'd' piece of input with change to 'ccc' + Arrays.asList("b", "b", "cc", "c", "d", "d", "d", "d"), + Arrays.asList("b", "b", "cc", "c", "d", "d", "dd"), + Arrays.asList("b", "b", "cc", "c", "d", "ddd"), + Arrays.asList("b", "b", "cc", "c", "dddd"), + // varying the 'd' piece of input with change to 'ccc' + Arrays.asList("b", "b", "ccc", "d", "d", "d", "d"), + Arrays.asList("b", "b", "ccc", "d", "d", "dd"), + Arrays.asList("b", "b", "ccc", "d", "ddd"), + Arrays.asList("b", "b", "ccc", "dddd"), + + // varying the 'd' piece of input with change to 'ccc' and 'bb' + Arrays.asList("bb", "c", "cc", "d", "d", "d", "d"), + Arrays.asList("bb", "c", "cc", "d", "d", "dd"), + Arrays.asList("bb", "c", "cc", "d", "ddd"), + Arrays.asList("bb", "c", "cc", "dddd"), + // varying the 'd' piece of input with change to 'ccc' and 'bb' + Arrays.asList("bb", "cc", "c", "d", "d", "d", "d"), + Arrays.asList("bb", "cc", "c", "d", "d", "dd"), + Arrays.asList("bb", "cc", "c", "d", "ddd"), + Arrays.asList("bb", "cc", "c", "dddd"), + // varying the 'd' piece of input with change to 'ccc' and 'bb' + Arrays.asList("bb", "ccc", "d", "d", "d", "d"), + Arrays.asList("bb", "ccc", "d", "d", "dd"), + Arrays.asList("bb", "ccc", "d", "ddd"), + Arrays.asList("bb", "ccc", "dddd") + ); + List> actual = PartitioningPalindromes.partition(input); + compareExpectedWithActual(expected, actual); + } + +} From ec51df847561f12bdc80455566961d7bbfcb6cc3 Mon Sep 17 00:00:00 2001 From: sam Date: Tue, 15 Nov 2016 18:00:33 -0600 Subject: [PATCH 2/6] draws out a few tests to show algo behavior --- src/main/java/PartitioningPalindromes.java | 118 +++++++++++++++++++++ 1 file changed, 118 insertions(+) diff --git a/src/main/java/PartitioningPalindromes.java b/src/main/java/PartitioningPalindromes.java index 962c519..3f30421 100644 --- a/src/main/java/PartitioningPalindromes.java +++ b/src/main/java/PartitioningPalindromes.java @@ -7,6 +7,124 @@ class PartitioningPalindromes { */ public static List> partition(String input) { List> palindromes = new LinkedList>(); + /* + 1. first start with exploded string + or + 2. first start with full string + + full string: + "abbcccdddd" + palLength = n = 10 + isPalindrome? + + n - 1 + "a" "bbcccdddd" + "abbcccddd" "d" + + n - 2 + "ab" "bcccdddd" + "a" "b" "bcccdddd" + "a" "bbcccddd" "d" + "abbcccdd" "dd" + "abbcccdd" "d" "d" + + n - 3 + "abb" "cccdddd" + "a" "bb" "cccdddd" + "ab" "b" "cccdddd" + "a" "b" "b" "cccdddd" + "ab" "bcccddd" "d" + "a" "b" "bcccddd" "d" + "a" "bbcccdd" "dd" + "a" "bbcccdd" "d" "d" + "abbcccd" "ddd" + + n - 4 + "abbc" "ccdddd" + "abb" "cccddd" "d" + "ab" "bcccdd" "dd" + "a" "bbcccd" "ddd" + "abbccc" "dddd" + + n - 5 + "abbcc" "cdddd" + "abbc" "ccddd" "d" + "abb" "cccdd" "dd" + "ab" "bcccd" "ddd" + "a" "bbccc" "dddd" + "abbcc" "cdddd" + + n - 6 + "abbccc" "dddd" + "abbcc" "cddd" "d" + "abbc" "ccdd" "dd" + "abb" "cccd" "ddd" + "ab" "bccc" "dddd" + "a" "bbcc" "cdddd" + "abbc" "ccdddd" + + n - 7 + "abbcccd" "ddd" + "abbccc" "ddd" "d" + "abbcc" "cdd" "dd" + "abbc" "ccd" "ddd" + "abb" "ccc" "dddd" + "ab" "bcc" "cdddd" + "a" "bbc" "ccdddd" + "abb" "cccdddd" + + n - 8 + "abbcccdd" "dd" + "abbcccd" "dd" "d" + "abbccc" "dd" "dd" + "abbcc" "cd" "ddd" + "abbc" "cc" "dddd" + "abb" "cc" "cdddd" + "ab" "bc" "ccdddd" + "a" "bb" "cccdddd" + "ab" "bcccdddd" + + n - 9 + "abbcccddd" "d" + "abbcccdd" "d" d" + "abbcccd" "d" "dd" + "abbccc" "d" "ddd" + "abbcc" "c" "dddd" + "abbc" "c" "cdddd" + "abb" "c" "ccdddd" + "ab" "b" "cccdddd" + "a" "b" "bcccdddd" + + + + + + + + + */ + return palindromes; } + + private static boolean isPalindrome(String input) { + char[] str = input.toCharArray(); + int left, right; + if(str.length % 2 == 1) { + left = ((str.length - 1) / 2) - 1; + right = left + 2; + } else { + left = (str.length / 2) - 1; + right = left + 1; + } + while(left >= 0 && right < str.length) { + if(str[left] != str[right]) { + return false; + } else { + left--; + right++; + } + } + return true; + } } From 378e1d93cecd2c6d60366483f978d1bf1c1596a6 Mon Sep 17 00:00:00 2001 From: sam Date: Tue, 15 Nov 2016 19:16:55 -0600 Subject: [PATCH 3/6] adds isPalindrome(String s) and isPalindrome(List l) --- src/main/java/PartitioningPalindromes.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/java/PartitioningPalindromes.java b/src/main/java/PartitioningPalindromes.java index 3f30421..ff77b9e 100644 --- a/src/main/java/PartitioningPalindromes.java +++ b/src/main/java/PartitioningPalindromes.java @@ -94,6 +94,7 @@ public static List> partition(String input) { "abb" "c" "ccdddd" "ab" "b" "cccdddd" "a" "b" "bcccdddd" + "a" "bbcccdddd" @@ -107,6 +108,14 @@ public static List> partition(String input) { return palindromes; } + private static boolean isPalindrome(List input) { + for (String partition : input) { + if(! isPalindrome(partition)) { + return false; + } + } + return true; + } private static boolean isPalindrome(String input) { char[] str = input.toCharArray(); int left, right; From 6bfc9e14858ec19e90b53daa6bf368c89914c66d Mon Sep 17 00:00:00 2001 From: sam Date: Mon, 5 Dec 2016 22:59:28 -0600 Subject: [PATCH 4/6] implements partition method, fails tests --- src/main/java/PartitioningPalindromes.java | 157 +++++++----------- .../java/PartitioningPalindromesTest.java | 2 + 2 files changed, 61 insertions(+), 98 deletions(-) diff --git a/src/main/java/PartitioningPalindromes.java b/src/main/java/PartitioningPalindromes.java index ff77b9e..ba91b2c 100644 --- a/src/main/java/PartitioningPalindromes.java +++ b/src/main/java/PartitioningPalindromes.java @@ -5,107 +5,65 @@ class PartitioningPalindromes { /** * Given a string, print all palindromic partitions. */ - public static List> partition(String input) { - List> palindromes = new LinkedList>(); - /* - 1. first start with exploded string - or - 2. first start with full string - - full string: - "abbcccdddd" - palLength = n = 10 - isPalindrome? - - n - 1 - "a" "bbcccdddd" - "abbcccddd" "d" - - n - 2 - "ab" "bcccdddd" - "a" "b" "bcccdddd" - "a" "bbcccddd" "d" - "abbcccdd" "dd" - "abbcccdd" "d" "d" - - n - 3 - "abb" "cccdddd" - "a" "bb" "cccdddd" - "ab" "b" "cccdddd" - "a" "b" "b" "cccdddd" - "ab" "bcccddd" "d" - "a" "b" "bcccddd" "d" - "a" "bbcccdd" "dd" - "a" "bbcccdd" "d" "d" - "abbcccd" "ddd" - - n - 4 - "abbc" "ccdddd" - "abb" "cccddd" "d" - "ab" "bcccdd" "dd" - "a" "bbcccd" "ddd" - "abbccc" "dddd" - - n - 5 - "abbcc" "cdddd" - "abbc" "ccddd" "d" - "abb" "cccdd" "dd" - "ab" "bcccd" "ddd" - "a" "bbccc" "dddd" - "abbcc" "cdddd" - - n - 6 - "abbccc" "dddd" - "abbcc" "cddd" "d" - "abbc" "ccdd" "dd" - "abb" "cccd" "ddd" - "ab" "bccc" "dddd" - "a" "bbcc" "cdddd" - "abbc" "ccdddd" - - n - 7 - "abbcccd" "ddd" - "abbccc" "ddd" "d" - "abbcc" "cdd" "dd" - "abbc" "ccd" "ddd" - "abb" "ccc" "dddd" - "ab" "bcc" "cdddd" - "a" "bbc" "ccdddd" - "abb" "cccdddd" - - n - 8 - "abbcccdd" "dd" - "abbcccd" "dd" "d" - "abbccc" "dd" "dd" - "abbcc" "cd" "ddd" - "abbc" "cc" "dddd" - "abb" "cc" "cdddd" - "ab" "bc" "ccdddd" - "a" "bb" "cccdddd" - "ab" "bcccdddd" - - n - 9 - "abbcccddd" "d" - "abbcccdd" "d" d" - "abbcccd" "d" "dd" - "abbccc" "d" "ddd" - "abbcc" "c" "dddd" - "abbc" "c" "cdddd" - "abb" "c" "ccdddd" - "ab" "b" "cccdddd" - "a" "b" "bcccdddd" - "a" "bbcccdddd" - - - - - - + public static List> partition(String input) throws IllegalArgumentException { + if(input.isEmpty() || input == null){ + throw new IllegalArgumentException("invalid inputs to partition(), requires string of length >= 1"); + } + // solution is a single possible palindromic partition + // palindromic partition is a way to split chars of input string that still contains all palindromes + List solution = new LinkedList<>(); - */ + // palindromes is all the possible solutions for str of length = n + List> output = new LinkedList<>(); + if(input.length() == 1) { + solution.add(input); + output.add(solution); + return output; + } - return palindromes; + // we create a List of outputs for each substring of length 1 -> n + List>> outputList = new LinkedList<>(); + + // string.substring is 0 indexed, exclusive top end + solution.add(input.substring(0,1)); + output.add(solution); + outputList.add(output); + // cursor is 0 indexed, like input string, and starts at second char bc input.length > 1 + int cursor = 1; + while(cursor < input.length()) { + String newChar = input.substring(cursor, cursor + 1); + // first add new char to all solutions from previous output + // 1. copy output to newOutput + // 2. for each solution in output:append new char to solution, add new solution to newOutput + List> newOutput = new LinkedList<>(); + for (List subSolution : output) { + subSolution.add(newChar); + newOutput.add(subSolution); + } + // then check all possible substrings from right to left for palindromes + for(int pivot = cursor - 1; pivot >= 0; pivot--) { + String mirror = input.substring(pivot, pivot + 1); + if(mirror.equals(newChar) && isPalindrome(input.substring(pivot + 1, cursor))) { + String palindrome = input.substring(pivot, cursor + 1); + if(pivot == 0) { + solution.clear(); + solution.add(palindrome); + newOutput.add(solution); + } else { + output = outputList.get(pivot - 1); + for (List subSolution : output) { + subSolution.add(palindrome); + newOutput.add(subSolution); + } + } + } + } + outputList.add(newOutput); + cursor++; + } + // return output for string length = n, which is all palindromes for input string + return output; } private static boolean isPalindrome(List input) { @@ -117,6 +75,9 @@ private static boolean isPalindrome(List input) { return true; } private static boolean isPalindrome(String input) { + if(input.isEmpty()) { + return true; + } char[] str = input.toCharArray(); int left, right; if(str.length % 2 == 1) { diff --git a/src/test/java/PartitioningPalindromesTest.java b/src/test/java/PartitioningPalindromesTest.java index 147a5a4..50234a8 100644 --- a/src/test/java/PartitioningPalindromesTest.java +++ b/src/test/java/PartitioningPalindromesTest.java @@ -8,6 +8,8 @@ public class PartitioningPalindromesTest { public void compareExpectedWithActual(List> expected, List> actual) { Assert.assertTrue("Size between expected and actual needs to match", expected.size() == actual.size()); + System.out.print("expected size is " + expected.size()); + System.out.print("actual size is " + actual.size()); for (List expectedPartitioning : expected) { String errorMessage = "Failed to find: '" + expectedPartitioning + "' in actuals"; Assert.assertTrue(errorMessage, actual.contains(expectedPartitioning)); From 9166761015cd54b5bf711b982148242b6a3eb39e Mon Sep 17 00:00:00 2001 From: sam Date: Wed, 7 Dec 2016 20:56:28 -0600 Subject: [PATCH 5/6] fixes implementation, 3rd test fails due to incomplete test cases --- src/main/java/PartitioningPalindromes.java | 13 ++++++++----- src/test/java/PartitioningPalindromesTest.java | 5 ++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/main/java/PartitioningPalindromes.java b/src/main/java/PartitioningPalindromes.java index ba91b2c..51ee469 100644 --- a/src/main/java/PartitioningPalindromes.java +++ b/src/main/java/PartitioningPalindromes.java @@ -38,8 +38,9 @@ public static List> partition(String input) throws IllegalArgumentE // 2. for each solution in output:append new char to solution, add new solution to newOutput List> newOutput = new LinkedList<>(); for (List subSolution : output) { - subSolution.add(newChar); - newOutput.add(subSolution); + solution = new LinkedList<>(subSolution); + solution.add(newChar); + newOutput.add(solution); } // then check all possible substrings from right to left for palindromes for(int pivot = cursor - 1; pivot >= 0; pivot--) { @@ -47,19 +48,21 @@ public static List> partition(String input) throws IllegalArgumentE if(mirror.equals(newChar) && isPalindrome(input.substring(pivot + 1, cursor))) { String palindrome = input.substring(pivot, cursor + 1); if(pivot == 0) { - solution.clear(); + solution = new LinkedList<>(); solution.add(palindrome); newOutput.add(solution); } else { output = outputList.get(pivot - 1); for (List subSolution : output) { - subSolution.add(palindrome); - newOutput.add(subSolution); + solution = new LinkedList<>(subSolution); + solution.add(palindrome); + newOutput.add(solution); } } } } outputList.add(newOutput); + output = newOutput; cursor++; } // return output for string length = n, which is all palindromes for input string diff --git a/src/test/java/PartitioningPalindromesTest.java b/src/test/java/PartitioningPalindromesTest.java index 50234a8..c3af0d7 100644 --- a/src/test/java/PartitioningPalindromesTest.java +++ b/src/test/java/PartitioningPalindromesTest.java @@ -7,9 +7,8 @@ public class PartitioningPalindromesTest { public void compareExpectedWithActual(List> expected, List> actual) { + System.out.print("expected size is " + expected.size() + " and actual size is " + actual.size()); Assert.assertTrue("Size between expected and actual needs to match", expected.size() == actual.size()); - System.out.print("expected size is " + expected.size()); - System.out.print("actual size is " + actual.size()); for (List expectedPartitioning : expected) { String errorMessage = "Failed to find: '" + expectedPartitioning + "' in actuals"; Assert.assertTrue(errorMessage, actual.contains(expectedPartitioning)); @@ -44,7 +43,7 @@ public void testCase2() { @Test public void testCase3() { - String input = "abbcccdddd"; + String input = "bbcccdddd"; // this problem is an example of combinatorial explosion List> expected = Arrays.asList( // varying the 'd' piece of input only From ede4d9b7d4612d1d8daab9ee12d2a7de49841afe Mon Sep 17 00:00:00 2001 From: sam Date: Mon, 2 Jan 2017 14:57:55 -0600 Subject: [PATCH 6/6] implements binary method, fixes 3rd test --- src/main/java/PartitioningPalindromes.java | 49 +++++ .../java/PartitioningPalindromesTest.java | 187 ++++++++++++++---- 2 files changed, 203 insertions(+), 33 deletions(-) diff --git a/src/main/java/PartitioningPalindromes.java b/src/main/java/PartitioningPalindromes.java index 51ee469..224ba87 100644 --- a/src/main/java/PartitioningPalindromes.java +++ b/src/main/java/PartitioningPalindromes.java @@ -69,6 +69,55 @@ public static List> partition(String input) throws IllegalArgumentE return output; } + public static List> partitionBinaryMethod(String input) throws IllegalArgumentException { + List> output = new LinkedList<>(); + // binary method makes a binary number with n - 1 bits, to act as boolean flags + // if the flag is 1 then there is a slice in the string at that space between characters + // iterate from max value of binary number of bits n - 1, i--, i > 0, and check possible solution + + int i = (int) Math.pow(2, input.length() - 1) - 1; + while(i >= 0) { + String bits = Integer.toBinaryString(i); + // bits is string representation of i in binary + // as we decrement, we will need to 0 pad the left of bits + if(bits.length() < input.length() - 1) { + // should use string builder + String pad = ""; + int padLength = input.length() - 1 - bits.length(); + for(int j = padLength; j > 0; j--) { + pad += "0"; + } + bits = pad + bits; + } + + // solution is a unique way to split input string into palindromic partitions + List solution = new LinkedList<>(); + // take binary string of splits and apply to input + // ints c and s, cursor and scissors, cursor is last slice, scissors increments + // when scissors finds a 1 in bit string, cuts substring from cursor to scissors + // then cursor gets moved up to scissors, add substring to solution + for(int s = 0, c = 0; s < bits.length(); s++) { + if(bits.charAt(s) == '1') { + String slice = input.substring(c, s + 1); + c = s + 1; + solution.add(slice); + } + if (bits.length() == s + 1) { + // s is at last char and last char is 0, just grab end of input from cursor + String slice = input.substring(c); + solution.add(slice); + } + } + + // if solution is palindromic, add to output List> + if(isPalindrome(solution)) { + output.add(solution); + } + i--; + } + + return output; + } private static boolean isPalindrome(List input) { for (String partition : input) { if(! isPalindrome(partition)) { diff --git a/src/test/java/PartitioningPalindromesTest.java b/src/test/java/PartitioningPalindromesTest.java index c3af0d7..3be0bd6 100644 --- a/src/test/java/PartitioningPalindromesTest.java +++ b/src/test/java/PartitioningPalindromesTest.java @@ -7,7 +7,6 @@ public class PartitioningPalindromesTest { public void compareExpectedWithActual(List> expected, List> actual) { - System.out.print("expected size is " + expected.size() + " and actual size is " + actual.size()); Assert.assertTrue("Size between expected and actual needs to match", expected.size() == actual.size()); for (List expectedPartitioning : expected) { String errorMessage = "Failed to find: '" + expectedPartitioning + "' in actuals"; @@ -28,6 +27,19 @@ public void testCase1() { compareExpectedWithActual(expected, actual); } + @Test + public void testCaseBinaryMethod1() { + String input = "fff"; + List> expected = Arrays.asList( + Arrays.asList("f", "f", "f"), + Arrays.asList("f", "ff"), + Arrays.asList("ff", "f"), + Arrays.asList("fff") + ); + List> actual = PartitioningPalindromes.partitionBinaryMethod(input); + compareExpectedWithActual(expected, actual); + } + @Test public void testCase2() { String input = "racecar"; @@ -41,56 +53,165 @@ public void testCase2() { compareExpectedWithActual(expected, actual); } + @Test + public void testCaseBinaryMethod2() { + String input = "racecar"; + List> expected = Arrays.asList( + Arrays.asList("r", "a", "c", "e", "c", "a", "r"), + Arrays.asList("r", "a", "cec", "a", "r"), + Arrays.asList("r", "aceca", "r"), + Arrays.asList("racecar") + ); + List> actual = PartitioningPalindromes.partitionBinaryMethod(input); + compareExpectedWithActual(expected, actual); + } + @Test public void testCase3() { String input = "bbcccdddd"; // this problem is an example of combinatorial explosion List> expected = Arrays.asList( - // varying the 'd' piece of input only Arrays.asList("b", "b", "c", "c", "c", "d", "d", "d", "d"), - Arrays.asList("b", "b", "c", "c", "c", "d", "d", "dd"), - Arrays.asList("b", "b", "c", "c", "c", "d", "ddd"), - Arrays.asList("b", "b", "c", "c", "c", "dddd"), - // varying the 'c' piece of input only - Arrays.asList("b", "b", "c", "cc", "d", "d", "d", "d"), - Arrays.asList("b", "b", "cc", "c", "d", "d", "d", "d"), - Arrays.asList("b", "b", "ccc", "d", "d", "d", "d"), - // varying the 'b' piece of input only Arrays.asList("bb", "c", "c", "c", "d", "d", "d", "d"), - - // varying the 'd' piece of input with change to 'ccc' - Arrays.asList("b", "b", "c", "cc", "d", "d", "d", "d"), - Arrays.asList("b", "b", "c", "cc", "d", "d", "dd"), - Arrays.asList("b", "b", "c", "cc", "d", "ddd"), - Arrays.asList("b", "b", "c", "cc", "dddd"), - // varying the 'd' piece of input with change to 'ccc' Arrays.asList("b", "b", "cc", "c", "d", "d", "d", "d"), - Arrays.asList("b", "b", "cc", "c", "d", "d", "dd"), - Arrays.asList("b", "b", "cc", "c", "d", "ddd"), - Arrays.asList("b", "b", "cc", "c", "dddd"), - // varying the 'd' piece of input with change to 'ccc' + Arrays.asList("bb", "cc", "c", "d", "d", "d", "d"), + Arrays.asList("b", "b", "c", "cc", "d", "d", "d", "d"), + Arrays.asList("bb", "c", "cc", "d", "d", "d", "d"), Arrays.asList("b", "b", "ccc", "d", "d", "d", "d"), + Arrays.asList("bb", "ccc", "d", "d", "d", "d"), + Arrays.asList("b", "b", "c", "c", "c", "dd", "d", "d"), + Arrays.asList("bb", "c", "c", "c", "dd", "d", "d"), + Arrays.asList("b", "b", "cc", "c", "dd", "d", "d"), + Arrays.asList("bb", "cc", "c", "dd", "d", "d"), + Arrays.asList("b", "b", "c", "cc", "dd", "d", "d"), + Arrays.asList("bb", "c", "cc", "dd", "d", "d"), + Arrays.asList("b", "b", "ccc", "dd", "d", "d"), + Arrays.asList("bb", "ccc", "dd", "d", "d"), + Arrays.asList("b", "b", "c", "c", "c", "d", "dd", "d"), + Arrays.asList("bb", "c", "c", "c", "d", "dd", "d"), + Arrays.asList("b", "b", "cc", "c", "d", "dd", "d"), + Arrays.asList("bb", "cc", "c", "d", "dd", "d"), + Arrays.asList("b", "b", "c", "cc", "d", "dd", "d"), + Arrays.asList("bb", "c", "cc", "d", "dd", "d"), + Arrays.asList("b", "b", "ccc", "d", "dd", "d"), + Arrays.asList("bb", "ccc", "d", "dd", "d"), + Arrays.asList("b", "b", "c", "c", "c", "ddd", "d"), + Arrays.asList("bb", "c", "c", "c", "ddd", "d"), + Arrays.asList("b", "b", "cc", "c", "ddd", "d"), + Arrays.asList("bb", "cc", "c", "ddd", "d"), + Arrays.asList("b", "b", "c", "cc", "ddd", "d"), + Arrays.asList("bb", "c", "cc", "ddd", "d"), + Arrays.asList("b", "b", "ccc", "ddd", "d"), + Arrays.asList("bb", "ccc", "ddd", "d"), + Arrays.asList("b", "b", "c", "c", "c", "d", "d", "dd"), + Arrays.asList("bb", "c", "c", "c", "d", "d", "dd"), + Arrays.asList("b", "b", "cc", "c", "d", "d", "dd"), + Arrays.asList("bb", "cc", "c", "d", "d", "dd"), + Arrays.asList("b", "b", "c", "cc", "d", "d", "dd"), + Arrays.asList("bb", "c", "cc", "d", "d", "dd"), Arrays.asList("b", "b", "ccc", "d", "d", "dd"), + Arrays.asList("bb", "ccc", "d", "d", "dd"), + Arrays.asList("b", "b", "c", "c", "c", "dd", "dd"), + Arrays.asList("bb", "c", "c", "c", "dd", "dd"), + Arrays.asList("b", "b", "cc", "c", "dd", "dd"), + Arrays.asList("bb", "cc", "c", "dd", "dd"), + Arrays.asList("b", "b", "c", "cc", "dd", "dd"), + Arrays.asList("bb", "c", "cc", "dd", "dd"), + Arrays.asList("b", "b", "ccc", "dd", "dd"), + Arrays.asList("bb", "ccc", "dd", "dd"), + Arrays.asList("b", "b", "c", "c", "c", "d", "ddd"), + Arrays.asList("bb", "c", "c", "c", "d", "ddd"), + Arrays.asList("b", "b", "cc", "c", "d", "ddd"), + Arrays.asList("bb", "cc", "c", "d", "ddd"), + Arrays.asList("b", "b", "c", "cc", "d", "ddd"), + Arrays.asList("bb", "c", "cc", "d", "ddd"), Arrays.asList("b", "b", "ccc", "d", "ddd"), + Arrays.asList("bb", "ccc", "d", "ddd"), + Arrays.asList("b", "b", "c", "c", "c", "dddd"), + Arrays.asList("bb", "c", "c", "c", "dddd"), + Arrays.asList("b", "b", "cc", "c", "dddd"), + Arrays.asList("bb", "cc", "c", "dddd"), Arrays.asList("b", "b", "ccc", "dddd"), + Arrays.asList("bb", "ccc", "dddd"), + Arrays.asList("b", "b", "c", "cc", "dddd"), + Arrays.asList("bb", "c", "cc", "dddd") + ); + List> actual = PartitioningPalindromes.partition(input); + compareExpectedWithActual(expected, actual); + } - // varying the 'd' piece of input with change to 'ccc' and 'bb' - Arrays.asList("bb", "c", "cc", "d", "d", "d", "d"), - Arrays.asList("bb", "c", "cc", "d", "d", "dd"), - Arrays.asList("bb", "c", "cc", "d", "ddd"), - Arrays.asList("bb", "c", "cc", "dddd"), - // varying the 'd' piece of input with change to 'ccc' and 'bb' + + @Test + public void testCaseBinaryMethod3() { + String input = "bbcccdddd"; + // this problem is an example of combinatorial explosion + List> expected = Arrays.asList( + Arrays.asList("b", "b", "c", "c", "c", "d", "d", "d", "d"), + Arrays.asList("bb", "c", "c", "c", "d", "d", "d", "d"), + Arrays.asList("b", "b", "cc", "c", "d", "d", "d", "d"), Arrays.asList("bb", "cc", "c", "d", "d", "d", "d"), - Arrays.asList("bb", "cc", "c", "d", "d", "dd"), - Arrays.asList("bb", "cc", "c", "d", "ddd"), - Arrays.asList("bb", "cc", "c", "dddd"), - // varying the 'd' piece of input with change to 'ccc' and 'bb' + Arrays.asList("b", "b", "c", "cc", "d", "d", "d", "d"), + Arrays.asList("bb", "c", "cc", "d", "d", "d", "d"), + Arrays.asList("b", "b", "ccc", "d", "d", "d", "d"), Arrays.asList("bb", "ccc", "d", "d", "d", "d"), + Arrays.asList("b", "b", "c", "c", "c", "dd", "d", "d"), + Arrays.asList("bb", "c", "c", "c", "dd", "d", "d"), + Arrays.asList("b", "b", "cc", "c", "dd", "d", "d"), + Arrays.asList("bb", "cc", "c", "dd", "d", "d"), + Arrays.asList("b", "b", "c", "cc", "dd", "d", "d"), + Arrays.asList("bb", "c", "cc", "dd", "d", "d"), + Arrays.asList("b", "b", "ccc", "dd", "d", "d"), + Arrays.asList("bb", "ccc", "dd", "d", "d"), + Arrays.asList("b", "b", "c", "c", "c", "d", "dd", "d"), + Arrays.asList("bb", "c", "c", "c", "d", "dd", "d"), + Arrays.asList("b", "b", "cc", "c", "d", "dd", "d"), + Arrays.asList("bb", "cc", "c", "d", "dd", "d"), + Arrays.asList("b", "b", "c", "cc", "d", "dd", "d"), + Arrays.asList("bb", "c", "cc", "d", "dd", "d"), + Arrays.asList("b", "b", "ccc", "d", "dd", "d"), + Arrays.asList("bb", "ccc", "d", "dd", "d"), + Arrays.asList("b", "b", "c", "c", "c", "ddd", "d"), + Arrays.asList("bb", "c", "c", "c", "ddd", "d"), + Arrays.asList("b", "b", "cc", "c", "ddd", "d"), + Arrays.asList("bb", "cc", "c", "ddd", "d"), + Arrays.asList("b", "b", "c", "cc", "ddd", "d"), + Arrays.asList("bb", "c", "cc", "ddd", "d"), + Arrays.asList("b", "b", "ccc", "ddd", "d"), + Arrays.asList("bb", "ccc", "ddd", "d"), + Arrays.asList("b", "b", "c", "c", "c", "d", "d", "dd"), + Arrays.asList("bb", "c", "c", "c", "d", "d", "dd"), + Arrays.asList("b", "b", "cc", "c", "d", "d", "dd"), + Arrays.asList("bb", "cc", "c", "d", "d", "dd"), + Arrays.asList("b", "b", "c", "cc", "d", "d", "dd"), + Arrays.asList("bb", "c", "cc", "d", "d", "dd"), + Arrays.asList("b", "b", "ccc", "d", "d", "dd"), Arrays.asList("bb", "ccc", "d", "d", "dd"), + Arrays.asList("b", "b", "c", "c", "c", "dd", "dd"), + Arrays.asList("bb", "c", "c", "c", "dd", "dd"), + Arrays.asList("b", "b", "cc", "c", "dd", "dd"), + Arrays.asList("bb", "cc", "c", "dd", "dd"), + Arrays.asList("b", "b", "c", "cc", "dd", "dd"), + Arrays.asList("bb", "c", "cc", "dd", "dd"), + Arrays.asList("b", "b", "ccc", "dd", "dd"), + Arrays.asList("bb", "ccc", "dd", "dd"), + Arrays.asList("b", "b", "c", "c", "c", "d", "ddd"), + Arrays.asList("bb", "c", "c", "c", "d", "ddd"), + Arrays.asList("b", "b", "cc", "c", "d", "ddd"), + Arrays.asList("bb", "cc", "c", "d", "ddd"), + Arrays.asList("b", "b", "c", "cc", "d", "ddd"), + Arrays.asList("bb", "c", "cc", "d", "ddd"), + Arrays.asList("b", "b", "ccc", "d", "ddd"), Arrays.asList("bb", "ccc", "d", "ddd"), - Arrays.asList("bb", "ccc", "dddd") + Arrays.asList("b", "b", "c", "c", "c", "dddd"), + Arrays.asList("bb", "c", "c", "c", "dddd"), + Arrays.asList("b", "b", "cc", "c", "dddd"), + Arrays.asList("bb", "cc", "c", "dddd"), + Arrays.asList("b", "b", "ccc", "dddd"), + Arrays.asList("bb", "ccc", "dddd"), + Arrays.asList("b", "b", "c", "cc", "dddd"), + Arrays.asList("bb", "c", "cc", "dddd") ); - List> actual = PartitioningPalindromes.partition(input); + List> actual = PartitioningPalindromes.partitionBinaryMethod(input); compareExpectedWithActual(expected, actual); }