Created
January 28, 2012 10:29
-
-
Save riovv/1693880 to your computer and use it in GitHub Desktop.
Facebook Hacker Cup - Single file boilerplate
This file contains hidden or 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
/** | |
* Written in Node.js | |
* http://nodejs.org | |
* | |
* Author: Patric Nordmark | |
* | |
* Usage: node index.js [-t [n]] [<input file>] [<output file>] | |
* | |
* Running node index.js without any parameters will solve all | |
* test cases in input.txt and write the results to output.txt | |
* | |
* -t [1..N] Test a single case. (omit to test all). | |
* | |
* <input file>: Read input data from file (input.txt) | |
* <output file>: Output results to file (output.txt) | |
* During test (-t): | |
* Read correct output from file (test_output.txt) | |
* | |
* | |
* fbhc-boilerplate: | |
* Patric Nordmark <[email protected]> | |
*/ | |
var fs = require('fs'); | |
// Default values (these will be used if no command line parameters are given) | |
var DEFAULTS = { | |
INPUT_FILE: 'input.txt', | |
OUTPUT_FILE: 'output.txt', | |
TEST_OUTPUT: 'test_output.txt' | |
}; | |
// Aliases to make life easier. | |
var _l = console.log, | |
_d = console.dir; | |
/** | |
* input | |
* | |
* Modify the parser method to your liking | |
* The parser will be called for each line of the input file. | |
* And should return the Formatted data that will represent that test case. | |
*/ | |
/* ====================================================================== | |
* IF THE INPUT FORMAT IS NOT ONE CASE PER LINE, THIS HAS TO BE MODIFIED. | |
* ====================================================================== */ | |
var Input = function (file) { | |
return fs.readFileSync(file) | |
.toString() | |
// Remove the first line with the number of test cases. | |
.replace(/^\d+\n/, '') | |
// Trim ending linebreak. | |
.replace(/\n$/, '') | |
// Create an array of lines. | |
.split('\n') | |
// Run each line through the parser. | |
.map(this.parser); | |
} | |
/* ====================================================================== | |
* USE THE PARSER TO FORMAT YOUR INPUT INTO WORKABLE data | |
* ====================================================================== */ | |
Input.prototype.parser = function (testCase) { | |
return testCase; | |
}; | |
/* ====================================================================== | |
* ====================================================================== | |
* CREATE YOUR SOLUTION HERE. | |
* AN INSTANCE WILL BE CREATED FOR EACH TEST CASE. | |
* THE solve METHOD WILL BE CALLED FOR EACH TEST CASE. | |
* DO NOT RETURN 'CASE #X: ', ONLY THE CORRECT RESULT. | |
* ====================================================================== | |
* ====================================================================== | |
* | |
* Case | |
* Modify this class to solve a singe test case. | |
* | |
* The Constructor will be called with one argument, | |
* the data of a single test case, formatted by Input.parser() | |
* The solve method will be called upon to solve a single test case. | |
*/ | |
// Constructor | |
var Case = function (data) { | |
this.data = data; | |
}; | |
// Solve | |
Case.prototype.solve = function () { | |
// solution | |
}; | |
/* ====================================================================== | |
* ====================================================================== | |
* AFTER THIS LINE IS ONLY ARGUMENT/TEST/RUN CODE. NO NEED TO EDIT. | |
* SEE INSTRUCTIONS AT THE TOP OF THIS FILE ON HOW TO USE IT. | |
*/ | |
var Arg = { v: process.argv.slice(2)}; | |
Arg.command = Arg.v[0]; | |
Arg.getTest = function () { | |
var i, n = isNaN(parseInt(Arg.v[1], 10)) ? null : parseInt(Arg.v[1], 10); | |
if (n == null) i = 1; | |
else i = 2; | |
return { n: n, i: Arg.v[i] || DEFAULTS.INPUT_FILE, o: Arg.v[i+1] || DEFAULTS.TEST_OUTPUT }; | |
}; | |
Arg.getOutput = function () { | |
return { i: Arg.v[0] || DEFAULTS.INPUT_FILE , o: Arg.v[1] || DEFAULTS.OUTPUT_FILE }; | |
}; | |
var Output = function (file) { | |
return fs.readFileSync(file) | |
.toString() | |
.replace(/\n$/, '') | |
.split('\n') | |
.map(function(l) { return l.replace(/^Case\s#\d+:\s/, ''); }); | |
}; | |
var Runner = function (inputFile, outputFile) { | |
this.inputFile = inputFile; | |
this.outputFile = outputFile; | |
this.input = new Input(inputFile); | |
}; | |
Runner.prototype.test = function (n) { | |
var startTime, endTime, | |
outputData = new Output(this.outputFile), | |
cases = ((n == null) ? this.input : this.input.slice(n - 1, n)) | |
.map(function (d) { return new Case(d); }); | |
cases.forEach(function (c, i) { | |
var sTime, time, result, correct, | |
j = n == null ? i : n - 1; | |
sTime = new Date().getTime(); | |
result = c.solve(); | |
time = new Date().getTime() - sTime; | |
correct = (result === outputData[j]); | |
_l((correct ? '\033[32m' : '\033[31m') | |
+ '================================================================================' + '\n' | |
+ '#' + (j + 1) + ' ' | |
+ time + 'ms ' | |
+ correct | |
+ '\n' + '================================================================================' | |
); | |
_d(result); | |
_d(outputData[j]); | |
_l('\n'); | |
}); | |
}; | |
Runner.prototype.output = function () { | |
var output = ''; | |
this.input.map(function(d) { return new Case(d); }).forEach(function (c, i) { | |
output += (i > 0 ? '\n' : '') + 'Case #' + (i + 1) + ': ' + c.solve(); | |
}); | |
_l(output); | |
fs.writeFileSync(this.outputFile, output); | |
}; | |
switch (Arg.command) { | |
case '-t': | |
// If next argument is numeric then test only that case otherwise test all. | |
var arg = Arg.getTest(), | |
test = new Runner(arg.i, arg.o).test(arg.n); | |
break; | |
default: | |
var arg = Arg.getOutput(); | |
output = new Runner(arg.i, arg.o).output(); | |
} |
This file contains hidden or 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
5 | |
3 5 10 2 5 3 10 4 3 3 9 7 | |
2 2 118 80 400 316 | |
3 3 339 250 301 199 109 34 | |
2 4 9 9 482 417 211 120 151 69 | |
4 5 244 132 65 46 12 11 129 81 487 342 |
This file contains hidden or 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
Case #1: 54/175 | |
Case #2: 36855/37288 | |
Case #3: 161352/164045 | |
Case #4: 495040/566703 | |
Case #5: 11435776/12904515 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment