From b19b9691dfb1410e3cc617114cb6472428b33ea6 Mon Sep 17 00:00:00 2001 From: Stanley Halka Date: Sun, 13 Nov 2016 17:51:23 -0800 Subject: [PATCH 1/8] 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/8] 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/8] 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/8] 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/8] 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/8] 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); } From e7e6be0de5c77533ecc70d4853ad1e61d7681012 Mon Sep 17 00:00:00 2001 From: sam Date: Thu, 9 Mar 2017 21:35:16 -0600 Subject: [PATCH 7/8] adds xml parser test outline --- src/test/java/XMLParserTest.java | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/test/java/XMLParserTest.java diff --git a/src/test/java/XMLParserTest.java b/src/test/java/XMLParserTest.java new file mode 100644 index 0000000..5416e1b --- /dev/null +++ b/src/test/java/XMLParserTest.java @@ -0,0 +1,26 @@ +/** + * Created by sam on 1/9/17. + */ +public class XMLParserTest { + + // this will test a few xml files + // take an xml file, parse to json, output to file + // take an optional second parameter which is a json file that explains the hierarchy of the xml + // a few tests with second parameter, a few without (how does it work without understanding the hierarchy + + + // the algo has an underlying parser that does two things: + /* + 1. reads a text file, understands new lines(maybe strips them out) and trims the file to the first tag + 2. with each tag, denoted by <.*>, finds closing tag , or finds closing tag of a different tag + a. with its own closing tag, creates object with tag as prop name, and + i. string contents as value // contents + ii. or restarts parser at new tag // stuff + b. with closing tag of different tag // ......... + i. goes from tag to tag2, makes objects and restarts parser to recurse each closing/then/opening tag including open tag2 + + then the algo outputs that to json, formatted nicely? what is true json? + + */ + +} From 82f031682b05affc13d510db1a0efeb970d0c9ae Mon Sep 17 00:00:00 2001 From: sam Date: Thu, 9 Mar 2017 21:38:39 -0600 Subject: [PATCH 8/8] implements parentheses problem #32 --- src/main/java/Parentheses.java | 85 ++++++++++++++++++++++++++++++ src/test/java/ParenthesesTest.java | 51 ++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 src/main/java/Parentheses.java create mode 100644 src/test/java/ParenthesesTest.java diff --git a/src/main/java/Parentheses.java b/src/main/java/Parentheses.java new file mode 100644 index 0000000..c833c3b --- /dev/null +++ b/src/main/java/Parentheses.java @@ -0,0 +1,85 @@ +import java.util.Arrays; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +/** + * Created by sam on 3/7/17. + */ +public class Parentheses { + + public static List generateParentheses(int n) { + + if(n == 0) { + return new LinkedList(Arrays.asList("")); + } + if(n == 1) { + return new LinkedList(Arrays.asList("()")); + } + // brute force is to start with a string of n good parentheses '()' + // then starting from right, grab first open parentheses, move to the left until at start + // each iteration check for valid set of parentheses, and add to results list + // then do n-- and find next open parentheses, to find all n open parentheses + // actually use a hash set to only keep a set of combos + Set results = new HashSet<>(); + StringBuilder str = new StringBuilder(); + for(int i = 1; i <= n; i++){ + str.append("()"); + } + results.add(str.toString()); + + for(int i = 2; i <= n; i++) { +// int l = str.lastIndexOf("("); + int l = str.indexOf("("); + // grab i-th from front '(' + for(int k = 2; k <= i; k++) { + l = str.indexOf("(", l + 1); + } + // pull that '(' to front + for(int j = l - 1; j >= 0; j--) { + str.setCharAt(j + 1, str.charAt(j)); + str.setCharAt(j, '('); + if(isValidParenthesesString(str.toString()) && ! results.contains(str.toString())) { + results.add(str.toString()); + } + } + } + + for(int i = 1; i < n; i++) { +// int l = str.lastIndexOf("("); + int l = str.indexOf(")"); + // grab i-th from front '(' + for(int k = 2; k <= i; k++) { + l = str.indexOf(")", l + 1); + } + // + for(int j = l - 1; j > 0; j--) { + // in this boolean, replace '(' then length() will count ')' + if (str.substring(j + 2).replace("(", "").length() > str.substring(j + 2).replace(")", "").length()) { + str.setCharAt(j + 1, str.charAt(j)); + str.setCharAt(j, ')'); + if(! results.contains(str.toString()) && isValidParenthesesString(str.toString()) ) { + results.add(str.toString()); + } + } + } + } + return new LinkedList<>(results); + + } + + private static boolean isValidParenthesesString(String s) { + int left = 0; + int right = 0; + for(int i = 0; i < s.length(); i++) { + if(s.charAt(i) == '(') left++; + if(s.charAt(i) == ')') right++; + if(right > left) return false; + } + // if (, left++; if ), right++ + // if right > left, return false + return true; + } + +} diff --git a/src/test/java/ParenthesesTest.java b/src/test/java/ParenthesesTest.java new file mode 100644 index 0000000..bcb06e1 --- /dev/null +++ b/src/test/java/ParenthesesTest.java @@ -0,0 +1,51 @@ +import org.junit.Assert; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Created by sam on 6/17/16. + */ +public class ParenthesesTest { + + + @Test + public void test1() { + List expected = Arrays.asList( + "()"); + Assert.assertEquals(expected.size(), Parentheses.generateParentheses(1).size()); + } + + + @Test + public void test2() { + List expected = Arrays.asList( + "(())", + "()()"); + Assert.assertEquals(expected.size(), Parentheses.generateParentheses(2).size()); + } + + @Test + public void test3() { + List expected = Arrays.asList( + "((()))", + "(()())", + "(())()", + "()(())", + "()()()"); +// Assert.assertEquals(expected, Parentheses.generateParentheses(3)); + Assert.assertEquals(expected.size(), Parentheses.generateParentheses(3).size()); + } + + + @Test + public void test4() { + List expected = Arrays.asList("()()()()", "(())()()", "(((())))", "()((()))", "(()())()", "(()(()))", "()()(())", "()(()())", "((()()))", "((()))()", "((())())"); +// Assert.assertEquals(expected, Parentheses.generateParentheses(4)); + Assert.assertEquals(expected.size(), Parentheses.generateParentheses(4).size()); + } + + +}