http://www.chrispearson.org/pages/programming/javascript/perms.asp
09h16
Wednesday, 8. October 2008

RECURSIVE JAVASCRIPT

If you're like me then someone else's recursive code makes your mind hurt. Sometimes I find my own code has the same effect.

Some time ago I needed to generate every permutation of a given set of numbers and to do it across an intranet, at the client. I put this example together while I was designing the web page - It's designed for clarity of reference more than elegance.

Click here to run perms


Note that the output page is correctly formed HTML but, for clarity, has been coded largely without formatting beyond a simple table to generate columns of data: There is a back button at the bottom of the output listing to return to this page.

So, how does it work?

The script loops through the required number of instances for the permutation, which the user provides through the named text box

<input type="text"
       name="ElementsToPerm"
       size="5"
       value="4"
       tabindex="1"
       onBlur="ElementCount=ElementsToPerm.value">

setting the JavaScript variable ElementCount then using it in the loop

for (i=0; i < ElementCount; i++)

and calling the function OutputPerms(ValsArray, PrevValsArray) with an array of
digit elements and an array of the previous elements.

The code relies on a JavaScript function's ability to call itself with different parameters.

Once the code is executing, the progress towards generating all possible permutations can
best be shown by getting the code to document itself: un-commenting the code shown
below right will display the progress of generating the permutations.

(A lot of what is displayed is to format the output to make it more readable.)

Each time the code in function OutputPerms needs to deal with a digit, the function calls itself with new arrays (ValsArray, PrevValsArray) as parameters.

The code doesn't take into account how many interations it will need to make to generate all possible permutations - Perms for four digits are returned very quickly (24 results) whereas the 720 posibilities for six digits can be quite slow.

 

/* ******************************************************************************
* OUTPUT TO DEMONSTRATE WHAT IS GOING ON                                        *
*********************************************************************************
document.write("<BR>===================================================<BR>");
document.write("<BR>Main loop i=" + i + "<BR><BR>CONTENTS OF NewValsArray<BR>");
document.write("Length of NewValsArray is " + NewValsArray.length + "<BR>");
for (ii=0; ii < NewValsArray.length; ii++) {
    document.write("<BR>" + NewValsArray[ii]);
}
document.write("<BR><BR>CONTENTS OF NewPrevValsArray<BR>");
for (ii=0; ii < NewPrevValsArray.length; ii++) {
    document.write("<BR>" + NewPrevValsArray[ii]);
}
document.write("<BR>CALLS ITSELF . . .<BR>==================<BR>");
*********************************************************************************
*/

When Internet Explorer detects a long-running loop it will (by default) display the dialog shown to the right.

Click on "No" to allow the script to run through to its conclusion.

Note, also, that a lot of the code does nothing more than write out HTML, as in the addition of the "Back" button at the end of the output:

document.write("<p><input type='button' value='&lt;= Back' name='cmdBack'"); /* Add back button */
document.write("onClick='javascript:history.back()'></p>");

which outputs the HTML

<p><input type='button' value='&lt;= Back' name='cmdBack'onClick='javascript:history.back()'></p>

and which, in turn,the browser delivers as

Top of this page

xxx,xxx

copyright ©2000 - 2008 Chris Pearson