diff --git a/.gitignore b/.gitignore index e99d9f2..e69de29 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +0,0 @@ -solution \ No newline at end of file diff --git a/Demo.html b/Demo.html index f42cf6a..1ede3a5 100644 --- a/Demo.html +++ b/Demo.html @@ -4,6 +4,7 @@ +
@@ -107,92 +108,6 @@

Efficiency:

} - \ No newline at end of file + diff --git a/solution/solution.js b/solution/solution.js new file mode 100644 index 0000000..f069ad1 --- /dev/null +++ b/solution/solution.js @@ -0,0 +1,75 @@ +var countChars = function(input) { + var counts = {}; + for (var i = 0; i < input.length; i++) { + var c = input[i]; + counts[c] = counts[c] || 0; + counts[c]++; + } + return counts; +}; + +var makeHuffmanTree = function(input) { + var charCounts = countChars(input); + var pq = new PriorityQueue(); + for (var c in charCounts) { + var n = charCounts[c]; + var tree = new Tree([c]); + pq.insert(n, tree); + } + + while (pq.size() > 1) { + var first = pq.extract(); + var second = pq.extract(); + + var tree1 = first.val; + var tree2 = second.val; + + var key1 = first.key; + var key2 = second.key; + + var newTree = new Tree(tree1.val.concat(tree2.val)); + newTree.left = tree1; + newTree.right = tree2; + pq.insert(key1+key2, newTree); + } + + return pq.extract().val; +}; + +var encodeString = function(input, huffman) { + var output = ""; + for (var i = 0; i < input.length; i++) { + var currentNode = huffman; + var nextCharacter = input[i]; + while (currentNode.val.length > 1) { + if (currentNode.left.val.indexOf(nextCharacter) !== -1) { + currentNode = currentNode.left; + output += "0"; + } else if (currentNode.right.val.indexOf(nextCharacter) !== -1) { + currentNode = currentNode.right; + output += "1"; + } else { + throw new Error("Character " + nextCharacter + " is not in this Huffman tree."); + } + } + } + return output; +}; + +var decodeString = function(input, huffman) { + var output = ""; + var currNode = huffman; + for (var currIdx = 0; currIdx < input.length; currIdx++) { + var currBit = input[currIdx]; + if (currBit === "0") { + currNode = currNode.left; + } else if (currBit === "1") { + currNode = currNode.right; + } + if (currNode.val.length === 1) { + output += currNode.val[0]; + currNode = huffman; + } + } + return output; +}; diff --git a/src/huffman.js b/src/huffman.js index 6205c60..7920d6c 100644 --- a/src/huffman.js +++ b/src/huffman.js @@ -1,13 +1,43 @@ -// // Given a Huffman tree and a string, encode that string into a new string -// // consisting only of 1s and 0s, using the code given by the tree. -var encodeString = function(input, huffmanTree) { - return ""; +// Given a Huffman tree and a string, encode that string into a new string +// consisting only of 1s and 0s, using the code given by the tree. +var encodeString = function(input, huffman) { + var output = ""; + for (var i = 0; i < input.length; i++) { + var currentNode = huffman; + var nextCharacter = input[i]; + while (currentNode.val.length > 1) { + if (currentNode.left.val.indexOf(nextCharacter) !== -1) { + currentNode = currentNode.left; + output += "0"; + } else if (currentNode.right.val.indexOf(nextCharacter) !== -1) { + currentNode = currentNode.right; + output += "1"; + } else { + throw new Error("Character " + nextCharacter + " is not in this Huffman tree."); + } + } + } + return output; }; -// // Given a Huffman tree and a string of 1s and 0s, decode that string into -// // a new, human-readable string, using the code given by the tree. -var decodeString = function(input, huffmanTree) { - return ""; +// Given a Huffman tree and a string of 1s and 0s, decode that string into +// a new, human-readable string, using the code given by the tree. +var decodeString = function(input, huffman) { + var output = ""; + var currNode = huffman; + for (var currIdx = 0; currIdx < input.length; currIdx++) { + var currBit = input[currIdx]; + if (currBit === "0") { + currNode = currNode.left; + } else if (currBit === "1") { + currNode = currNode.right; + } + if (currNode.val.length === 1) { + output += currNode.val[0]; + currNode = huffman; + } + } + return output; }; // Given a corpus of text, return a Huffman tree that represents the @@ -22,6 +52,39 @@ var decodeString = function(input, huffmanTree) { // You may also use the `Tree` class that is provided in the file `misc.js` // Some corpuses are included as the variables `lorumIpsum` and `declaration`. var makeHuffmanTree = function(corpus) { - return new Tree(); + var charCounts = countChars(corpus); + var pq = new PriorityQueue(); + for (var c in charCounts) { + var n = charCounts[c]; + var tree = new Tree([c]); + pq.insert(n, tree); + } + + while (pq.size() > 1) { + var first = pq.extract(); + var second = pq.extract(); + + var tree1 = first.val; + var tree2 = second.val; + + var key1 = first.key; + var key2 = second.key; + + var newTree = new Tree(tree1.val.concat(tree2.val)); + newTree.left = tree1; + newTree.right = tree2; + pq.insert(key1+key2, newTree); + } + + return pq.extract().val; }; +var countChars = function(input) { + var counts = {}; + for (var i = 0; i < input.length; i++) { + var c = input[i]; + counts[c] = counts[c] || 0; + counts[c]++; + } + return counts; +};