Search⌘ K

Solution to Sub-task Line Breaks

Explore how to manage line breaks in JavaScript by splitting lines and hyphenating words based on dictionary references. Understand recursive methods to generate hyphenation combinations and apply punctuation handling to format text correctly within width limits.

We'll cover the following...

Line breaks

After splitting a line by a certain width, introduce the hyphenation of a word. The word should be split into parts by referring to a dictionary and incorporating the broken word in the first part of the line however possible.

Node.js
// helper function to permute combinations
// input -> [[String][String]] eg. [['he'],['l', 'lo']]
// Output -> [[[String][String]]]
// eg. [ [['he'], ['l', 'lo']],
// [['he', 'l'], ['lo']],
// [['he', 'l', 'lo'], []], ]
function getPermutations(arr){
let [fst , snd] = arr; // destructure array
if(snd.length === 0) return [[fst, snd]]; // basecase
let [x, ...xs] = snd; // remove one element from right arrray
let permute = [[...fst, x], xs]; // shift removed element to left array
let answer = getPermutations(permute); // call for further combinations
return [arr, ...answer]; // return all combinations
}
function lineBreaks(dict, width, line){
let [fstPart, sndPart] = splitLine(line, width);
if(sndPart.length === 0) return [[fstPart, sndPart]];
let word = sndPart[0].replace(/[^A-Za-z]/g,''); // get first word of second part of line
if(dict.hasOwnProperty(word)){
let permutations = getPermutations([[],dict[word]]);
// map all permutations with splitLine output
let possAns = permutations.map(x => {
// see if hyphen needed
let leftSide = x[0].length ? x[0].join('').concat('-') : [];
// see if punctuation mark needed
let rightSide = sndPart[0].match(/[.,]/) ?
x[1].join('') + sndPart[0].substr(-1):
x[1].join('') ;
// add leftSide and rightSide
return leftSide.length?
[[ ...fstPart, leftSide],[ rightSide, ...sndPart.slice(1)]]
: [[ ...fstPart],[ rightSide, ...sndPart.slice(1)]];
});
// filter lines with greater than the width length
let finAns = possAns.filter(x => {
let total = x[0].reduce((prev, curr) => curr.length + prev, 0);
return (x[0].length - 1 + total) <= width
})
return finAns; // return final answer
}
else{
return [[fstPart, sndPart]];
}
}
// dictionary
enHyp = {
"creative" : ["cr","ea","ti","ve"],
"controls" : ["co","nt","ro","ls"],
"achieve" : ["ach","ie","ve"],
"future" : ["fu","tu","re"],
"present" : ["pre","se","nt"],
"motivated" : ["mot","iv","at","ed"],
"desire" : ["de","si","re"],
"others" : ["ot","he","rs"],
}
console.log(lineBreaks(enHyp,12, ["He", "who", "controls.","world"] ));

In this solution, first split the line according to its width using the splitLine function from the previous part. (line 18). Our base-case or corner case ...