One way to do this is to think of the spaces between elements as movable boundaries. If we have words a - e, and we want to break them into three non-empty sequences, then we need to choose two of these spaces (with implied ones always at either end.)
a b c d e indices words
--------------------------------------------
| | [1, 2] (a, b, cde)
| | [1, 3] (a, bc, de)
| | [1, 4] (a, bcd, e)
| | [2, 3] (ab, c, de)
| | [2, 4] (ab, cd, e)
| | [3, 4] (abc, d, e)
--------------------------------------------
0 1 2 3 4 Infinity
We can use these boundaries along with the original array to fairly easily reconstruct your collection of words.
So the hard problem is finding those sets of borders. But this is now the problem of choosing two elements from four options (in general, choosing n - 1 options from words .length - 1 options) and that's a fairly well-known problem. Using a recursive version of that and two minor helper functions, we can write this:
const inPairs = (xs) => xs .slice (1) .map ((x, i) => [xs [i], x])
const range = (lo, hi) => Array .from ({length: hi - lo}, (_, i) => i + lo)
const choose = (n) => (xs) =>
n < 1 || n > xs .length
? []
: n == 1
? [...xs .map (x => [x])]
: [
...choose (n - 1) (xs .slice (1)) .map (ys => [xs [0], ...ys]),
...choose (n) (xs .slice (1))
]
const wordBreaks = (ws) => (n) =>
choose (n - 1) (range (1, ws .length)) .map (
(ns) => inPairs ([0, ...ns, Infinity]) .map(([a, b]) => ws .slice (a, b))
)
console .log (wordBreaks (['Simplicity', 'is', 'the', 'ultimate', 'sophistication']) (3))
.as-console-wrapper {max-height: 100% !important; top: 0}
The helpers are fairly trivial.
toPairs groups an array into a collection of consecutive pairs:
toPairs (['a', 'b', 'c', 'd']) //=> [['a', 'b'], ['b', 'c'], ['c', 'd']]
range creates an integer range, inclusive on the left, exclusive on the right:
range (3, 12) //=> [3, 4, 5, 6, 7, 8, 9, 10, 11]
The important function here is choose, which collects every set of n items from an array of values.
choose (2) (['a', 'b', 'c', 'd']) //=>
// [['a', 'b'], ['a', 'c'], ['a', 'd'], ['b', 'c'], ['b', 'd'], ['c', 'd']]
The main function is wordBreaks. It uses range to get get those interstitial indices from the diagram, then uses choose to select n - 1 of those indices, giving us something like [[1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3, 5], [1, 4, 5], [2, 3, 4], [2, 3, 5], [2, 4, 5], [3, 4, 5]]. Each one of these is wrapped to include 0 and Infinity as well, so that [1, 3, 4] becomes [0, 1, 3, 4, Infinity]. We use toPairs to split this into [[0, 1], [1, 3], [3, 4], [4, Infinity]], then uses those as slice boundaries on our original array, turning ["Here's", "looking", "at", "you", "kid"] into [["Here's"], ["looking", "at"], ["you"], ["kid"]]. And we do this for every collection of indices.
If we add a little display function, we can break a seven-word Shakespeare quote into four segments, like this:
const display = (xss) => console .log (
(xss .map (xs => `["${xs .map (x => x .join (' ')) .join ('", "')}"]`) .join ('\n'))
)
display (wordBreaks (['Now', 'is', 'the', 'winter', 'of', 'our', 'discontent']) (4))
to get
["Now", "is", "the", "winter of our discontent"]
["Now", "is", "the winter", "of our discontent"]
["Now", "is", "the winter of", "our discontent"]
["Now", "is", "the winter of our", "discontent"]
["Now", "is the", "winter", "of our discontent"]
["Now", "is the", "winter of", "our discontent"]
["Now", "is the", "winter of our", "discontent"]
["Now", "is the winter", "of", "our discontent"]
["Now", "is the winter", "of our", "discontent"]
["Now", "is the winter of", "our", "discontent"]
["Now is", "the", "winter", "of our discontent"]
["Now is", "the", "winter of", "our discontent"]
["Now is", "the", "winter of our", "discontent"]
["Now is", "the winter", "of", "our discontent"]
["Now is", "the winter", "of our", "discontent"]
["Now is", "the winter of", "our", "discontent"]
["Now is the", "winter", "of", "our discontent"]
["Now is the", "winter", "of our", "discontent"]
["Now is the", "winter of", "our", "discontent"]
["Now is the winter", "of", "our", "discontent"]