By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
432,403 Members | 891 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 432,403 IT Pros & Developers. It's quick & easy.

Open Source / Collaboration

P: n/a
Hi. I am an under-graduate currently studying Open Source (Linux) vs Closed
Source and Collaboration within the IT Community. I am fairly new to
Javascript and I have written a "Lottery Program" which essentially picks 6
numbers at random and puts them in sequence.

Would anyone would be interested in modifying the code below to

a). Check for bugs
b). Make the program more efficient

My idea is to see the response to this so as to make a comparison to
developers and the Open Source Movement.

Thanks

<HTML>

<HEAD>

<TITLE> Program_7.2.1 First Program

</TITLE>

<SCRIPT LANGUAGE = "JavaScript">

/*********************************/

/* */

/* Lottery Program */

/* Author: Bill Marsden */

/* Date: 17/05/2004 */

/* */

/*********************************/

// Define Variables

var lott_one;

var lott_two;

var lott_three;

var lott_four;

var lott_five;

var lott_six;

var sort_numbers;

var another_go;

another_go = 'YES'

while (another_go == 'YES')

{

// Load the balls! Our adjudicator tonight is Bill Marsden !

lott_one = Math.floor(Math.random()*50+1) ;

lott_two = Math.floor(Math.random()*50+1) ;

// Main body of program testing for unique numbers

if (lott_two == lott_one)

{

lott_two = Math.floor(Math.random()*50+1)

}

;

lott_three = Math.floor(Math.random()*50+1) ;

if (lott_three == lott_two || lott_three == lott_one)

{

lott_three = Math.floor(Math.random()*50+1)

}

;

lott_four = Math.floor(Math.random()*50+1) ;

if (lott_four == lott_three || lott_four == lott_two || lott_four ==
lott_one)

{

lott_four = Math.floor(Math.random()*50+1)

}

;

lott_five = Math.floor(Math.random()*50+1) ;

if (lott_five == lott_four || lott_five == lott_three ||

lott_five == lott_two || lott_five == lott_one)

{

lott_five = Math.floor(Math.random()*50+1)

}

;

lott_six = Math.floor(Math.random()*50+1) ;

if (lott_six == lott_five || lott_six == lott_four ||

lott_six == lott_three || lott_six == lott_two || lott_six ==
lott_one)

{

lott_six = Math.floor(Math.random(1)*50+1)

}

;

// We have our selection, lets sort them in ascending order

sort_numbers = [lott_one , lott_two , lott_three , lott_four , lott_five ,
lott_six]

function sortNumbers(a, b) { return a - b}

// Are you a lucky winner? Check the output!

document.write('And this weeks winning numbers are:' + '<BR>'

+ sort_numbers.sort(sortNumbers) + '<BR>' + '<BR>' ) ;

another_go = window.prompt('Another go? Enter YES/NO' , '') ;

}

;

</SCRIPT>

</HEAD>

<BODY>

</BODY>

</HTML>

Jul 23 '05 #1
Share this Question
Share on Google+
29 Replies


P: n/a
Lee
Bill Marsden said:

Hi. I am an under-graduate currently studying Open Source (Linux) vs Closed
Source and Collaboration within the IT Community. I am fairly new to
Javascript and I have written a "Lottery Program" which essentially picks 6
numbers at random and puts them in sequence.

Would anyone would be interested in modifying the code below to

a). Check for bugs
b). Make the program more efficient

My idea is to see the response to this so as to make a comparison to
developers and the Open Source Movement.


I can't help but suspect that your idea is to get somebody
else to do your homework assignment.

1. Your code is hard to read.
In my newsreader it's double-spaced.
There are extraneous semi-colons on lines by themselves.

2. You should use an array, instead of lott_one, lott_two, etc.

3. Your algorithm allows duplicate numbers.

if (lott_two == lott_one)
{
lott_two = Math.floor(Math.random()*50+1)
}
// lott_two can still be the same as lott_one

4. You don't allow the page to ever finish loading,
which is the only reason you can get away with
using document.write() more than once. That may
be ok for a very simple case, but it's questionable.
There are other things that I would do differently,
but you probably haven't covered them, yet.
Reading the newsgroup's FAQ before posting is always
a good idea. I believe it contains a link to a page
that has an efficient function for returning random
numbers without repetition.
http://www.jibbering.com/faq/#FAQ4_22
The link to "Dealing and Shuffling".

Jul 23 '05 #2

P: n/a
Bill Marsden wrote:
Hi. I am an under-graduate currently studying Open Source (Linux)
vs Closed Source and Collaboration within the IT Community.
Either that or you are a student trying to find a credible excuse for
getting help with your programming homework (it is that time of year
again :)
I am fairly new to Javascript and I have written
a "Lottery Program" which essentially picks 6 numbers
at random and puts them in sequence.
That certainly sounds like a programming exercise. It certainly isn't
something that you would write for the benefit of humanity.
Would anyone would be interested in modifying the code below to
The best modification is to delete it and start again.
a). Check for bugs
b). Make the program more efficient

My idea is to see the response to this so as to make a
comparison to developers and the Open Source Movement.
If that is your real reason I don't see how you could learn anything
useful from this exercise.

<snip> <SCRIPT LANGUAGE = "JavaScript">
The language attribute is deprecated in HTML 4.01 and the type attribute
is required:-

<SCRIPT type="text/javascript">

<snip> // Define Variables
var lott_one;
var lott_two;
var lott_three;
var lott_four;
var lott_five;
var lott_six;
Six variables with numeric suffixes makes it look like you probably want
to be using an Array instead.

<snip> another_go = 'YES'
another_go looks like it should be boolean. Generally, if a variable is
only going to have two states it should be boolean. In this case the two
states are "YES" and NOT "YES", they should be true and false.
while (another_go == 'YES')
if - another_go - had been boolean you would not need to be doing a
relatively heavyweight string comparison in the test expression of
your - while - loop. Instead you would use:-

while (another_go)

- which is considerably simpler and faster.

<snip> // Load the balls! Our adjudicator tonight is Bill Marsden !
?
lott_one = Math.floor(Math.random()*50+1) ;

lott_two = Math.floor(Math.random()*50+1) ;
Random numbers form 1 to 50 (except maybe on the buggy and old Opera 4 &
5 browsers where they might get to 51). That is 0 to < 50 plus 1 == 1 to
< 51, rounded down == 1 to 50.
// Main body of program testing for unique numbers
if (lott_two == lott_one)
{

lott_two = Math.floor(Math.random()*50+1)

}
You realise that this isn't going to work properly because there is
always a chance that the replacement - lott_two - number will be the
same as the first and so still identical to - lott_one -?

<snip> if (lott_three == lott_two || lott_three == lott_one)
A pattern is starting to emerge.

<snip> if (lott_six == lott_five || lott_six == lott_four ||

lott_six == lott_three || lott_six == lott_two || lott_six ==
lott_one)


Yes, this is a ludicrous thing to be doing.

I would go into the details of why but in reality the algorithm
implemented here is just wrong. The algorithm should be:-

1. Create a re-orderable collection/Array of all of
the numbers (1 to 50 in your case).
2. Randomly shuffle that collection/Array.
3. Pull the first 6 numbers from the front (or end),
they should be random and they will never coincide
with each other.

Google for "javascript shuffle"

<snip>

Now the part that tells the student with a desire to have their homework
done for them from the individual with a genuine desire; an
implementation that no idle student could ever hope to get away with
handing it as their own work :)

In previous discussions of the shuffling problem I have often wondered
whether a stack could be used instead of an array. With the items
representing the numbers being dropped onto the stack such that they
would fall to a randomly determined depth within the stack. I don't know
if that would be a mathematically good shuffle but I thought it was
about time I had a go at implementing it:-

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<script type="text/javascript">

var sixNumbers = (function(){
function pull(){
base = this.next;
return this;
}
function toString(){
return String(this.valueOf());
}
function b(itm){
itm.next = b;
itm.index = 1;
return itm;
}
function aSort(a, b){return a - b;}
b.pull = pull;
b.index = 0;
b.next = b;
b.toString = toString;
b.valueOf = function(){return '';};
var base = b;
var outAr = [];
function getStackFnc(num){
function p(itm, index){
if(index < p.index){
p.next = p.next(itm, index);
++p.index;
return p;
}else{
itm.next = p;
itm.index = p.index + 1;
return itm;
}
}
p.pull = pull;
p.index = NaN;
p.next = null;
p.valueOf = function(){return num;};
p.toString = toString;
return p;
}
for(var c = 50;--c;){
base = base(getStackFnc(c), 1);
}
return ({
toString:function(){
var tempBase = b;
for(var c = outAr.length;c--;){
base = base(outAr[c],1);
}
for(var c = 50;--c;){
tempBase = tempBase(base.pull(),
(((Math.random()%1)*(tempBase.index+1))|0));
}
base = tempBase;
for(var c = 6;c--;){
outAr[c] = base.pull();
}
return outAr.sort(aSort).join(' ');
}
});
})();

</script>
</head>
<body>
<form action="" name="f">
<input type="button" value="Get Numbers"
onclick="this.form.elements.t.value = sixNumbers;">
<textarea cols="70" rows="10" name="t"></textarea>
</form>
</body>
</html>

The output range is 1 to 49, if you do want 1 to 50 you will have to
change the two occurrences of 50 to 51.

Richard.
Jul 23 '05 #3

P: n/a
Lee
Richard Cornford said:
Now the part that tells the student with a desire to have their homework
done for them from the individual with a genuine desire; an
implementation that no idle student could ever hope to get away with
handing it as their own work :)


<html>
<head>
<script type="text/javascript">
function lotto(m,n){
var selected=new Array();
var hat=new Array(m+1);
for(while n--){
var r=Math.floor(Math.random()*m+1);
selected.push(hat[r]?hat[r]:r);
hat[r]=m--;
}
return selected.sort(numerically);
}
function numerically(a,b){return a-b}
</script>
</head>
<body>
<button onclick="this.innerHTML=lotto(50,5)">go</button>
</body>
</html>

Jul 23 '05 #4

P: n/a
Lee
Lee said:

Richard Cornford said:
Now the part that tells the student with a desire to have their homework
done for them from the individual with a genuine desire; an
implementation that no idle student could ever hope to get away with
handing it as their own work :)


<html>
<head>
<script type="text/javascript">
function lotto(m,n){
var selected=new Array();
var hat=new Array(m+1);
for(while n--){
var r=Math.floor(Math.random()*m+1);
selected.push(hat[r]?hat[r]:r);
hat[r]=m--;
}
return selected.sort(numerically);
}
function numerically(a,b){return a-b}
</script>
</head>
<body>
<button onclick="this.innerHTML=lotto(50,5)">go</button>
</body>
</html>

Extra credit: find the bug.

Jul 23 '05 #5

P: n/a
JRS: In article <cb*********@drn.newsguy.com>, seen in
news:comp.lang.javascript, Lee <RE**************@cox.net> posted at Thu,
24 Jun 2004 10:07:22 :
Lee said:

Richard Cornford said:
Now the part that tells the student with a desire to have their homework
done for them from the individual with a genuine desire; an
implementation that no idle student could ever hope to get away with
handing it as their own work :)

function lotto(m,n){
var selected=new Array();
var hat=new Array(m+1);
for(while n--){
var r=Math.floor(Math.random()*m+1);
selected.push(hat[r]?hat[r]:r);
hat[r]=m--;
}
return selected.sort(numerically);
}
function numerically(a,b){return a-b} <button onclick="this.innerHTML=lotto(50,5)">go</button>
Extra credit: find the bug.


That reminds me of a problem published in Scientific American, long ago;
a diagram showing circles and rectangles of paper dropped on the floor,
the question being to identify three instances of four points (a point
being a visible corner or intersection of edges) lying on a circle.
Four such instances could be found.

One bug is that the required version of JS is not specified. The OP is
apparently a UK student; he may have a nice new computer himself, but
his institution and its staff may be impoverished.

If I remove both the line with the amazing syntax and its mate ISTM that
I should have script that executes (but does not satisfy the OP) in
*your* browser; but I do not have Array.push, so it does not execute for
me. It should be easy enough to do without Array.push.

I have a syntax change which, combined with replacing push, seems at
first to work; but not at second.

If such a method works, it should work for drawing most or all of the
balls, and that will find some errors rather quickly.

It appears to be a method taking time proportional to the number of
balls drawn, rather than the number available; this is good.

I'd be pleased to put a compatible working copy on my Web page, with
attribution.

ISTM that the OP has one ball more than the customary 49.

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4
<URL:http://jibbering.com/faq/> JL / RC : FAQ for news:comp.lang.javascript
<URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
Jul 23 '05 #6

P: n/a
Bill Marsden wrote:
Hi. I am an under-graduate currently studying Open Source (Linux) vs Closed
Source and Collaboration within the IT Community. I am fairly new to
Javascript and I have written a "Lottery Program" which essentially picks 6
numbers at random and puts them in sequence.

Would anyone would be interested in modifying the code below to

a). Check for bugs
b). Make the program more efficient


<snip>
For some ideas look at:

http://www.mickweb.com/javascript/ra...y_lottery.html

Good luck

Jul 23 '05 #7

P: n/a
Lee
Dr John Stockton said:
I have a syntax change which, combined with replacing push, seems at
first to work; but not at second.

If such a method works, it should work for drawing most or all of the
balls, and that will find some errors rather quickly.

It appears to be a method taking time proportional to the number of
balls drawn, rather than the number available; this is good.

I'd be pleased to put a compatible working copy on my Web page, with
attribution.

The for(while) line was a typo. I changed the loop and apparently
made the edit in the post, rather than making a fresh copy of
tested code. I chose push() partly because it was unlikely to be
familiar to a student and partly for brevity, knowing that it made
the code less library worthy.

I'm relieved that the error I caught isn't so obvious as to be
completely humiliating. The algorithm simply doesn't work.
I didn't test with large enough n until after I posted it.
Then I started seeing duplicates.

Say m=5, n=3

pass 1:
r := 4
selected.push(4)
hat[4] := 5
m := 4

pass 2:
r := 3
selected.push(3)
hat[3] := 4 *** 4 re-enters the selection pool!
m := 3

pass 3:
r := 3
selected.push(hat[3]=4) *** duplicate!
hat[3] := 3
m := 2

result: 4,3,4

Jul 23 '05 #8

P: n/a
JRS: In article <Uh*******************@twister.nyroc.rr.com>, seen in
news:comp.lang.javascript, Mick White <mw******@BOGUSrochester.rr.com>
posted at Fri, 25 Jun 2004 14:04:36 :
Bill Marsden wrote:
...
and I have written a "Lottery Program" which essentially picks 6
numbers at random and puts them in sequence.

Would anyone would be interested in modifying the code below to

a). Check for bugs
b). Make the program more efficient


<snip>
For some ideas look at:

http://www.mickweb.com/javascript/ra...y_lottery.html

I have looked at that page. It was not clear to me how it was supposed
to work, so I went to its source code.
The code is not indented.

While it is entirely appropriate for delivered code that is intended to
be read only by browsers to be not indented, code intended to be read or
edited by humans should be indented to show its intended logical
structure - preferably by two or three spaces per level, and not by a
tab. If that is not in the FAQ or the FAQ notes, then it should be.
The code uses getElementById. That is nowadays a reasonable choice; but
it should be an informed choice on the part of the code editor.
Accordingly, for code offered as example code, it would be well to note
the presence of a comparatively recent function, and/or to provide code
to emulate, if necessary, that function. Such code may be in the FAQ
notes; it is in my js-other.htm (taken from a post by Randy).
Your method is, basically, to generate an array of numbers (i.e. make
the balls), to shuffle it, and to take from the beginning the required
number of entries.

Your shuffle is done by a large number (300) of swaps of randomly-chosen
elements. Random is thus called 600 times, with, for 59 balls, 59
possibilities per call. Therefore there are, in principle assuming
random to be perfect, 59^600 ways for the code to run. But there are
59! possible orders of the balls, and 59^600 is not a multiple of 59!,
so the sequences cannot all be equi-probable, as they should be.

Granted, 59^600/59! is large : I think that it is about
23,398, ...,806.964 ~= 2.3e982, so the deviation will be unimportant.
But, more significantly, the method is slower than need be; only 59
calls of random are needed to shuffle the array equi-probably. The
method is quite well-known, in Knuth, linked from the FAQ, almost
obvious, and codes slightly shorter.

Starting with the array, one selects a ball at random, and swaps it with
the end ball. The last-placed ball is thus randomly chosen. The
process is repeated using only those balls not already chosen, until
there is one ball left (or no balls).

To pick a few balls, just terminate the process early and use the end
balls.
To obtain a random-order array of sequential numbers, there is no need
to pre-fill the array; a slight modification generates them directly.
At each step, the array is considered to be expanded by one position;
the content of a random location in the expanded array is moved to the
new position; the next new number is placed at that random position.
In code offered for others to read, it is better not to use l as an
identifier; it can look very much like 1 - likewise O and 0.
I would not choose to use func as an identifier for something which is
not a function. PrintResults is in effect a simple version of FAQ
DynWrite (with reversed parameters), and can print any string.
My copy of W3's checker TIDY (1st November 2003) reports several errors.
Many readers will be unfamiliar with some or all of the various
lotteries shown; it would be well to describe them briefly in words.

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4
<URL:http://jibbering.com/faq/> JL / RC : FAQ for news:comp.lang.javascript
<URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
Jul 23 '05 #9

P: n/a
JRS: In article <cb*********@drn.newsguy.com>, seen in
news:comp.lang.javascript, Lee <RE**************@cox.net> posted at Fri,
25 Jun 2004 16:53:07 :
The algorithm simply doesn't work.


I thought that it might be a version of that obtained via David Rifkind
and c.l.p.d.m, in <URL:http://www.merlyn.demon.co.uk/pas-rand.htm#Draw>:

type RandomSet = set of 1..MaxN ;

{ Generate M non-repeating random numbers from 1 to N }
procedure GenerateRandomSet(M, N : integer ; var aSet : RandomSet) ;
var J : integer ;
begin
if M < 1 then aSet := []
else begin
GenerateRandomSet(M - 1, N - 1, aSet) ;
J := Random(N) + 1 { J is in [1..N] } ;
if J in aSet then Include(aSet, N) else Include(aSet, J) ;
end ;
end {GenerateRandomSet} ;

It seems to work, & DR is trustworthy.

Throwing it rapidly into javascript, I got a function returning an array
of length <= N in which M elements existed at random positions indexed
1..N - which corresponds to Pascal/Delphi set notation. A minor change
then made the element at position K, if present, be of value K. One
needs then only to strip the undefined elements, which ISTM that sort
will do. There may be a quicker way than sort, for this special case;
and I cannot say whether sort really should do what is wanted.
function GenerateRandomSet(M, N) {
// Generate M non-repeating random numbers from 1 to N }
if (M<1) return []
var aSet = GenerateRandomSet(M-1, N-1)
var J = Math.floor(Math.random()*N) + 1 // J is in 1..N
aSet[J] ? aSet[N]=N : aSet[J]=J
return aSet }

Ans = GenerateRandomSet(3, 9) // .sort() // to compactify
NOTES :
1. The translation needs to be checked
2. The javascript needs to be tested
3. In fact, sort only moves the selected elements together. How best
to compactify?
4. Recursion may not be quickest

BTW, it is easy to see that Random is called M times, with appropriate
handling to get the correct number of possibilities.

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 MIME.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/&c., FAQqy topics & links;
<URL:http://www.merlyn.demon.co.uk/clpb-faq.txt> RAH Prins : c.l.p.b mFAQ;
<URL:ftp://garbo.uwasa.fi/pc/link/tsfaqp.zip> Timo Salmi's Turbo Pascal FAQ.
Jul 23 '05 #10

P: n/a
rh
Dr John Stockton wrote :
<snip>

Throwing it rapidly into javascript, I got a function returning an array
of length <= N in which M elements existed at random positions indexed
1..N - which corresponds to Pascal/Delphi set notation. A minor change
then made the element at position K, if present, be of value K. One
needs then only to strip the undefined elements, which ISTM that sort
will do. There may be a quicker way than sort, for this special case;
and I cannot say whether sort really should do what is wanted.
function GenerateRandomSet(M, N) {
// Generate M non-repeating random numbers from 1 to N }
if (M<1) return []
var aSet = GenerateRandomSet(M-1, N-1)
var J = Math.floor(Math.random()*N) + 1 // J is in 1..N
aSet[J] ? aSet[N]=N : aSet[J]=J
return aSet }

Ans = GenerateRandomSet(3, 9) // .sort() // to compactify


Netscape (and its Gecko friends?) don't do very well on numerically
sorting and grouping sparse arrays, unless the compare function is
specifically set up to shift the "undefined" values into the high end
of the array.

An alternative may be:

function GenerateRandomSet(M, N) {
// Generate M non-repeating random numbers from 1 to N }
if ( M < 1 ) return {}; // Use an object instead of array
var aSet = GenerateRandomSet(M-1, N-1);
var J = Math.floor(Math.random()*N) + 1; // J is in 1..N
aSet[J] ? aSet[N]=N : aSet[J]=J;
return aSet ;
}

AnsObj = GenerateRandomSet(M,N);
var Ans = [];
for (var k in AnsObj) Ans.push( AnsObj[k] );
Ans.sort( function (a,b) { return a-b } );

../rh
Jul 23 '05 #11

P: n/a
Lee wrote:
<snip>
The for(while) line was a typo. <snip>

I immediately spotted that.
... . The algorithm simply doesn't work.

<snip>

But I am glad you said that because I couldn't see any way of changing
the code so that it would not output duplicates.

I was looking at my version and noticed that I could lose the sort
operation because I knew the order of the values when they were first
created. Storing the relationships at the time of creation allows the
results array to be assembled pre-sorted, and simplifies the resulting
code.

var sixNumbers = (function(){
var base,orderBase,outAr = [];
function pull(){
base = this.next;
return this;
}
function toString(){
return String(this.valueOf());
}
function b(itm){
itm.next = b;
itm.index = 1;
return itm;
}
function getFinal(index){
var ar = this.orderPrv.getFinal(index);
if(this.index <= index){
ar[ar.length] = this;
}
return ar;
}
b.pull = pull;
b.index = 0;
b.next = b;
b.toString = toString;
b.valueOf = function(){return '';};
b.getFinal = function(){
outAr.length = 0
return outAr;
}
base = orderBase = b;
function getStackFnc(num){
function p(itm, index){
if(index < p.index){
p.next = p.next(itm, index);
++p.index;
return p;
}else{
itm.next = p;
itm.index = p.index + 1;
return itm;
}
}
p.pull = pull;
p.index = NaN;
p.next = null;
p.valueOf = function(){return num;};
p.toString = toString;
p.orderPrv = orderBase;
p.getFinal = getFinal;
return (orderBase = p);
}
for(var c = 1;c < 50;c++){
base = base(getStackFnc(c), 1);
}
return ({
toString:function(){
var tempBase = b;
while(base.index){
tempBase = tempBase(base.pull(),
((Math.random()*(tempBase.index+1))|0));
}
base = tempBase;
return orderBase.getFinal(6).join(' ');
}
});
})();

Richard.
Jul 23 '05 #12

P: n/a
JRS: In article <t0**************@merlyn.demon.co.uk>, seen in
news:comp.lang.javascript, Dr John Stockton <sp**@merlyn.demon.co.uk>
posted at Sat, 26 Jun 2004 23:16:29 :
3. In fact, sort only moves the selected elements together. How best
to compactify?


Sort, then assign the length ?
If the array is long, replace the sort by a scan that moves elements
down to the first vacancy.

The method in the cited article looks like a recursive form of my
GenerateSubsetUnorderedSparse2(M, N), which has for some while been on
the FAQ-cited page.

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4
<URL:http://jibbering.com/faq/> JL / RC : FAQ for news:comp.lang.javascript
<URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
Jul 23 '05 #13

P: n/a
Dr John Stockton wrote:
JRS: In article <Uh*******************@twister.nyroc.rr.com>, seen in
news:comp.lang.javascript, Mick White <mw******@BOGUSrochester.rr.com>
posted at Fri, 25 Jun 2004 14:04:36 :
Bill Marsden wrote:
I have written a "Lottery Program" which essentially picks 6
numbers at random and puts them in sequence.
<snip>
For some ideas look at:

http://www.mickweb.com/javascript/ra...y_lottery.html
I have looked at that page. It was not clear to me how it was supposed
to work, so I went to its source code.
The code is not indented.

While it is entirely appropriate for delivered code that is intended to
be read only by browsers to be not indented, code intended to be read or
edited by humans should be indented to show its intended logical
structure - preferably by two or three spaces per level, and not by a
tab. If that is not in the FAQ or the FAQ notes, then it should be.


My concern in this case is that the page function, but your point is
well taken

The code uses getElementById. That is nowadays a reasonable choice; but
it should be an informed choice on the part of the code editor.
Accordingly, for code offered as example code, it would be well to note
the presence of a comparatively recent function, and/or to provide code
to emulate, if necessary, that function. Such code may be in the FAQ
notes; it is in my js-other.htm (taken from a post by Randy).

Yes, you're correct, there's nothing in the code that couldn't be
tweaked to work in very old browsers or to fail unceremoniously in js
challenged browsers.


Your method is, basically, to generate an array of numbers (i.e. make
the balls), to shuffle it, and to take from the beginning the required
number of entries.

Your shuffle is done by a large number (300) of swaps of randomly-chosen
elements. Random is thus called 600 times, with, for 59 balls, 59
possibilities per call. Therefore there are, in principle assuming
random to be perfect, 59^600 ways for the code to run. But there are
59! possible orders of the balls, and 59^600 is not a multiple of 59!,
so the sequences cannot all be equi-probable, as they should be.

Granted, 59^600/59! is large : I think that it is about
23,398, ...,806.964 ~= 2.3e982, so the deviation will be unimportant.
But, more significantly, the method is slower than need be; only 59
calls of random are needed to shuffle the array equi-probably. The
method is quite well-known, in Knuth, linked from the FAQ, almost
obvious, and codes slightly shorter.
From the start, I was concerned with the shuffle function's efficiency,
not so much with its pure randomness.

Starting with the array, one selects a ball at random, and swaps it with
the end ball. The last-placed ball is thus randomly chosen. The
process is repeated using only those balls not already chosen, until
there is one ball left (or no balls).

To pick a few balls, just terminate the process early and use the end
balls.
To obtain a random-order array of sequential numbers, there is no need
to pre-fill the array; a slight modification generates them directly.
At each step, the array is considered to be expanded by one position;
the content of a random location in the expanded array is moved to the
new position; the next new number is placed at that random position.

Certainly looks to be more efficient. Thanks.

In code offered for others to read, it is better not to use l as an
identifier; it can look very much like 1 - likewise O and 0.

Good advice, mea culpa.

I would not choose to use func as an identifier for something which is
not a function. PrintResults is in effect a simple version of FAQ
DynWrite (with reversed parameters), and can print any string.

What would you suggest? I use "func" to remind me that the parameter to
be passed was to be the return statement of a function.

My copy of W3's checker TIDY (1st November 2003) reports several errors.

One errror now, according to http://validator.w3.org/check

....boldred=function(){return "<span style='color:red'
"+this.bold()+"</span>"}

The element named above was found in a context where it is not allowed.
This could mean that you have incorrectly nested elements -- such
as a "style" element in the "body" section instead of inside
"head" -- or two elements that overlap (which is not allowed).

I know what is being pointed out, but how would you create a "legal"
bold red String prototype ?

Many readers will be unfamiliar with some or all of the various
lotteries shown; it would be well to describe them briefly in words.


The intended audience knows more about the lotteries than Spasky does
about gambits...

Thanks for your critique, a rel eye opener.

Mick

Jul 23 '05 #14

P: n/a
Mick White wrote:
<snip>
One errror now, according to http://validator.w3.org/check

...boldred=function(){return "<span style='color:red'"
+this.bold()+"</span>"} ^^
The element named above was found in a context where it is not
allowed. This could mean that you have incorrectly nested
elements -- such
as a "style" element in the "body" section instead of inside
"head" -- or two elements that overlap (which is not allowed).

I know what is being pointed out, but how would you create a "legal"
bold red String prototype ?

<snip>

It is likely that the validator is having trouble with the - </ -
character sequence and escaping that to - <\/ - would pacify it. But if
you want bold why not use a - font-weight:bold; - clause in the STYLE
attribute of the containing SPAN?

Richard.
Jul 23 '05 #15

P: n/a
Dr John Stockton wrote:
<snip>
While it is entirely appropriate for delivered code that is intended
to be read only by browsers to be not indented, code intended to be
read or edited by humans should be indented to show its intended
logical structure - preferably by two or three spaces per level, and
not by a tab. If that is not in the FAQ or the FAQ notes, then it
should be.
The notes state that *posted* code should be indented with spaces rather
than tabs, and explain the practical reasons for doing so. I don't think
I would recommend the same restriction for all code. Different people
seem to favour different depths of indentation. If they indent with tabs
and set their text editors up so that tabs are the indent they prefer
others can do likewise, and all can work on the same code in the comfort
of their own preferred indentation depths.
The code uses getElementById. ... <snip> provide code to emulate, if necessary, that function. Such code may
be in the FAQ notes; it is in my js-other.htm (taken from a post by
Randy).

<snip>

It is. It is on the alternative DynWrite page (as getElementById is used
there).

Richard.
Jul 23 '05 #16

P: n/a
JRS: In article <29**************************@posting.google.com >, seen
in news:comp.lang.javascript, rh <co********@yahoo.ca> posted at Sat, 26
Jun 2004 21:06:54 :

AnsObj = GenerateRandomSet(M,N);
var Ans = [];
for (var k in AnsObj) Ans.push( AnsObj[k] );
Ans.sort( function (a,b) { return a-b } );


MSIE4 does not do well on push - but that's easy to code around.
The wanted elements are already in order; no _real_ sorting is needed.

But your k in AnsObj extracts them in historical order, I think; so

function TestGRS(X, Z, M, N) { var Q, j, k=0, Ans=[]
Q = GenerateRandomSet(M, N)
for (j=0 ; j < Q.length ; j++) if (Q[j]) Ans[k++] = Q[j]
X.value = Q ; Z.value=Ans /* or return Ans */ }

Q.length appears the highest index used in Q, plus one - I believe that
to be as it should be.

However, if the selection is sparse, (k in Q) then sort may be faster.

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4
<URL:http://jibbering.com/faq/> JL / RC : FAQ for news:comp.lang.javascript
<URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
Jul 23 '05 #17

P: n/a
rh
Dr John Stockton wrote:
MSIE4 does not do well on push - but that's easy to code around.
Right. The usual? :

if (! Array.prototype.push) {
Array.prototype.push = function() {
for(var k=0; k < arguments.length; k++) this[this.length] =
arguments[k];
}
}

should supplant.
The wanted elements are already in order; no _real_ sorting is needed.

Realized that at some later point and re-worked it into the following
non-recursive non-push, non-sort dependant (equivalent, I think :))
function, which has a certain similarity to your revision with regard
to the array compression:

function GenerateRandomSet(M,N) {
var aSet = [], n, J;
if (M <= N && M > 0) {
for (var k = 1; k <= M; k++) {
n = N-M+k;
J = Math.floor(Math.random()*n+1) ;
aSet[J] ? aSet[n]= n : aSet[J] = J;
}
for (var j=k=0; k<aSet.length; k++) aSet[k]? aSet[j++]=aSet[k]:0;
aSet.length = j;
}
return aSet;
}
But your k in AnsObj extracts them in historical order, I think; so

function TestGRS(X, Z, M, N) { var Q, j, k=0, Ans=[]
Q = GenerateRandomSet(M, N)
for (j=0 ; j < Q.length ; j++) if (Q[j]) Ans[k++] = Q[j]
X.value = Q ; Z.value=Ans /* or return Ans */ }

Q.length appears the highest index used in Q, plus one - I believe that
to be as it should be.

However, if the selection is sparse, (k in Q) then sort may be faster.


Aside from the problems mentioned earlier with Netscape sorting of
sparse arrays, I found IE to be extremely slow when sorting on large
M, sparse arrays. Therefore, I think sort would be best left out of
it.

The non-recursiveness should be more efficient and avoids recursion
depth limitations that can occur in some browsers with relatively
modest-sized N.

../rh
Jul 23 '05 #18

P: n/a
JRS: In article <%_*******************@twister.nyroc.rr.com>, seen in
news:comp.lang.javascript, Mick White <mw******@BOGUSrochester.rr.com>
posted at Sun, 27 Jun 2004 15:48:11 :
Dr John Stockton wrote:
JRS: In article <Uh*******************@twister.nyroc.rr.com>, seen in
news:comp.lang.javascript, Mick White <mw******@BOGUSrochester.rr.com>
posted at Fri, 25 Jun 2004 14:04:36 :
For some ideas look at:

http://www.mickweb.com/javascript/ra...y_lottery.html
What would you suggest? I use "func" to remind me that the parameter to
be passed was to be the return statement of a function.


Retn? Ansr? But the routine, IIRC, will handle any string; so maybe
St or Str?

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 MIME.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/&c., FAQqy topics & links;
<URL:http://www.merlyn.demon.co.uk/clpb-faq.txt> RAH Prins : c.l.p.b mFAQ;
<URL:ftp://garbo.uwasa.fi/pc/link/tsfaqp.zip> Timo Salmi's Turbo Pascal FAQ.
Jul 23 '05 #19

P: n/a
JRS: In article <29**************************@posting.google.com >, seen
in news:comp.lang.javascript, rh <co********@yahoo.ca> posted at Sun, 27
Jun 2004 21:01:04 :
Dr John Stockton wrote:
MSIE4 does not do well on push - but that's easy to code around.
Right. The usual? :

if (! Array.prototype.push) {
Array.prototype.push = function() {
for(var k=0; k < arguments.length; k++) this[this.length] =
arguments[k];
}
}

should supplant.


No need in this case, where only one element is pushed at a time; direct
code suffices.

The wanted elements are already in order; no _real_ sorting is needed.


Realized that at some later point and re-worked it into the following
...

for (var j=k=0; k<aSet.length; k++) aSet[k]? aSet[j++]=aSet[k]:0;
aSet.length = j;
Why the :0, or is it just that ? needs : ?
// At this step, j should have the same value as M.
However, if the selection is sparse, (k in Q) then sort may be faster.


Aside from the problems mentioned earlier with Netscape sorting of
sparse arrays, I found IE to be extremely slow when sorting on large
M, sparse arrays. Therefore, I think sort would be best left out of
it.


Above, the data will not be sparse when being sorted.
The non-recursiveness should be more efficient and avoids recursion
depth limitations that can occur in some browsers with relatively
modest-sized N.


Good.

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk Turnpike v4.00 IE 4
<URL:http://jibbering.com/faq/> JL / RC : FAQ for news:comp.lang.javascript
<URL:http://www.merlyn.demon.co.uk/js-index.htm> jscr maths, dates, sources.
<URL:http://www.merlyn.demon.co.uk/> TP/BP/Delphi/jscr/&c, FAQ items, links.
Jul 23 '05 #20

P: n/a
rh
Dr John Stockton wrote:
...
for (var j=k=0; k<aSet.length; k++) aSet[k]? aSet[j++]=aSet[k]:0;
aSet.length = j;
Why the :0, or is it just that ? needs : ?


It's just syntax fodder, producing an expression result that is
discarded when exercised. The "for() if()" syntax you used may well be
preferable for both clarity and efficiency.
// At this step, j should have the same value as M.


Yes.

../rh
Jul 23 '05 #21

P: n/a
rh
Dr John Stockton wrote:
...
for (var j=k=0; k<aSet.length; k++) aSet[k]? aSet[j++]=aSet[k]:0;
aSet.length = j;
Why the :0, or is it just that ? needs : ?


It's just syntax fodder, producing an expression result that is
discarded when exercised. The "for() if()" syntax you used may well be
preferable for both clarity and efficiency.
// At this step, j should have the same value as M.


Yes.

../rh
Jul 23 '05 #22

P: n/a
JRS: In article <29**************************@posting.google.com >, seen
in news:comp.lang.javascript, rh <co********@yahoo.ca> posted at Mon, 28
Jun 2004 22:07:36 :

It's just syntax fodder, producing an expression result that is
discarded when exercised. The "for() if()" syntax you used may well be
preferable for both clarity and efficiency.


Thanks.

In fact, the "compacting" stage is unnecessary, since the elements which
are put into aSet can be duplicated, in sequence of creation, in an
array bSet. The order of bSet is not fully random, for M>1; and is
systematic for M>=N. M<1 needs no specific test (I assume M, N are
integer).

If needed, the result can be sorted; but sorting should be a separate
stage.

function GenRndSubSet(M, N) { var aSet = [], bSet=[], j, k, n
if (M>N) M = N
for (k = 0; k < M; k++) { n = N - M + k + 1
j = Math.floor(Math.random()*n + 1)
if (aSet[j]) j = n
bSet[k] = aSet[j] = j }
return bSet }

Sorting is convenient if lottery results are to be checked; but not
necessary if a decimating centurion's intent is to select ten out of a
hundred.

<URL:http://www.merlyn.demon.co.uk/js-randm.htm> is updated, in colour.

--
John Stockton, Surrey, UK. ?@merlyn.demon.co.uk DOS 3.3, 6.20; Win98.
Web <URL:http://www.merlyn.demon.co.uk/> - FAQqish topics, acronyms & links.
PAS EXE TXT ZIP via <URL:http://www.merlyn.demon.co.uk/programs/00index.htm>
My DOS <URL:http://www.merlyn.demon.co.uk/batfiles.htm> - also batprogs.htm.
Jul 23 '05 #23

P: n/a
rh
Dr John Stockton wrote:
...

<URL:http://www.merlyn.demon.co.uk/js-randm.htm> is updated, in colour.


One final small note: The line

if (M<0) return aSet

in RH_GenRndSubSet could be dropped. The returned result for negative
M should be an empty array (the same as for M=0).

Thanks for the attribution -- does that mean I have to be nice to you
now? ;).

Seriously, if credit is due, I'd say most of it goes to Lee and to
you.

../rh
Jul 23 '05 #24

P: n/a
Lee wrote:
Lee said:
<script type="text/javascript">
function lotto(m,n){
var selected=new Array();
var hat=new Array(m+1);
for(while n--){ ^^^^^^^^^^^^^^ [...]


Extra credit: find the bug.

^^^^^^^^^^^^

[x] done

As usual, please send it to the account specified
on the opposite page of this posting.
Regards,
PointedEars
Jul 23 '05 #25

P: n/a
Richard Cornford wrote:
Dr John Stockton wrote:
While it is entirely appropriate for delivered code that is intended
to be read only by browsers to be not indented, code intended to be
read or edited by humans should be indented to show its intended
logical structure - preferably by two or three spaces per level, and
not by a tab. If that is not in the FAQ or the FAQ notes, then it
should be.


The notes state that *posted* code should be indented with spaces rather
than tabs, and explain the practical reasons for doing so. I don't think
I would recommend the same restriction for all code. Different people
seem to favour different depths of indentation. If they indent with tabs
and set their text editors up so that tabs are the indent they prefer
others can do likewise, and all can work on the same code in the comfort
of their own preferred indentation depths.


That may help for certain text editors. However, with others and when
displaying source code outside of text editors, the tab character may
have a different meaning, aligning the text to next possible tab grid
column of the terminal rather than creating a fixed spacing. Repeatedly
this has resulted in bad display on different devices and thus hardly
legible code (apart from the fact that there are programming languages
where indentation depth is considered to create block structures rather
than delimiter characters), so it is best to avoid tab characters as
whitespace in source code at all. Space whitespace, usually 2 and/or 4
of it, has sufficed for indentation to date.
PointedEars
Jul 23 '05 #26

P: n/a
On Sat, 03 Jul 2004 23:38:45 +0200, Thomas 'PointedEars' Lahn
<Po*********@nurfuerspam.de> wrote:
Repeatedly
this has resulted in bad display on different devices and thus hardly
legible code (apart from the fact that there are programming languages
where indentation depth is considered to create block structures rather
than delimiter characters), so it is best to avoid tab characters as
whitespace in source code at all. Space whitespace, usually 2 and/or 4
of it, has sufficed for indentation to date.


so the first thing I have to do is search and replace those spaces to
tabs which has a much worse risk of stuff going wrong than you've
suggested - 4 spaces per indent is absolutely unusable to me, and
gives no flexibility. tab (but not on usenet)

Jim.
--
comp.lang.javascript FAQ - http://jibbering.com/faq/

Jul 23 '05 #27

P: n/a
Jim Ley wrote:
On Sat, 03 Jul 2004 23:38:45 +0200, Thomas 'PointedEars' Lahn
<Po*********@nurfuerspam.de> wrote:
Repeatedly this has resulted in bad display on different devices
and thus hardly legible code (apart from the fact that there are
programming languages where indentation depth is considered to
create block structures rather than delimiter characters), so it is
best to avoid tab characters as whitespace in source code at all. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ Space whitespace, usually 2 and/or 4 of it, has sufficed for
indentation to date.


so the first thing I have to do is search and replace those spaces to
tabs [...]


I wonder how you get *this* idea?
PointedEars
Jul 23 '05 #28

P: n/a
On Sun, 04 Jul 2004 00:30:02 +0200, Thomas 'PointedEars' Lahn
<Po*********@nurfuerspam.de> wrote:
Jim Ley wrote:
On Sat, 03 Jul 2004 23:38:45 +0200, Thomas 'PointedEars' Lahn
<Po*********@nurfuerspam.de> wrote:
Repeatedly this has resulted in bad display on different devices
and thus hardly legible code (apart from the fact that there are
programming languages where indentation depth is considered to
create block structures rather than delimiter characters), so it is
best to avoid tab characters as whitespace in source code at all. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^ Space whitespace, usually 2 and/or 4 of it, has sufficed for
indentation to date.


so the first thing I have to do is search and replace those spaces to
tabs [...]


I wonder how you get *this* idea?


Because space whitespace of 4 is too large, I cannot read that
indention effectively (my tabwidth is set to 1) it will reduce my
coding effectiveness by many orders of magnitude.

Jim.
--
comp.lang.javascript FAQ - http://jibbering.com/faq/

Jul 23 '05 #29

P: n/a
JRS: In article <40**************@PointedEars.de>, seen in
news:comp.lang.javascript, Thomas 'PointedEars' Lahn
<Po*********@nurfuerspam.de> posted at Sat, 3 Jul 2004 23:38:45 :
Richard Cornford wrote:
The notes state that *posted* code should be indented with spaces rather
than tabs, and explain the practical reasons for doing so. I don't think
I would recommend the same restriction for all code. Different people
seem to favour different depths of indentation. If they indent with tabs
and set their text editors up so that tabs are the indent they prefer
others can do likewise, and all can work on the same code in the comfort
of their own preferred indentation depths.


However, if the material is treated in a manner which converts tabs to
spaces - and at least some news-posting software does that - then it is
necessary first to ensure that the tab stop spacing used in conversion
is set to suit both the material and the medium.

That may help for certain text editors. However, with others and when
displaying source code outside of text editors, the tab character may
have a different meaning, aligning the text to next possible tab grid
column of the terminal rather than creating a fixed spacing. Repeatedly
this has resulted in bad display on different devices and thus hardly
legible code (apart from the fact that there are programming languages
where indentation depth is considered to create block structures rather
than delimiter characters), so it is best to avoid tab characters as
whitespace in source code at all. Space whitespace, usually 2 and/or 4
of it, has sufficed for indentation to date.


Evidently you do not understand the difference between not recommending
and recommending not. Richard was expressing a liberal position in
respect of non-posted code; one sufficiently liberal that only a
dirigiste would find occasion to differ.
Also, you give an uncommon interpretation of the tab character.

In coding, they are commonly used only at the beginning of a line, and a
row of leading tab characters have the same effect as the same number of
multiple-spaces.

But it is intrinsic to the tab concept that it is not fixed width; it
occupies one position on the visible line, plus as many more as are
needed to reach the next "tab stop". This usage derives, I expect, from
mechanical typewriter usage, where tab stops were optional protrusions
that could stop the carriage going further. Interpretation of a tab as
giving a fixed spacing, independent of position, seems to me to be most
unusual, possibly unique.

In computing, tab stops are very commonly defaulted to be after each
8n'th column. A reader should always consider it likely, if there is
nothing to the contrary written, that such a tab setting is what an
author had in mind.
I have tried indentation by one per logical level; it is too little to
suit me. Two or three spaces seems fine; and anything more than four
seems to make the code hard to read.
In News/Mail, the character } (/inter alia/) should never be in the
first column; it is very likely to be taken as implying that the line is
a quoted line.

--
John Stockton, Surrey, UK. ??*@merlyn.demon.co.uk Turnpike v4.00 MIME.
Web <URL:http://www.merlyn.demon.co.uk/> - FAQish topics, acronyms, & links.
Check boilerplate spelling -- error is a public sign of incompetence.
Never fully trust an article from a poster who gives no full real name.
Jul 23 '05 #30

This discussion thread is closed

Replies have been disabled for this discussion.