From dd6ffbf14a7c4452baa0407315c8f60e88bcbbfd Mon Sep 17 00:00:00 2001 From: Zachary Miller <2.4.8.16.32.sixtyfour@gmail.com> Date: Tue, 10 Jan 2017 21:38:07 -0700 Subject: [PATCH 1/7] Challenge 11 in Java --- challenge_11/java/zmiller91/BST.java | 268 +++++++++++++++++++++++++++ challenge_11/java/zmiller91/YOP.java | 49 +++++ 2 files changed, 317 insertions(+) create mode 100644 challenge_11/java/zmiller91/BST.java create mode 100644 challenge_11/java/zmiller91/YOP.java diff --git a/challenge_11/java/zmiller91/BST.java b/challenge_11/java/zmiller91/BST.java new file mode 100644 index 000000000..af232fccf --- /dev/null +++ b/challenge_11/java/zmiller91/BST.java @@ -0,0 +1,268 @@ +import java.lang.Integer; + +/** + * @author zmiller + */ + + +class Node { + + public int data; + public Node left; + public Node right; + + public Node(int data) { + this.data = data; + } +} + +class BST extends YOP { + + + /** + * Returns the object containing the provided data point + * + * @param data - value to be deleted + * @param n - tree to look at + */ + public Node search(int data, Node n) { + + // Not found + if (n == null) { + return null; + } + + // Found, return the node + if (data == n.data) { + return n; + } + + // Search the next tree + Node next = data < n.data ? n.left : n.right; + return search(data, next); + } + + /** + * Inserts a value into a BST. + * + * @param data - what to insert + * @param head - where to insert + * @return insert node + */ + public Node insert (int data, Node head) { + + if (head == null) { + return new Node(data); + } + + if (data < head.data) { + if (head.left != null) { + return insert(data, head.left); + } + + head.left = new Node(data); + return head.left; + } + + if (data > head.data) { + if (head.right != null) { + return insert(data, head.right); + } + + head.right = new Node(data); + return head.right; + } + + // Ignore duplicates + return null; + } + + /** + * Removes an element from the list; `n` will remain the head + * after removal; + * + * @param data - value to delete + * @param n - head of subtree + */ + public void remove(int data, Node n) { + remove(search(data, n), n, n); + } + + /** + * Removes an element from the list; `n` will remain the head + * after removal; + * + * @param data - value to delete + * @param n - head of subtree + * @param head - a reference to the head of the tree + */ + private void remove(Node remove, Node n, Node head) { + + // Find the node + if (remove == null){ + return; + } + + // Find the minimum element on the right. + if (remove.right != null) { + + // The smallest can't have a left, if it has a + // right then shift it up + Node smallest = smallest(remove.right); + swap(smallest, remove); + remove(smallest, remove, head); + } + + // Find the largest element on the left. + else if(remove.left != null) { + + // The largest can't have a right, if it has a + // left then shift it up + Node largest = largest(remove.left); + swap(largest, remove); + remove(largest, remove, head); + } + + else { + + System.out.println("pruning..."); + // Has neither + prune(remove, head); + } + } + + /** + * Prints a tree in preorder DFS. + * + * @param head - tree to print + */ + public void print(Node head) { + + if (head == null) { + return; + } + + System.out.println(head.data); + print(head.left); + print(head.right); + } + + /** + * Finds the smalles element in a BST + * + * @param n - root of the tree + * @return the smallest node in the tree + */ + private Node smallest(Node n) { + + if (n == null) { + return null; + } + + while (n.left != null) { + n = n.left; + } + + return n; + } + + /** + * Finds the largest element in a BST + * + * @param n - root of the tree + * @return the largest node in the tree + */ + private Node largest(Node n) { + + if (n == null) { + return null; + } + + while (n.right != null) { + n = n.right; + } + + return n; + } + + /** + * Prunes a tree be removing `data` and it's + * subtree. + * + * @param data - node to prune + * @param head of the tree + */ + private void prune(Node prune, Node head) { + + if (prune == null || head == null || prune == head) { + return; + } + + + System.out.println("------"); + System.out.println(prune.data); + System.out.println(head.data); + System.out.println("------"); + + if(prune.data < head.data && head.left != null) { + if(head.left.data == prune.data) { + head.left = null; + return; + } + + prune(prune, head.left); + } + + if(prune.data > head.data && head.right != null) { + if(head.right.data == prune.data) { + head.right = null; + return; + } + + prune(prune, head.right); + } + } + + /** + * Swaps the two objects + * + * @param a - first node + * @param b - second node + */ + private void swap(Node a, Node b) { + + int temp = a.data; + a.data = b.data; + b.data = temp; + } + + /** + * Executes the problem's solution + * + * @param input + */ + protected void run(String input) { + + // Create the BST + String[] split = input.split("\\|"); + int remove = Integer.parseInt(split[1].trim()); + Node head = null; + for (int i : csvToIntArray(split[0])) { + if (head == null) { + head = new Node(i); + continue; + } + + insert(i, head); + } + + print(head); + remove(remove, head); + System.out.println(); + print(head); + } + + public static void main(String args[]) { + launch(new BST()); + } +} \ No newline at end of file diff --git a/challenge_11/java/zmiller91/YOP.java b/challenge_11/java/zmiller91/YOP.java new file mode 100644 index 000000000..8c818bd33 --- /dev/null +++ b/challenge_11/java/zmiller91/YOP.java @@ -0,0 +1,49 @@ +import java.lang.Integer; +import java.lang.String; +import java.util.Scanner; + +/** + * @author zmiller + */ +public abstract class YOP { + + protected int[] csvToIntArray(String csv) { + String[] strings = csv.split(","); + int[] ints = new int[strings.length]; + for (int i = 0; i < strings.length; i++) { + ints[i] = Integer.parseInt(strings[i].trim()); + } + + return ints; + } + + /** + * Executes the life cycle of the solution. + * + * @param yop - class to execute + */ + protected static void launch(YOP yop) { + + String input; + Scanner scan = new Scanner(System.in); + + System.out.println("Type 'done' to terminate.\n"); + while(true) { + System.out.print("Input: "); + input = scan.nextLine(); + if(input.toLowerCase().equals("done")) { + return; + } + + yop.run(input); + } + } + + /** + * Executes the solution + * + * @param input - command line input + */ + protected abstract void run(String input); + +} From a3e79c692caa2cdbe0f933a0aef4388af4e61691 Mon Sep 17 00:00:00 2001 From: Zachary Miller <2.4.8.16.32.sixtyfour@gmail.com> Date: Wed, 11 Jan 2017 20:24:19 -0700 Subject: [PATCH 2/7] finishing touches --- challenge_11/java/zmiller91/BST.java | 377 +++++++++++---------------- 1 file changed, 157 insertions(+), 220 deletions(-) diff --git a/challenge_11/java/zmiller91/BST.java b/challenge_11/java/zmiller91/BST.java index af232fccf..b06b35b50 100644 --- a/challenge_11/java/zmiller91/BST.java +++ b/challenge_11/java/zmiller91/BST.java @@ -1,246 +1,183 @@ import java.lang.Integer; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; /** * @author zmiller */ - - class Node { + public int data; + public Node left; + public Node right; + public Node parent; - public int data; - public Node left; - public Node right; - - public Node(int data) { - this.data = data; - } + public Node(int data) { + this.data = data; + } } class BST extends YOP { + /** + * Returns the object containing the provided data point + * + * @param data - value to be deleted + * @param n - tree to look at + */ + public Node search(int data, Node n) { + + // Not found + if (n == null) { + return null; + } + + // Found, return the node + if (data == n.data) { + return n; + } + + // Search the next tree + Node next = data < n.data ? n.left : n.right; + return search(data, next); + } - /** - * Returns the object containing the provided data point - * - * @param data - value to be deleted - * @param n - tree to look at - */ - public Node search(int data, Node n) { - - // Not found - if (n == null) { - return null; - } - - // Found, return the node - if (data == n.data) { - return n; - } - - // Search the next tree - Node next = data < n.data ? n.left : n.right; - return search(data, next); - } - - /** - * Inserts a value into a BST. - * - * @param data - what to insert - * @param head - where to insert - * @return insert node - */ - public Node insert (int data, Node head) { - - if (head == null) { - return new Node(data); - } - - if (data < head.data) { - if (head.left != null) { - return insert(data, head.left); - } - - head.left = new Node(data); - return head.left; - } - - if (data > head.data) { - if (head.right != null) { - return insert(data, head.right); - } - - head.right = new Node(data); - return head.right; - } - - // Ignore duplicates - return null; - } - - /** - * Removes an element from the list; `n` will remain the head - * after removal; - * - * @param data - value to delete - * @param n - head of subtree - */ - public void remove(int data, Node n) { - remove(search(data, n), n, n); - } - - /** - * Removes an element from the list; `n` will remain the head - * after removal; - * - * @param data - value to delete - * @param n - head of subtree - * @param head - a reference to the head of the tree - */ - private void remove(Node remove, Node n, Node head) { - - // Find the node - if (remove == null){ - return; - } - - // Find the minimum element on the right. - if (remove.right != null) { - - // The smallest can't have a left, if it has a - // right then shift it up - Node smallest = smallest(remove.right); - swap(smallest, remove); - remove(smallest, remove, head); - } + /** + * Inserts a value into a BST. + * + * @param data - what to insert + * @param head - where to insert + * @return insert node + */ + public Node insert (int data, Node head) { + + if (head == null) { + return new Node(data); + } + + if (data < head.data) { + if (head.left != null) { + return insert(data, head.left); + } + + head.left = new Node(data); + head.left.parent = head; + return head.left; + } + + if (data > head.data) { + if (head.right != null) { + return insert(data, head.right); + } + + head.right = new Node(data); + head.right.parent = head; + return head.right; + } + + // Ignore duplicates + return null; + } - // Find the largest element on the left. - else if(remove.left != null) { + /** + * Removes an element from the list; `n` will remain the head + * after removal; + * + * @param data - value to delete + * @param n - head of subtree + */ + public void remove(int data, Node n) { + remove(search(data, n), n); + } - // The largest can't have a right, if it has a - // left then shift it up - Node largest = largest(remove.left); - swap(largest, remove); - remove(largest, remove, head); - } + /** + * Removes an element from the list; `n` will remain the head + * after removal; + * + * @param data - value to delete + * @param n - head of subtree + * @param head - a reference to the head of the tree + */ + public void remove(Node remove, Node n) { + + if (remove == null){ + return; + } + + // Get the smallest on the right or largest on the left, depending on + // what children are set + Node swap = remove.right != null ? smallest(remove.right) : + remove.left != null ? largest(remove.left) : null; + + // Not a leaf node, recurse + if (swap != null) { + remove.data = swap.data; + remove(swap, remove); + } + + // Leaf node, unset the reference + else { + Node parent = remove.parent; + parent.left = parent.left != remove ? parent.left : null; + parent.right = parent.right != remove ? parent.right : null; + } + } - else { + /** + * Finds the smallest element in a BST + * + * @param n - root of the tree + * @return the smallest node in the tree + */ + private Node smallest(Node n) { + + if (n != null) { + while (n.left != null) { + n = n.left; + } + } + return n; + } - System.out.println("pruning..."); - // Has neither - prune(remove, head); - } - } + /** + * Finds the largest element in a BST + * + * @param n - root of the tree + * @return the largest node in the tree + */ + private Node largest(Node n) { + + if (n != null) { + while (n.right != null) { + n = n.right; + } + } + + return n; + } - /** - * Prints a tree in preorder DFS. - * - * @param head - tree to print - */ - public void print(Node head) { + /** + * Prints a tree in pre-order DFS. + * + * @param head - tree to print + */ + public void print(Node head) { - if (head == null) { - return; - } + if (head == null) { + return; + } System.out.println(head.data); print(head.left); print(head.right); - } - - /** - * Finds the smalles element in a BST - * - * @param n - root of the tree - * @return the smallest node in the tree - */ - private Node smallest(Node n) { - - if (n == null) { - return null; - } - - while (n.left != null) { - n = n.left; - } - - return n; - } - - /** - * Finds the largest element in a BST - * - * @param n - root of the tree - * @return the largest node in the tree - */ - private Node largest(Node n) { - - if (n == null) { - return null; - } - - while (n.right != null) { - n = n.right; - } - - return n; - } - - /** - * Prunes a tree be removing `data` and it's - * subtree. - * - * @param data - node to prune - * @param head of the tree - */ - private void prune(Node prune, Node head) { - - if (prune == null || head == null || prune == head) { - return; - } - - - System.out.println("------"); - System.out.println(prune.data); - System.out.println(head.data); - System.out.println("------"); - - if(prune.data < head.data && head.left != null) { - if(head.left.data == prune.data) { - head.left = null; - return; - } - - prune(prune, head.left); - } - - if(prune.data > head.data && head.right != null) { - if(head.right.data == prune.data) { - head.right = null; - return; - } - - prune(prune, head.right); - } - } - - /** - * Swaps the two objects - * - * @param a - first node - * @param b - second node - */ - private void swap(Node a, Node b) { - - int temp = a.data; - a.data = b.data; - b.data = temp; - } + } /** * Executes the problem's solution * * @param input */ + @Override protected void run(String input) { // Create the BST @@ -248,12 +185,12 @@ protected void run(String input) { int remove = Integer.parseInt(split[1].trim()); Node head = null; for (int i : csvToIntArray(split[0])) { - if (head == null) { - head = new Node(i); - continue; - } + if (head == null) { + head = new Node(i); + continue; + } - insert(i, head); + insert(i, head); } print(head); From 60478d1059fb40b51a540abd20a20f214702e5bb Mon Sep 17 00:00:00 2001 From: Zachary Miller <2.4.8.16.32.sixtyfour@gmail.com> Date: Wed, 11 Jan 2017 20:30:27 -0700 Subject: [PATCH 3/7] Added a readme --- challenge_11/java/zmiller91/README.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 challenge_11/java/zmiller91/README.md diff --git a/challenge_11/java/zmiller91/README.md b/challenge_11/java/zmiller91/README.md new file mode 100644 index 000000000..82f3f1750 --- /dev/null +++ b/challenge_11/java/zmiller91/README.md @@ -0,0 +1,20 @@ +# Binary Search Tree + +This solution contains a BST implementation that can add, search, and remove +elements from a tree; all functions run in O(log(n)) time. + +## How To Run + +``` +javac BST.java +java BST +``` + +# Input + +Input is accepted in the following format: + +``` +csv_of_elements | element_to_delete +1,2,3,4 | 3 +``` \ No newline at end of file From 4189dbd8c383ae862db7fe557c931216402b87ea Mon Sep 17 00:00:00 2001 From: Zachary Miller <2.4.8.16.32.sixtyfour@gmail.com> Date: Wed, 11 Jan 2017 20:58:04 -0700 Subject: [PATCH 4/7] returning head from insert, not the inserted node --- challenge_11/java/zmiller91/BST.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/challenge_11/java/zmiller91/BST.java b/challenge_11/java/zmiller91/BST.java index b06b35b50..76df89475 100644 --- a/challenge_11/java/zmiller91/BST.java +++ b/challenge_11/java/zmiller91/BST.java @@ -62,7 +62,7 @@ public Node insert (int data, Node head) { head.left = new Node(data); head.left.parent = head; - return head.left; + return head; } if (data > head.data) { @@ -72,7 +72,7 @@ public Node insert (int data, Node head) { head.right = new Node(data); head.right.parent = head; - return head.right; + return head; } // Ignore duplicates From 851df4fed5256cc8a0b2167ba88276b19532fc90 Mon Sep 17 00:00:00 2001 From: Zachary Miller <2.4.8.16.32.sixtyfour@gmail.com> Date: Wed, 11 Jan 2017 21:32:30 -0700 Subject: [PATCH 5/7] changed search to a protected accessor --- challenge_11/java/zmiller91/BST.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/challenge_11/java/zmiller91/BST.java b/challenge_11/java/zmiller91/BST.java index 76df89475..79484df2f 100644 --- a/challenge_11/java/zmiller91/BST.java +++ b/challenge_11/java/zmiller91/BST.java @@ -25,16 +25,16 @@ class BST extends YOP { * @param data - value to be deleted * @param n - tree to look at */ - public Node search(int data, Node n) { + protected Node search(int data, Node n) { // Not found if (n == null) { - return null; + return null; } // Found, return the node if (data == n.data) { - return n; + return n; } // Search the next tree From bd87b0b0f58c051e1e7036cb8e110816483a7263 Mon Sep 17 00:00:00 2001 From: Zachary Miller <2.4.8.16.32.sixtyfour@gmail.com> Date: Wed, 11 Jan 2017 21:34:28 -0700 Subject: [PATCH 6/7] changed a delete accessor to protected and updated readme to reflect the new api --- challenge_11/java/zmiller91/BST.java | 48 +++++++++++++-------------- challenge_11/java/zmiller91/README.md | 2 +- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/challenge_11/java/zmiller91/BST.java b/challenge_11/java/zmiller91/BST.java index 79484df2f..74c1b55b0 100644 --- a/challenge_11/java/zmiller91/BST.java +++ b/challenge_11/java/zmiller91/BST.java @@ -19,29 +19,6 @@ public Node(int data) { class BST extends YOP { - /** - * Returns the object containing the provided data point - * - * @param data - value to be deleted - * @param n - tree to look at - */ - protected Node search(int data, Node n) { - - // Not found - if (n == null) { - return null; - } - - // Found, return the node - if (data == n.data) { - return n; - } - - // Search the next tree - Node next = data < n.data ? n.left : n.right; - return search(data, next); - } - /** * Inserts a value into a BST. * @@ -98,7 +75,7 @@ public void remove(int data, Node n) { * @param n - head of subtree * @param head - a reference to the head of the tree */ - public void remove(Node remove, Node n) { + protected void remove(Node remove, Node n) { if (remove == null){ return; @@ -122,6 +99,29 @@ public void remove(Node remove, Node n) { parent.right = parent.right != remove ? parent.right : null; } } + + /** + * Returns the object containing the provided data point + * + * @param data - value to be deleted + * @param n - tree to look at + */ + protected Node search(int data, Node n) { + + // Not found + if (n == null) { + return null; + } + + // Found, return the node + if (data == n.data) { + return n; + } + + // Search the next tree + Node next = data < n.data ? n.left : n.right; + return search(data, next); + } /** * Finds the smallest element in a BST diff --git a/challenge_11/java/zmiller91/README.md b/challenge_11/java/zmiller91/README.md index 82f3f1750..9e539a8af 100644 --- a/challenge_11/java/zmiller91/README.md +++ b/challenge_11/java/zmiller91/README.md @@ -1,6 +1,6 @@ # Binary Search Tree -This solution contains a BST implementation that can add, search, and remove +This solution contains a BST implementation that can add and remove elements from a tree; all functions run in O(log(n)) time. ## How To Run From 2f6b7573cb1cda155da0612adbac18d2a574a18f Mon Sep 17 00:00:00 2001 From: Zachary Miller <2.4.8.16.32.sixtyfour@gmail.com> Date: Thu, 12 Jan 2017 19:24:19 -0700 Subject: [PATCH 7/7] [Java] challenge 12 --- challenge_12/java/zmiller91/Compression.java | 130 +++++++++++++++++++ challenge_12/java/zmiller91/README.md | 22 ++++ challenge_12/java/zmiller91/YOP.java | 49 +++++++ 3 files changed, 201 insertions(+) create mode 100644 challenge_12/java/zmiller91/Compression.java create mode 100644 challenge_12/java/zmiller91/README.md create mode 100644 challenge_12/java/zmiller91/YOP.java diff --git a/challenge_12/java/zmiller91/Compression.java b/challenge_12/java/zmiller91/Compression.java new file mode 100644 index 000000000..ddd50efac --- /dev/null +++ b/challenge_12/java/zmiller91/Compression.java @@ -0,0 +1,130 @@ + +import java.util.Arrays; + +/** + * @author zmiller + */ +public class Compression extends YOP{ + + /** + * Compresses a alphabetic string + * + * @param input - string to compress + * @return - compressed string + */ + public String compress(String input) { + + StringBuilder retval = new StringBuilder(); + StringBuilder sequence = new StringBuilder(); + for(char c : input.toCharArray()) { + + // Found the end of a sequence + if (sequence.length() > 0 && sequence.charAt(0) != c) { + retval.append(formatForCompression(sequence)); + sequence = new StringBuilder(); + } + + // Add to the sequence + sequence.append(c); + } + + // Don't forget the leftovers + return retval.append(formatForCompression(sequence)).toString(); + } + + /** + * Decompresses an alphabetic string + * + * @param input - string to decompress + * @return - decompressed string + */ + public String decompress(String input) { + StringBuilder retval = new StringBuilder(); + for(int i = 0; i < input.length(); i++) { + + // Compressed sequence, uncompress it + if(input.charAt(i) == '#') { + i++; + + // Find the number of repeated characters + StringBuilder count = new StringBuilder(); + while(i < input.length() && isInt(input.charAt(i))) { + count.append(input.charAt(i)); + i++; + } + + // Append a string with the correct number of repeated characters + retval.append(formatForDecompression( + retval.charAt(retval.length() - 1), + Integer.parseInt(count.toString()) - 1)); + + // Terminate if the string has been exhausted + if(i == input.length()) { + break; + } + } + + retval.append(input.charAt(i)); + } + + return retval.toString(); + } + + /** + * Checks if a character is an integer + * + * @param i + * @return + */ + private boolean isInt(char i) { + try { + Integer.parseInt(Character.toString(i)); + return true; + } + catch (Exception e) { + return false; + } + } + + /** + * Creates a string with repeated characters + * + * @param fillWith - characters to repeat + * @param size - number of repetitions + * @return repeated character string + */ + private String formatForDecompression(char fillWith, int size) { + char[] chars = new char[size]; + Arrays.fill(chars, fillWith); + return new String(chars); + } + + /** + * Takes a string with repeated characters and compresses it to the + * proper format + * + * @param sequence + * @return + */ + private String formatForCompression(StringBuilder sequence) { + if(sequence.length() > 3) { + return Character.toString(sequence.charAt(0))+ "#" + + Integer.toString(sequence.length()); + } + + return sequence.toString(); + } + + @Override + protected void run(String input) { + String compressed = compress(input); + System.out.println("Compressed: " + compressed); + String decompressed = decompress(compressed); + System.out.println("Decompressed: " + decompressed); + System.out.println("Decompressed == Input? " + decompressed.equals(input)); + } + + public static void main(String[] args) { + launch(new Compression()); + } +} diff --git a/challenge_12/java/zmiller91/README.md b/challenge_12/java/zmiller91/README.md new file mode 100644 index 000000000..fcdd056ec --- /dev/null +++ b/challenge_12/java/zmiller91/README.md @@ -0,0 +1,22 @@ +# Compression and Decompression + +This solution compresses and decompresses a string of alphabetic characters +by turning a repeating sequence into `character#repeated`, assuming the sequence +is repeated more than 3 times. + +## How To Run + +``` +javac Compression.java +java Compression +``` + +## Discussion + +* Space: O(N) +* Time: O(N) + +The solution builds a new string as it's compressed; if that space isn't +considered in the space complexity, then the solution would use O(1) space. This +solution works with empty strings and builds the compressed and decompressed +strings with a single pass. \ No newline at end of file diff --git a/challenge_12/java/zmiller91/YOP.java b/challenge_12/java/zmiller91/YOP.java new file mode 100644 index 000000000..8c818bd33 --- /dev/null +++ b/challenge_12/java/zmiller91/YOP.java @@ -0,0 +1,49 @@ +import java.lang.Integer; +import java.lang.String; +import java.util.Scanner; + +/** + * @author zmiller + */ +public abstract class YOP { + + protected int[] csvToIntArray(String csv) { + String[] strings = csv.split(","); + int[] ints = new int[strings.length]; + for (int i = 0; i < strings.length; i++) { + ints[i] = Integer.parseInt(strings[i].trim()); + } + + return ints; + } + + /** + * Executes the life cycle of the solution. + * + * @param yop - class to execute + */ + protected static void launch(YOP yop) { + + String input; + Scanner scan = new Scanner(System.in); + + System.out.println("Type 'done' to terminate.\n"); + while(true) { + System.out.print("Input: "); + input = scan.nextLine(); + if(input.toLowerCase().equals("done")) { + return; + } + + yop.run(input); + } + } + + /** + * Executes the solution + * + * @param input - command line input + */ + protected abstract void run(String input); + +}