 |

11-24-2007, 09:17 AM
|
|
WebProWorld Pro
|
|
Join Date: Oct 2003
Location: Alberta, Canada
Posts: 230
|
|
It's play, but what the hey? abstract problem
Code:
function factors(x) {
var n = x.length;
for ( var k = 0, q = new Array(); k < n; k++ ) { q[k] = 1 };
var p = 1, r = 0, i = 0, j = 1;
while ( i < n ) {
if ( x[i]==x[j] ) q[r]++; else r++;
i++; j++;
};
while ( r > 0 ) {
r--;
p = p * factorial(q[r]);
};
return 1/p;
};
The returned value is the denominator of nPr expressed as a factor. Everything is volatile save for for the returned value of one over p. The abstract value, r, is the one that perplexes me. How can I share this value outside of this function without disrupting the mathematical purpose?
The call to this function is an equation which hands over a sorted array: nPr = nPn * factors( a.sort() );
I'd really love to snag 'r' before its regression if it is possible. Convoluting the purely mathematical with hardened scripting seems such a shame...
For completeness, this should be included, though it's quite moot,
Code:
function factorial(x) {
var n, f = 1;
while ( x > 0 ) { n = x; f = f * n; x--; };
return f;
};
It's also the numerator in nPn or nPr. This assumes possible multiple multiples in the sample array, each evaluated as factorials before factoring them into p.
__________________
Volunteer for something in your community today!
Last edited by weegillis : 11-24-2007 at 09:44 AM.
Reason: Addendum
|

11-25-2007, 10:16 AM
|
 |
WebProWorld Veteran
|
|
Join Date: Dec 2006
Location: Calgary, Alberta, Canada
Posts: 389
|
|
Re: It's play, but what the hey? abstract problem
Put r in the argument list of the function and pass it in by reference:
function factors(x, &r) {
....
}
|

11-25-2007, 08:35 PM
|
|
WebProWorld Pro
|
|
Join Date: Oct 2003
Location: Alberta, Canada
Posts: 230
|
|
Re: It's play, but what the hey? abstract problem
Thanks, Dave. After trying a dozen different approaches, all with some form of error or another, still stuck with the same problem.
I follow the concept - 'r' as a reference is shared.
Code:
function scramble(word) {
var a = new Array(), b = new Array();
var w = word.toUpperCase();
a = w.split("");
b = a.sort( function() { return 0.5 - Math.random() } );
for( var j = 0, v = b.length, s = new String(); j < v; j++ ) { s += b[j]; };
document.theform.permute.value=factorial(word.length)*factors(a.sort());
return s;
}
function factors(x) {
for ( var k = 0, n = x.length, q = new Array(); k < n; k++ ) { q[k] = 1 };
var p = 1, r = 0, i = -1;
while ( i < n ){ i++; if ( x[i]==x[i+1] ) q[r]++; else r++; };
while ( r > 0 ) { r--; p *= factorial(q[r]); }; return 1/p;
}
function factorial(x) {
var n, f = 1;
while ( x > 0 ) { n = x; f *= n; x--; };
return f;
}
To describe further, this function, combined with factorial(x) calculates the denominator in the permutation:
nPr = n! x p where p = 1/ a!b!c!...
In the example "12315645237839",
x = [ 1,1,2,2,3,3,3,4,5,5,6,7,8,9 ],
n = 14,
p = 2! x 2! x 3! x 2!, (2-1s, 2-2s, 3-3s, 2-5s)
and r counts up to 9.
n - r = 5, the number of repeated elements in x.
There is no simple way to pass 'r' into the function (zeroed) and read it back on returning 1/p, owing to the nature of the calling function, itself an equation. I tried declaring it as a global, and removed it from the var list in this function, but read back '0', every time.
This is obviously not a real problem. The purpose of the function is to calculate 1/p, which it does fine. It would be nice to be able to report (n-r) on return.
Example form:
HTML Code:
<div><form name="theform" method="post" action=""><fieldset><legend>Word Scrambler Lite</legend>
<label for="theword">A Word: <input type="text" size="24" name="theword" id="theword" /></label>
<input type="button" name="thebutton" value="Scramble!" onclick="with (document.theform) { result.value=scramble(theword.value) };" /><br />
<label for="result">Output: <input type="text" size="24" id="result" name="result" readonly="readonly" /></label>
<label for="permute"><input type="text" size="9" id="permute" name="permute" readonly="readonly" />nPr</label>
</fieldset></form></div>
Live Example
__________________
Volunteer for something in your community today!
Last edited by weegillis : 11-25-2007 at 11:18 PM.
Reason: revised code
|

11-26-2007, 11:09 AM
|
 |
Moderator
|
|
Join Date: Jun 2006
Location: United States
Posts: 1,840
|
|
Re: It's play, but what the hey? abstract problem
To make sure I understand the problem, you want to obtain the max value r reaches during the execution of the factors() function? Assuming that you have set a global value to store r called rvalue, the following should work (changing the spot where r is incremented so it will at the same time record the new value into rvalue).
Code:
function factors(x) {
global rvalue;
var n = x.length;
for ( var k = 0, q = new Array(); k < n; k++ ) { q[k] = 1 };
var p = 1, r = 0, i = 0, j = 1;
while ( i < n ) {
if ( x[i]==x[j] ) {
q[r]++;
} else {
r++;
rvalue = r;
}
i++; j++;
};
while ( r > 0 ) {
r--;
p = p * factorial(q[r]);
};
return 1/p;
};
__________________
The best way to learn anything, is to question everything.
|

11-26-2007, 11:38 PM
|
|
WebProWorld Pro
|
|
Join Date: Oct 2003
Location: Alberta, Canada
Posts: 230
|
|
Re: It's play, but what the hey? abstract problem
This is a more drawn out example, to demonstrate the problem...
HTML Code:
...<br />
<label for="verbose">Summary:<textarea id="verbose" name="verbose" readonly="readonly" cols="49" rows="3"></textarea></label>
</fieldset></form></div>
<script type="text/javascript">
function scramble(word) {
var a=new Array(), b=new Array(), summary=new String();
var w=word.toUpperCase(), n=word.length, r=0; // r is declared here
a=w.split("");
b=a.sort(function(){return 0.5-Math.random()});
for(var i=0,j=b.length,s=new String();i<j;i++){s+=b[i];};
var nPn=factorial(n);
var nPr=nPn*factors(a.sort()); alert(n-r); // return alert
var effect = nPn==nPr ? 'No repetitions.' : nPr + ' due to repetitions.'
summary+= word + ' [ ' + a + ' ] ';
summary+= nPn + ' permutations, assuming ' + n + ' unique factors. ';
summary+= effect;
document.theform.permute.value=nPr;
document.theform.verbose.value=summary;
return s;
}
function factors(x) {
for(var k=0,n=x.length,q=new Array();k<n;k++){q[k]=1};
var p=1,i=-1;r=0;
while(i<n){i++;if(x[i]==x[i+1]){q[r]++;} else {r++;}};i=r; alert(r); // max-r alert
while(i>0){i--;p*=factorial(q[i]);}; return 1/p;
}
function factorial(x){var n,f=1; while(x>0){n=x;f*=n;x--;}; return f;}
</script>
</body>
Note the alerts in factors() and in scramble(). The former reports the correct value for r, the latter reports 0 (or more correctly, n-r reports n).
HTML Code:
var effect = nPn==nPr ? 'No repetitions.' : nPr + ' due to ' + n-r + ' repetitions.'
What's more, when we insert the equation, n-r, we get NaN.
If 'r' is global, it should be visible in factors(), but I keep getting error 'r not defined' when I remove r=0 from factors().
__________________
Volunteer for something in your community today!
|

11-27-2007, 11:00 AM
|
 |
Moderator
|
|
Join Date: Jun 2006
Location: United States
Posts: 1,840
|
|
Re: It's play, but what the hey? abstract problem
Currently, the alert(n-r); command will output n because r has been set to 0 a few lines above.
You mention that there is a global variable n that this function should be using. I am not sure how that variable is set as global, but it is incorrect. In PHP, every variable that is not inside a function is considered a global variable. To access one of these global variables, you need to declare such at the very beginning of the function with a line "global $variable". If you have a variable you want to share between functions, you need to set that variable as global in every function.
__________________
The best way to learn anything, is to question everything.
|

11-27-2007, 10:17 PM
|
|
WebProWorld Pro
|
|
Join Date: Oct 2003
Location: Alberta, Canada
Posts: 230
|
|
Re: It's play, but what the hey? abstract problem
We're a long way from PHP, here. This is beginner javascript.
I've tried declaring r outside of the functions, but kept get undefined errors once factors() is run.
Now trying it again,
Code:
var r,effect;
function scramble(word) {
...
var w=word.toUpperCase(), n=word.length;// r=0
...
var nPr=nPn*factors(a.sort());alert(n-r);
effect = nPn==nPr ? 'No repetitions.' : nPr + ' due to ' + n-r + ' repetitions.'
... alert(n-r) reports correctly.
The problem shows up here:
Code:
var effect=nPn==nPr ? 'No repetitions.' : nPr + ' due to ' + n-r + ' repetitions.'
which reports, "NaN repetitions."
Funniest thing, the whole problem goes away with a little change:
Code:
var nPr=nPn*factors(a.sort()), d = n-r;
effect = nPn==nPr ? 'No repetitions.' : nPr + ' due to ' + d + ' repetitions.'
Does this whole problem boil down to a syntax error? The expanded working version is at the Live Example given above.
__________________
Volunteer for something in your community today!
|

11-28-2007, 11:26 AM
|
 |
Moderator
|
|
Join Date: Jun 2006
Location: United States
Posts: 1,840
|
|
Re: It's play, but what the hey? abstract problem
So thats what all those <script> tags meant... I feel silly now...
Anyway, yes, it looks for javascript that this is a syntax issue. If you enclosed the n-r in parentheses, that would also work I think. Right now, n and r are converted to strings, and you can't subtract one string from another. Surrounding them with parens would cause the variables to be evaluated as numbers, then the result would convert to a string for display.
__________________
The best way to learn anything, is to question everything.
|

11-29-2007, 12:39 AM
|
|
WebProWorld Pro
|
|
Join Date: Oct 2003
Location: Alberta, Canada
Posts: 230
|
|
Re: It's play, but what the hey? abstract problem
Thanks Wige. Right you are. Wrapping the expression in brackets is the cure, with 'r' declared globally. Here is the tightened up version of this project (sans stylesheet, which is online).
Code:
<body>
<div><form name="theForm" method="post" action=""><fieldset><legend>Word Scrambler Lite</legend>
<label for="theWord">A Word:<input type="text" size="24" name="theWord" id="theWord" /></label>
<input type="button" name="theButton" value="Scramble!" onclick="scramble();" /><br />
</fieldset><fieldset><legend>Repeating gives new result</legend>
<label for="theResult">Output:<input type="text" size="24" id="theResult" name="theResult" readonly="readonly" /></label>
<label for="permute"><input type="text" size="9" id="permute" name="permute" readonly="readonly" />P(X)</label><br />
<label for="verbose">Summary:<textarea id="verbose" name="verbose" readonly="readonly" cols="49" rows="3"></textarea></label>
</fieldset></form></div>
<script type="text/javascript">
//<!--
var r;
function scramble(){
var v=outerObject.theWord.value.toUpperCase();
var a=[], b=[];
a=v.split(""); v+=' ['+a+']\n';
b=a.sort(function(){return 0.5-Math.random()});
v+='['+a+'] ';
outerObject.theResult.value=b.join("");
var n=b.length, nPn=factorial(n);
var Px=nPn*factors(b.sort());
v+='['+b+']\n';
v+=nPn+' permutations, assuming '+n+' unique factors.\n';
v+= nPn==Px ? 'No repetitions.' : Px+' due to '+(n-r)+' repetitions.';
outerObject.permute.value=Px;
outerObject.verbose.value=v;
};
function factors(x){
var p=1,i=-1,q=[];r=0;
while(i<x.length){i++;q.push(p);if(x[i]==x[i+1]){q[r]++;} else {r++;}};i=r;
while(i>0){i--;p*=factorial(q[i]);}; return 1/p;
};
function factorial(x){var n,f=1; while(x>0){n=x;f*=n;x--;}; return f;};
var outerObject = document.theForm;
outerObject.theWord.defaultValue = 'scrambler';
window.onload = scramble();
// -->
</script>
</body>
__________________
Volunteer for something in your community today!
Last edited by weegillis : 11-29-2007 at 12:44 AM.
Reason: added link to example
|

12-01-2007, 05:20 AM
|
|
WebProWorld Pro
|
|
Join Date: Oct 2003
Location: Alberta, Canada
Posts: 230
|
|
Re: It's play, but what the hey? abstract problem
Probably should have tested in IE before posting code. My bad...
The one thing that jumps out is that IE doesn't seem to recognize formName.inputName.value.defaultValue="%somevalue% ", which forced me to create and populate a value attribute in the input tag. It's probably the right way to do it, but as a novice I was rather basking in the faint glow of the DOM method to preload the form that works fine in FF. Live and learn.
What is keeping IE from recognizing value.defaultValue= ? Is this another Mozilla thing?
__________________
Volunteer for something in your community today!
|

12-03-2007, 10:30 AM
|
 |
Moderator
|
|
Join Date: Jun 2006
Location: United States
Posts: 1,840
|
|
Re: It's play, but what the hey? abstract problem
I am not absolutely sure about this, but I think that IE sees one container more than Firefox. I think that the safest way to get the value of a form field is with the getElementById function. So if your field has the id num, you should be able to use var $n = getElementById('num').value; in either Firefox or Internet Explorer.
__________________
The best way to learn anything, is to question everything.
|

12-04-2007, 03:06 AM
|
|
WebProWorld Pro
|
|
Join Date: Oct 2003
Location: Alberta, Canada
Posts: 230
|
|
Re: It's play, but what the hey? abstract problem
How does that tie in with outerObject=window.document.theForm;?
Once we start getting elements might we do just as well to generate the form in its entirety, and skip the html altogether?
__________________
Volunteer for something in your community today!
|

12-04-2007, 10:27 AM
|
 |
Moderator
|
|
Join Date: Jun 2006
Location: United States
Posts: 1,840
|
|
Re: It's play, but what the hey? abstract problem
The getElementById searches all the elements on the page, so you don't need to find each node of the document to call the desired element. This corrects for processing differences between IE and FF. Otherwise you would need two different access methods, one for each browser, to locate the form element. It also allows for a measure of portability - if you have a script for Ajax that displays output in a specifically named div, the script can be called by any page and work regardless of where in the DOM that div is placed.
Honestly, I don't know enough about Javascript to know how generating the form elements with Javascript will affect the script's ability to find the data. I don't think it would cause a problem though.
__________________
The best way to learn anything, is to question everything.
|
| Thread Tools |
|
|
| Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
|