Skip to content

Instantly share code, notes, and snippets.

@mikepc
Last active February 22, 2018 05:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mikepc/c62b016063f82fb82393ae1f34df4856 to your computer and use it in GitHub Desktop.
Save mikepc/c62b016063f82fb82393ae1f34df4856 to your computer and use it in GitHub Desktop.
Coding Challenge, buffer problem
//Author: Michael Draper <mdraper@gmail.com>
//Justifies a string into a buffer.
// I ran it on Node v9.5.0 in ES2017 syntax.
const isInt = (n) => {
return n % 1 === 0;
}
//Example: justify('The quick brown fox jumps over the lazy dog', 52)
const justify = (str, len) => {
if(typeof(str) !== 'string'){
throw new Error('cannot justify string: input is not a string');
}
if(typeof(len) !== 'number'){
throw new Error('cannot justify string: len is not a number');
}
if(!isInt(len)){
throw new Error('cannot justify string: len must be a whole number');
}
console.debug('len', len, 'str.length', str.length);
if(len <= str.length) {
throw new Error('cannot justify string: the specified length is too short to justify');
}
//Deconstruct the original string into its constiuent parts.
const words = str.split(' '); // "The", "Quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog"
// Gotta have map/reduce, just because.. it's map/reduce!
const charLen = words.map(w => w.length).reduce( (sum, w) => sum + w ); //Total length of all characters
// In all words.
if(len < charLen) {
//TODO: Improve this message
throw new Error("cannot justify string: input string is larger than the allowed buffer size");
}
//52 - 34 = 18
const numSpaces = len - charLen; // Derives the number of total spaces which require allocation.
//Require a minimum of 1 space between words
if(numSpaces <= words.length - 1) {
throw new Error('cannot justify string: the desired length will not allow at least (1) space between words');
}
// 18 / 9 = 2
let spaceSize = numSpaces / words.length; // The number of spaces allocated per word.
//"The"
let buffer = words.shift(); //Take the first word off the array and push it into the buffer.
// "dog"
let lastWord = words[words.length - 1];
for(let word of words) { //Loop through the set of words
if(word !== lastWord)
{
for(let i = 0;i< spaceSize;i++){
buffer += " ";
}
buffer += word; //Push the non-last word into the buffer.
}else{
console.debug('buffer length at last word =>', buffer.length);
// This is really in-eloquent, but it's the best I can think of on short notice
// Buffer the last *before* the last word.
let finalSpaceSize = len - buffer.length - word.length;
//For the last word we pre-pend the spaces instead of appending them.
for(let i = 0;i< finalSpaceSize;i++){
buffer += " ";
}
buffer += word;
}
}
console.debug(buffer);
return buffer;
}
module.exports = justify;
{
"name": "coding_challenge",
"version": "1.0.0",
"description": "Coding Challenge",
"main": "index.js",
"scripts": {
"test": "jest ./test.js"
},
"author": "Michael Draper",
"license": "ISC",
"devDependencies": {
"jest": "^22.4.0"
}
}
//Author: Michael Draper <mdraper@gmail.com>
// Tests the justify() function
// These tests were coded for Jest (eg. npm install --save-dev jest)
const justify = require('./index');
test('accepts a buffer and prints out exactly that buffer length', function(){
let output = justify('The quick brown fox jumps over the lazy dog', 52);
expect(output[0]).toEqual('T');
expect(output[51]).toEqual('g');
expect(output.length).toEqual(52);
});
test('works for a phrase different than the sample case from the exercise', function(){
let output = justify('King of the world!', 22);
expect(output[0]).toEqual('K');
expect(output[21]).toEqual('!');
expect(output.length).toEqual(22);
})
test('throws an error when we cannot have enough spaces', function(){
const error = function(){
justify('The quick brown fox jumps over the lazy dog', 41);
}
expect(error).toThrowError(/the specified length is too short to justify/);
});
test('does not allow non-string as input', function(){
const error = function(){
justify({'heh': 'this should not work'}, 42);
}
expect(error).toThrowError(/input is not a string/);
});
test('does not allow non-integer for second parameter', function(){
const error = function(){
justify("The Last Jedi", '42');
}
expect(error).toThrowError(/len is not a number/);
});
test('does not allow negative numbers', function(){
const error = function(){
justify("The Last Jedi", -42);
}
expect(error).toThrowError(/the specified length is too short to justify/);
});
test('does not allow cheeky bastards to pass floating point numbers', function(){
const error = function(){
justify("The Last Jedi", 3.1419);
}
expect(error).toThrowError(/len must be a whole number/);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment