Guest User

FindHoles.js

a guest
Jul 17th, 2023
28
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. tCategories = {
  2.     "C": "b,d,dz,g,ġ,gh,h,j,k,k',kh,l,m,n,p,p',q,q',r,s,ş,t,t',ts,ts',tş,tş',v,z".split(","),
  3.     "V": "a,ạ,e,i,o,u".split(",")
  4. }
  5.  
  6. ///////////////////////////////////////////////////////////
  7.  
  8. // the entire lexicon of Old Mtsqrveli compressed into one, space-delimited line
  9. var sWords = "abi abmiot'i ạbts ạbtsila adele adhava adkhlo ạdrelva adumi ạdzproqar ạdzprova aes aghdgeva aghleva aghsmsglema aghsmsgleva ạgoli ạjalva aje akhali akhola ạlạ alt'kạreşva alt'kạreşvo alt'kạrva amarteva andebsva ani anitşmenra antiova ap api apjeva apts ạr arav aravola aravtsmegduli ard ardaba ardzġvoş ạrgạ ạrgạli arhaz arin arioa ạrjạl ạrkos ạrkots'ạli ạrlo ạrt artova artsmdo aruli ạsb ạşqạm ạstuli atoni ạtşạ atuliş ạvạlos avli avt azkhrane azkhrava ạztạr azva ba baġrạj bagrat bạntsava bạri barqa başvke batomi bdov bdzerala bdzeraldagoma bdztots begeomima begeva bel beştova bgera bgeti bghi bghloni bghola bikhi bkhievo bkhliva bkhvseba braşi braşoli brba brdebsva brdzola brebsva brivgha brivghebiva brivghi brmava brts'eva brts'q'inavs brve brveli brvjema brvmotmelova btmirdzma btmire btsqalavs btşroşin btşrova Budạpasetis bul bvareti bvlino bvlinoba bzeleunamva bzeleva bziniva bzq'e bzvo bzvoma da- dạ dados dag- dagoş te daidebişin daidebiva daisi dameti Damotsa damşalva daova daqtsva dari darkht'iva darmiot'i darupts'srt'ma dasaniva daşkham daşlieva datskeliva dats'kiva dạtşnoma datşrema datşreva dbrebesva dbres debi dede dereva dgareva dghiş dgileva dgova di- didanatşeni diemşili digagemajemi digagemi dighlobi dimt'eli dimtsetsvatş'rebi dimtştemtani diobani dirteli disakvi diteri dkha dkhliva dmelo dmova dno doda dona donapreliva dor druva duguli dvagerts dviş dvişnen dzala dzamova dzan dzebuli dzge dzghạnd dzgherba ghvenili dzghva dzgoni dzidi dzilva dzkhuli dzmoba dznebula dzneva dzol dzora dzrebva dzto dzuzegi -eb- edza eger ehit ehitne ek'- ek'dimt'elimpova ekhneva ek'şnola ek'ter ek'vse eld elt eltaba ema emo emşi ena ereva erguli eri eromema ert erta ertjeva ervde ervdempova ervdene eskats eşva et etseva et've euni ev eva evjevo ġa- gabrtsema gabrtseva gadkheva gadkhunamila gạdz gạdzotni gagemajema gagemajeva gageva gaisreva ġajarva ġajeva gạla ġạmạ gamari gamoja ġams gana gạnạd gạndza ġanieva gankhetliva gạntsva ġaraq'ava garega gariva gaşaula gaşvnelo ġatavsova gatsva ġaverts'eva ba jạpreght'ova ġavetşova gavola ġavraq'ava gavs gbeli gdmebova gdmo ġdseva gduliva gdza gdzabola ġdzạmi ġdzạmi ninạ gdzra gdzrola geli gelmiot'i gemits ġena gera gerts ġevli gh- ghabsva ghadiava ghak'avs ghạli ghạlima ghani ghar ghde gherian gherianebsva ghevma ghirsebi ghis ghloba ghme- ghmedaidebiva ghmotebiva ghnova ghobduli gholuri ghq'arova ghrạlova ghreba ghrnova ghrto ghtiova ghtşmelova ghtsova ghturva ghumeli ghur ghvạr ghvạrjeva ghveni ghvenidgareva ghvi giạri ginva girgi giurt ġkheta ġkhro ġkhruba ġletiva ġmavi gmbrava gmehova ġmer ġmihiova ġmio ġmotşva ġmtş'ạlva gmur ġmztava gni gnva goneva gordikhruva gordva ġori gorna ġort'q'va ġova ġovar ġovrebsva grge gro grojeva ġtsareva gtvava guliva ġundza ġuşur guza gva ġvạdo gvalova gvạmde ġvạr gvdelo ġver ġvivta ġvivtaba ġvlo ġvoni gvqi ġvrepts ġvsotar ġvsova ġzar gznev ha hae- haedgova haenihova hạlova hara hạreva hatar hatskhva hạz helez hergova hiova hiova adkhat hiova otvlid histạva hizd ho hod hornva idva igan iganaşmine igt ikạlto ikhre ikhruva ik'meva ik'ura ilava ilomi imsviva ina ioda iodaghema ipra iprala iq'os ir teo iravs irula iruli iş- isari işbrdzova işdaşliva işdgova işdruva işeşin iseskatsva işkạd işk'edulebiva işk'elkrva iskerdva işkerdva işk'vanvo işmġnova işmikhulva işoktsiva işomiva işpgholamdova işqova işsidva istavnebiva isteli işuliva işvitsva itar it'ev iti itroq'noşvo itşi itşk'vanva ivdor ivela ivelebiva ivkhe ivkheghloba ivs iz izjeva izrail izula jai jana jạpreght'ova jạpruba jạpruts'ạli jạpruts'ạlidavqar jaqtsva jạroş jartsva jasti jatşve jạvre jazi jega jegoli qmirạ jemei jiarva jiomavạn jiova jirusạlemi jmil jmora jmur jneoni jneva joha johaeldi joli jolmiot'i jom jora jrdzo jrta jruts'nil jruts'nilne juri jurişin juva jvar jvari aborul Jvari magrulvis jveba jvei jvini jvloha k'ar Kạrdzimekhrạ kạrdzkạ kari karkar kạrkiva k'aşk'i katova k'ats k'edula k'edulebiva kedz kedzukhi k'elkrva ker k'erava kerd k'erk'eti kersam kertş kertşdago kh khada khalosani khalosanine khari khari rdzema kharine kharsva khdzar khemo khest'i khest'ila khev khlat'va khmurdavi khmuri khmuridavs khna khntso kholo khorti khrạt'homa Khrista khristabzvo Khristabzvosam khrova khubi khusli khvits'i khvp'i kird k'marva k'marvo k'miva kneva kobula kolke kordva k'ova kroni kuna kundema kundeva k'up'va kurd kurdova kurdovo kurdovoba kurke kurmtsava kurmtso k'vanva kve k'verkhi kvro ladz lạjvro lạjvroma lakebiva lana lanaba lari larijeva laşegava lạsrva latşari lat'var lavs lebtşima lege leva lva mạdạgoma mạdạgova madav mạdztrạl magos magrulva mạjatva makhlomạrna mạlte mạmitsakvosam mamshi mạmtsva mana maraji maraji ut'q'mevo mạrạs mardavs mark'e marq'mevo marşva martsve maşkola maşkoli mạştova mat'ova matş mạts mdadạ mdahir mdareva mde mdigmats'ạli mdigva mdkart mdme mdmejeva mdnova mdtghaz mdveri mdzo meda medbrebesva megduva megholi mekhrạ melaeli meli melistavnebiva meoma meomela meova mepe mera meşiva met'a meteva metsikhvo mevari mevt mġạlova mghera mghoni mghrạt mghrạtikhubima mghva mgnedza mġnoba mġnojeva mgreli mġrvtso mgurva mi- mielba mielsạ mikhebuliva mikhula mino minola mioba miot'i mirmeva mirmevo misạ mit'ebeva mits'an mk'a mkare mk'eva mkhare mkhedveli mkherdova mkhlimpova mkhline mkhliti mkhrava mkhreduli mkna mkral mkrebalva mkreġoma mkreġova mk'tş'espova mkvasi mkvat mk'vdebiva mnişeva mo- modonebiva mogankhetliva moġmtş'ạlva moma momo moqdzeva mormi moti motmelova motş'ilimpova mots'orilebiva moul movtsalebiva mparevs mparveli mparveva mp'ivs mplobsva mp'ts'eva mqareva mqarevo mqeho mq'isiera mq'opi mqşama mqşava mq't'ivs mq'ts'e mq'tşeva mqva mq'var mq'vili mqvlet'i mrkhi mrtelova mrzva msar mşimuni msneva msopli msqi mşvạt mşvildi msvili msvili ninạ mta mtaki mtani mtanine mt'ạreva mt'eli mt'evs mtiane mtkhvevaşi mtkhvevaşine mt'k'inevuli mt'k'oni mtliani mt'o mtokvi mtosma mtosva mtosvi mtosvine mt'ruli mts- mtş'abs mtsali mts'ali mts'alimpova mtsare mtsaz mtsbtmirdzmidamşal mtsdadid mtsdats'ki mtşema mtşemaġvivtaba mtşemdo mtsetsvatş'reba mtşeva mtşevo mtşevoba mtsġataviso mtshorn mtsimsveba mtsjiar mtşkura mtsne mtşo mtşola mtşolasako mtşolasam mtşoskhivi mtsqrạ mtsqrveli mtssakhedzmidamşal mtşteva mtstş'eno mtveli mtvrali mtvralimpova mtvrghtsova munga muq'o mzeli mzkhal nạbi nạbi- nais nakhri nạkhvạr nạkola naova naq'ar nari naşi nats natsdago natshatar natsi mdmela ndmirni -ndz- ndzelạ neiva nevt nid nieva nihova nilova nilovo nimdzi nimkhli nimskhet'i ninạ nino nitş nitşmot nkghri nkhriadhava norma norva notghe notghetsạ nt'miş ntsiro ntşoma nuriva oba od odz- okha okhli okhro okhroli oktsi ol oliş oljeva olma olmats'ạli onzva orav ori orma ornạli ort' ortghi ortşva orul osi oskeva oşp oşpi otni otnima otnimats kh ts'ạlimats otni-ts'ạli otsa otşsebiva otşsi otvli ova ovda ovs ozan pạgha p'aghtova pạkor p'ani pạnt'ova par p'arak'eva p'ari p'arine p'erlova p'io p'irev p'itil pleda plei pogạ p'oki p'okordva pona prekova preliva prq'ts'eva prta prtebava p'tşt'oni p'tşt'va p'uli pvreva qạ- -ş qạmşi qar qarsạli qạrtoş qdzeva q'dzt'eva qema qemdva qetsma meomi qetsva q'ipts'la q'iq'ova qitsda q'jrma q'jroni qmạ qmadi qmạjeva qmar Qmarola qmartur qmel qmetava qmha qmhats'ạli qmhats'ạlima qmirạ q'mtla q'mtlebiva qmtoma qmtova q'mtş'ova -qn- qoşva q'ov qova qrhạ qrma qrtnạ qrva q'smi q'smiot'i q'sveli qşvo qtşe q'tsmina q'tsvoni q'uha q'uhotni quntsi q'uq'uli quri quridavs qvar q'vdiadiva qvela rạbtş'i rad radoli rae raq'ava rạtşomi rbneva rdev rdgala rdveba rdzema rdzeva rdznioni rdznioni adkhanen rdzniva retskhva rgava rghebdạ rghemeva rghova rghuno rieli rip'al risula risva rkhab rkhe rkhilva rkhneva rk'ida rkmena rkova rmgadi rmip'ova rmnebiva rmni Roma rqopva rsạ rtela rt'q'va rts'a rtşeva rtspeva rtspeva khvp'is ruk'an runi rupts'i rupts'srt'va rus ruti ruvạli rve rvno rzeva rzli rzqạrebiva sadova sadzoba saere sakali sakhe sakhedzma sakhejeva saktsla sakvo sakvosam sạmạla şạmdola samepo şạmi samiha samihane samqạre samsverkhi samt'o saniva sanja sạnqe sạpliva sapteli sạrep'i sarev sark'ala sạrmo sartola sartva şạrva sasmeli sạtkelos satkhva satş'a satşari sats'i sats'osumi sauli sạvsli şedzlova şeġạma şeġạva şema şen- şenbege şenetşi şenghrna şenomdo şenova şenrdze şentsmeho serm şevseba sidva şini- şiniş sipi sisk'i sist'ula sitsneva şiv skhivi slduva şme- şmeġmihiova şmets'q'ariva şmit'i şmiva şnola şnova so şoba sohaş soşmiot'i soşvi spasva sqamts sqtsne sqtsnebeva srt'va şude sudgileva sula şuli sumeva suo sup'i suruva sust'ili svamps svan şvar şvei şveni şvenidavs şvenimats arghebdi svġo şvili şvimz şvir svkhulidavs şvnelo svre svreba şvtse şvtsemormebiva svtsheli svtsheva svumi şvuri t'ạd t'ạdloba t'ạdola tadzrvo tadzrvola tadzrvosamema tadzrvuli tagi takht'i t'ani taq'vani tarebs tarebsjeva tatevs tats'e tatsebs tatuli t'ava tạvạd tạvạdipra tavisola tavsoli tavsova tbiliva tbiri tbleva tbrtstova t'dzre t'ebva teghirna tegir t'ekhvmiva tel- telapledatsva telervdema telervdeva telhova teo teove tera terjvạl t'erva tesmek'i teti t'etri t'ets'i tets'ma tevze tghandi tghas tgheskatsva tghorva tkhevadi tkhit'ova tkhmeva tkhsi t'k'mali t'k'nola t'k'nova tkoni t'k'şuli tkva tma tmelova t'meri t'mşạva tmşeva t'mverkhova t'na tnạli tojol tolova t'om t'ots'e t'q'ineba t'qts've t'q'upebivo t'q'va tra treti trha tronuva tsala tsalaotniş tsalebiva ts'ạli -ts'ạli ts'ạli mdmeghe ts'ạlima ts'ani tsạq'ova tş'areva ts'ari tş'ạto tşdequli ts'eba tşelạ tşem tşemi tşemiokhliva tsemova tşeno tşenoba tş'enova tş'epleva tş'epva tşetşri ts'eva tşgvra tşida tş'ili tşin tşişi ts'iti ts'itijveba ts'itijveba oruli ts'ivri ts'ivrişin ts'k'apva tş'keli ts'keromiş tskhae tskhaltova tşkhenova tşkhenuli tşkhieva tşkhrdebuli tskhri ts'khrik'ạ tskhurova ts'kiva ts'k'mena tsk'ugha ts'mado tsmehova tş'mevti tşmi ts'mikheva tşmiot'i Ts'mirisam tş'mlira ts'mrde tşneva tş'nimi ts'odeba ts'ogli ts'ok'ni tş'oqtş ts'ori ts'orila ts'orilebiva tsovanet'i tşovar tsoveba ts'pens ts'p'ni ts'q'arima ts'q'ariva ts'q'eba ts'q'rveva ts'q'uli tşra ts'rdari tşrdilova ts'relevro tsrolaghloba tsrova tş'smeva ts't'keva tst'o ts'ubari ts'ubarine tşutşi tsva tsvan tsvanebola tsvanebsva tşvar tş'vera ts'vina tşvino tsvlo tsvlohatar tsvo tsvoba ts'vroba tur t'ut'i t'var t'vas'i t'vasliva tvaşt' tvazkạrkiva tvazkạrkivo t'vet'gheva tvi tvilisi t'vilova tvira t'vis tvmiot'i t'vrạlo t'vrjma t'vrjva tvro u ubi- udrạlo udvar uġạr ughara uhar ukhi uk'neli uli umerva un- una undiaghleli unpari unt'meri up'alidavs uptşmova uqtsva uq'vkhots ur urbnisi ure urjul uroş urt urvni uşvalova ut'q'meva utskeli utşnov utşnovsumi uts'q'oda uvdova uvis uvisdgooni uvli uvlimomas uvmes uvmetsova v- vagdal vagdaljeva vaghras vali vama vamba vạnt'ma vạr vardza varkan vats vatş'ar vdạ vdareva vdzkeva venova verts' verts'eva vet'eli vetşova videts vin vitsva vkart vk'ava vk'meva vne vqa vrk'eli vrskhebiva vşeli vsgeva vsrt'ma vsrt'oni vsrt'va vsulebiva vtghaz vulebiva vulebivo vuli zạd zạdulebiva zạduli zagola zagova Zan zanidavs zar zarmk'vdebiva zeghe zeghva zeli zema zepuri zepurjevo zeva zi ziani zirmi zoriba zrme zrmeli rkhab zughali zuli zuni zurtva zuti zvel zveli zvisva";
  10. var tWords = sWords.split(" ");
  11.  
  12. // returns a dictionary sorted by value in descending order
  13. // (otherwise by default dictionaries are unordered, but will display by keys in alphabetical order)
  14. // (from StackOverflow)
  15. function sort_object(obj) {
  16.     items = Object.keys(obj).map(function(key) {
  17.         return [key, obj[key]];
  18.     });
  19.     items.sort(function(first, second) {
  20.         return second[1] - first[1];
  21.     });
  22.     sorted_obj={}
  23.     items.forEach(function(v) {
  24.         use_key = v[0]
  25.         use_value = v[1]
  26.         sorted_obj[use_key] = use_value
  27.     })
  28.     return(sorted_obj)
  29. }
  30.  
  31. // returns the number of matches in the lexicon of each segment that matches sPattern
  32. function Stats(sPattern) {
  33.     let tCombos = expandCategories(sPattern); // get all combinations that fit the pattern
  34.                                               // e.g. if sPattern = "tV", then this returns
  35.                                               // ["ta","tạ","te","ti","to","tu"]
  36.     let tOut = {};
  37.     for (let i = 0; i < tCombos.length; i++) {
  38.         tOut[tCombos[i]] = 0;
  39.     }
  40.     // sort the combinations by descending length*, then smoosh into a regex
  41.     // (* since some of the consonants are digraphs, e.g. "gh", and regexes match the first thing they can,
  42.     //    if we don't force it to try to match longer combinations first, it would never match e.g. "agh" -
  43.     //    that would always be counted as a match for "ag".)
  44.     let re = new RegExp(tCombos.sort(function(a,b) { return b.length - a.length }).join("|"), "g");
  45.     while (result = re.exec(sWords)) {
  46.         tOut[result[0]] = tOut[result[0]] + 1;
  47.     }
  48.     return tOut;
  49. }
  50.  
  51. // the same as above, except sorted by value in descending order
  52. function OStats(sPattern) {
  53.     let tOStats = sort_object(Stats(sPattern));
  54.     let str = '{\n' + Object.getOwnPropertyNames(tOStats).map(key => `  ${key}: ${tOStats[key]}`).join('\n') + '\n}';
  55.     console.log(str);
  56. }
  57.  
  58. // given some pattern ABC, find combinations of ABC that don't appear in the lexicon, even though AB and BC individually do
  59. function FindHoles(sPattern) {
  60.        
  61.     let tPattern = Stats(sPattern); // results for search on "ABC"
  62.     let tTop = Stats(sPattern.substring(0,2)); // results for search on "AB"
  63.     let tBottom = Stats(sPattern.substring(1)); // results for search on "BC"
  64.    
  65.     let tOut = [];
  66.    
  67.     for (let sKey in tPattern) { // for each "ABC" we tallied up the results for,
  68.         let sTop = sKey.substring(0,2); // the corresponding "AB"
  69.         let sBottom = sKey.substring(1); // the corresponding "BC"
  70.        
  71.         // if "AB" occurs, and "BC" occurs, but "ABC" doesn't
  72.         if ( (tTop[sTop] < 2) && (tBottom[sBottom] < 2) && (tPattern[sKey] > 2) ) {
  73.             // I'm not really sure what a good metric would be for deciding if a combination "occurs" or not
  74.             tOut.push(sKey);
  75.         }
  76.        
  77.     }
  78.    
  79.     return tOut;
  80.    
  81. }
  82.  
  83. FindHoles("VCC");
  84.  
  85. ////////////////////////////////////////////////////////////////////////
  86. ////////////////////////////////////////////////////////////////////////
  87.  
  88. // Everything after this point exists to power the function expandCategories, which is used in Stats
  89. // which basically determines all possible permutations of an input pattern, e.g. "VCC", that contains a reference to a category like C or V
  90. // if it looks way more complicated than it needs to be, that's because it is
  91. // it's directly taken and repurposed from a sound engine I wrote where it's meant to deal with much much more complicated input patterns
  92. // like (C)[P('),B2,r]aC(:) or whatever, not just VCC
  93. // so it's quite overkill for this particular use case, but there was no use
  94.  
  95. function join(array) {
  96.   return Array.isArray(array) ? array.join('') : array;
  97. }
  98.  
  99. function categoryValueToString(array = []) {
  100.   return `[${array.toString()}]`;
  101. }
  102.  
  103. function multiply(twoDArray1, twoDArray2) {
  104.   if (twoDArray1.length === 0 && twoDArray2.length === 0) {
  105.     return [];
  106.   }
  107.   else if (twoDArray1.length === 0) {
  108.     return twoDArray2;
  109.   }
  110.   else if (twoDArray2.length === 0) {
  111.     return twoDArray1;
  112.   }
  113.   const product = [];
  114.   for (let i = 0; i < twoDArray1.length; i++) {
  115.     for (let j = 0; j < twoDArray2.length; j++) {
  116.       product.push([...twoDArray1[i], twoDArray2[j]]);
  117.     }
  118.   }
  119.   return product;
  120. }
  121.  
  122. function expandMultiCharacterCategory(inputString) {
  123.   const multiCharCategories = Object.keys(tCategories).filter((key) => key.length > 1).sort((category1, category2) => category2.length - category1.length);
  124.   let output = inputString;
  125.   for (let category of multiCharCategories) {
  126.     const expandedCategoryString = categoryValueToString(tCategories[category]);
  127.     while (output.includes(category)) {
  128.       output = output.replace(category, expandedCategoryString);
  129.     }
  130.   }
  131.   return output;
  132. }
  133.  
  134. function hasSquareBrackets(inputString) {
  135.   for (let i = 0, ch = inputString.charAt(0); i < inputString.length; i++, ch = inputString.charAt(i)) {
  136.     if (ch === '[') {
  137.       return true;
  138.     }
  139.   }
  140.   return false;
  141. }
  142.  
  143. function expandSquareBrackets(inputString) {
  144.   if (!hasSquareBrackets(inputString)) {
  145.     return inputString;
  146.   }
  147.   let output = [[]];
  148.   for (let i = 0, ch = inputString.charAt(0), squareBrackets = 0, j = 0; i < inputString.length; i++, ch = inputString.charAt(i)) {
  149.     if (ch === '[') {
  150.       squareBrackets++;
  151.       if (squareBrackets === 1) {
  152.         output.push([]);
  153.         j++;
  154.         continue;
  155.       }
  156.     }
  157.     else if (ch === ']') {
  158.       squareBrackets--;
  159.       if (squareBrackets === 0) {
  160.         output.push([]);
  161.         j++;
  162.         continue;
  163.       }
  164.     }
  165.  
  166.     if (ch !== ' ') {
  167.       output[j].push(ch);
  168.     }
  169.   }
  170.   output = output
  171.     .map(join)
  172.     .filter((string) => string !== '')
  173.     .map(split)
  174.     .reverse()
  175.     .reduceRight(multiply)
  176.     .map(join);
  177.     return output;
  178. }
  179.  
  180. function split(inputString) {
  181.   let output = [];
  182.   for (
  183.     let i = 0, j = 0, ch = inputString.charAt(0), squareBrackets = 0;
  184.     j <= inputString.length;
  185.     j++, ch = inputString.charAt(j)
  186.   ) {
  187.     if (ch === '[') {
  188.       squareBrackets++;
  189.     }
  190.     else if (ch === ']') {
  191.       squareBrackets--;
  192.     }
  193.  
  194.  
  195.     if (squareBrackets === 0 && (ch === ',' || j === inputString.length)) {
  196.       output.push(inputString.slice(i, j));
  197.       i = j + 1;
  198.     }
  199.   }
  200.   return output;
  201. }
  202.  
  203. function stringHasCategories(inputString) {
  204.   for (const key of Object.keys(tCategories)) {
  205.     if (inputString.includes(key)) {
  206.       return true;
  207.     }
  208.   }
  209.   return false;
  210. }
  211.                    
  212. function expandCategories(inputString) {
  213.   if (!stringHasCategories(inputString)) {
  214.     return inputString;
  215.   }
  216.   let output = [[]];
  217.   for (let i = 0, ch = inputString.charAt(0); i < inputString.length; i++, ch = inputString.charAt(i)) {
  218.     if (tCategories[ch]) {
  219.       output = multiply(output, tCategories[ch]);
  220.     }
  221.     else {
  222.       output.forEach((op) => op.push(ch));
  223.     }
  224.   }
  225.   output.forEach((op, i) => { output[i] = op.join(''); });
  226.   return output;
  227. }
Add Comment
Please, Sign In to add comment