Last active
September 6, 2015 01:18
-
-
Save nimamehanian/7c1438c39cf8aa72748d to your computer and use it in GitHub Desktop.
Toy problem: SplitSort. Given an input string, render the space-separated entries across `n` columns, vertically, and in alphabetical order. (i.e., implement an elementary UNIX `ls -a` command)
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
// test strings | |
var str1 = 'the quick brown fox jumps over the lazy dog and this is probably the longest sentence you have ever come across because it just has so many words in it that it just runs on and on needlessly can you tell'; | |
var str2 = 'Oh, what a harmony of abandonment and impulse, of unnatural and yet graceful postures, in that mystical language of limbs, freed from the weight of corporeal matter, marked quantity infused with new substantial form, as if the holy band were struck by an impetuous wind, breath of life, frenzy of delight, rejoicing song of praise miraculously transformed, from the sound that it was, into image.'; | |
var rand = 'Oh, what a harmony of abandonment? and impulse!, of unnatural (and yet graceful) postures, in that mystical language of limbs, freed from the weight of corporeal matter, marked quantity infused with new substantial form; as if the holy band were struck by an impetuous wind, breath of life: frenzy of delight: rejoicing song of praise, miraculously transformed, from the sound that it was, into image.'; | |
var files = '. .. .CFUserTextEncoding .DS_Store .Trash .avcd .babel.json .bash_history .bash_profile .bashrc .cache .config .cups .dbshell .divshot .firebaserc .gem .gemrc .ghc .gitconfig .heroku .irb-history .lein .local .m2 .mkshrc .mongorc.js .netrc .node-gyp .npm .oracle_jre_usage .pgpass .profile .psql_history .rnd .rvm .ssh .v8flags.3.28.73.mehanian.json .zlogin .zshrc Applications Creative%w%Cloud%w%Files Desktop Documents Downloads Library Movies Music Pictures Public dump.rdb'; | |
// SplitSort | |
// @param {string} input: a string containing a space-separated list of entries | |
// @param {number} cols: the desired number of columns to render | |
// @param {boolean} lc: lower-case entries of input string, if true | |
var ls = listAll = splitSort = splort = function (input, cols, lc) { | |
// ensure cols is a positive integer; default to 3 | |
cols = cols > 0 ? cols : 3; | |
// ensure input is a string and contains at least as many words as desired columns | |
if (cols > input.split(' ').length) { | |
throw new TypeError('The number of columns cannot exceed the number of available words.'); | |
} | |
var | |
_format = function (str, lower) { | |
return str.split(' ').map(function (val) { | |
var len = val.length; | |
// lower-case the entry, if flag is passed | |
val = lower ? val.toLowerCase() : val; | |
// remove whitespace and , : ; ! " ? ( ) from entry | |
val = val.replace(/,|:|;|!|\"|\?|\(|\)|\s/g, ''); | |
// add deliberate whitespace | |
val = val.replace(/%w%/g, ' '); | |
// remove trailing periods, unless entry is '.' or '..' | |
val = (len > 2 && val[len - 1] === '.') ? val.slice(0, len - 1) : val; | |
return val; | |
// sort alphabetically and drop any false values | |
}).sort().filter(function (val) { return !!val; }); | |
}, | |
_chunk = function (list, size) { | |
if (list.constructor.name !== 'Array') { | |
throw new TypeError('`list` must be an array.'); | |
} | |
var i = 0, result = []; | |
while (i < list.length) { | |
result.push(list.slice(i, i += size)); | |
} | |
return result; | |
}, | |
// return the length of the longest string in a given column | |
_colWidth = function (column) { | |
if (column.constructor.name !== 'Array') { | |
throw new TypeError('`column` must be an array.'); | |
} | |
return Math.max.apply(null, column.map(function (val) { return val.length; })); | |
}, | |
_repeat = function (char, count) { | |
var result = ''; | |
for (var i = 0; i < count; i++) { | |
result += char; | |
} | |
return result; | |
}, | |
_align = function (col, row) { | |
if (matrix[col - 1] && matrix[col - 1][row]) { | |
return _repeat(' ', (_colWidth(matrix[col - 1]) - matrix[col - 1][row].length + 5)); | |
} else { | |
throw new RangeError('The number of words in the input string do not evenly ' + | |
'split into ' + cols + ' columns. Try applying the function again with ' + | |
(cols - 1) + ' or ' + (cols + 1) + ' columns.'); | |
} | |
}, | |
// begin on a new line for proper alignment | |
result = '\n', | |
// split the data into an array | |
wordList = _format(input, lc), | |
// divide the number of words by the desired number of columns to yield column length (i.e., rows) | |
colLength = Math.ceil(wordList.length / cols), | |
// chunk into subarrays of colLength | |
matrix = _chunk(wordList, colLength); | |
// render (by row) | |
for (var r = 0; r < colLength; r++) { | |
// first column | |
result += matrix[0][r]; | |
// remaining columns | |
for (var c = 1; c < cols; c++) { | |
// The padding is equal to the length of the longest word in the column, | |
// minus the length of the word, plus a five-space buffer (see `_align`) | |
result += _align(c, r); | |
result += (matrix[c] && matrix[c][r]) ? matrix[c][r] : ''; | |
} | |
result += '\n'; | |
} | |
// logging output because `return` statements do not render the newline (\n) character. | |
console.log(result); | |
// return result; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment