Last active
August 29, 2015 14:01
-
-
Save 1995eaton/c07e4be75135f17faa87 to your computer and use it in GitHub Desktop.
/r/dailyprogrammer problem #162 [easy + intermediate + hard]
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env node | |
// See http://www.reddit.com/r/dailyprogrammer/comments/25o2bd/5162014_challenge_162_hard_novel_compression_pt_3/ | |
// Usage: | |
// ./162 -c input.txt -o compressed.txt | |
// ./162 -d compressed.txt -o output.txt | |
var fs = require("fs"); | |
var stdio = require("stdio"); // npm install stdio | |
var args = stdio.getopt({ | |
compress: {key: "c", args: 0, description: "compress a file"}, | |
decompress: {key: "d", args: 0, description: "decompress a string"}, | |
outputFile: {key: "o", args: 1, description: "a file to output the data"} | |
}); | |
function compress(input) { | |
input.replace(/--|[^ a-zA-Z.,\-?!;:\n]|([.,?!;:]+)[a-z]+\1|( |[A-Z]+)[a-z]+[A-Z]+/, function() { | |
throw "Error: invalid input"; | |
}); | |
var dictionary = []; | |
input = input.replace(/([\n.,?\-!;:])/g, " $1 "); | |
input.match(/[a-zA-Z]+/g).forEach(function(e) { | |
if (dictionary.indexOf(e.toLowerCase()) === -1) | |
dictionary.push(e.toLowerCase()); | |
}); | |
return dictionary.join(" ") + " -> " + input.split(/ +/).map(function(e) { | |
return /[.,?!\-;:]/.test(e) ? e : | |
dictionary.indexOf(e.toLowerCase()).toString().replace(/-1/, "R") + | |
e.replace(/^([A-Z]){2,}$/, "!").replace(/^[A-Z]/g, "^").replace(/[^^!]+/, ""); | |
}).concat("E").join(" "); | |
} | |
function decompress(data, words) { | |
if (typeof words === "string") words = words.split(/ +/); | |
return data.replace(/R/g, " \n ").replace(/([0-9]+)/g, function(e) { return words[parseInt(e)]; }) | |
.replace(/(\S+)!/g, function(e) { return e.slice(0, -1).toUpperCase(); }) | |
.replace(/(\S+)\^/g, function(e) { return e[0].toUpperCase() + e.slice(1, -1); }).split(/ +/) | |
.slice(0, -2).join(" ").replace(/ - /g, "-").replace(/ ([,.?!])/g, "$1") | |
.replace(/( +)?\n( +)/g, "\n").replace(/(\n| )+$/, ""); | |
} | |
var argLen = Object.keys(args).length - 2; | |
function openFile(fname, callback) { | |
fs.readFile(fname, "utf8", function(err, data) { | |
callback(data); | |
}); | |
} | |
if (!args.hasOwnProperty("outputFile")) { | |
return false; | |
} | |
if (args.hasOwnProperty("compress") && args.args && args.args.length && argLen === 3) { | |
openFile(args.args[0], function(data) { | |
fs.writeFileSync(args.outputFile, compress(data)); | |
}); | |
} else if (args.hasOwnProperty("decompress") && argLen === 3) { | |
openFile(args.args[0], function(data) { | |
var a = data.split(" -> "); | |
if (a.length === 2) { | |
fs.writeFileSync(args.outputFile, decompress(a[1], a[0])); | |
} | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment