let input = 'L,8,R,10,L,10,R,10,L,8,L,8,L,10,L,8,R,10,L,10,L,4,L,6,L,8,L,8,R,10,L,8,L,8,L,10,L,4,L,6,L,8,L,8,L,8,R,10,L,10,L,4,L,6,L,8,L,8,R,10,L,8,L,8,L,10,L,4,L,6,L,8,L,8,'; let out = []; // convert every substr occurence in `arr` to a symbol in `str` // toSymbols('12345123',['123','45']) yields 'ABA' function toSymbols(str, arr) { arr.forEach((s, i) => { let re = new RegExp(s, 'g'); str = str.replace(re, String.fromCharCode(65 + i)); }); return str; } do { out = []; let scratch = input for (let j = 0; j < 3; j++) { let b = Math.random() * 20 | 0; let sym = scratch.substr(0, b); let re = new RegExp(sym, 'g'); // remove all occurences of the symbol from the string scratch = scratch.replace(re, ''); out.push(sym); } // did our randomly chosen symbols manage to cover the whole input? if (/^[ABC]+$/.test(toSymbols(input, out))) { break; } } while (1); console.log(toSymbols(input, out)); console.log(out);