 # Javascript Challenge: Lotto Number Generator

Written on September 23rd 2009 by Matthias Reuter

This post was originally published at united-coders.com Somehow it's credited to a different author there.

The German lottery currently holds a jackpot of about 30 million Euro. A friend of mine took the bait and participated yesterday. Since he is a software developer, he wrote a small program to get him six random numbers in the range of 1 and 49.

Well, it’s not difficult to write such a program. The challenge is to do so in little bytes. So I challenge you:

Write a JavaScript function that generates random lotto numbers. This function has to return an array of six different numbers from 1 to 49 (including both) in ascending order. You may use features of ECMA-262-3 only, that means no Array.contains and stuff. You must not induce global variables.

The function has to look like this

``````function getRandomLottoNumbers() {
}
``````

Minify your function using JSMin or any other minfier and count the bytes between the outer curly braces.

To participate in this challenge, simply post your solution as a comment.

Spoiler warning In the following I describe the steps I took for my solution. Don’t read if you want to submit your own.

## First steps

First attempt. My idea is to generate an array containing the numbers from 1 to 49 and then remove elements until six remain. 117 bytes.

``````function getRandomLottoNumbers() {
var n = [];

for (var i = 1; i < 50; i++) {
n.push(i);
}

while (n.length > 6) {
n.splice(Math.floor(Math.random() * n.length), 1);
}

return n;
}
``````

First optimization: n.length is used twice, so store it in a variable. Use i, since that is defined already. 114 bytes.

``````function getRandomLottoNumbers() {
var n = [];

for (var i = 1; i < 50; i++) {
n.push(i);
}

while ((i = n.length) > 6) {
n.splice(Math.floor(Math.random() * i), 1);
}

return n;
}
``````

Next step: optimize variable declaration. Saves one var. 112 bytes.

``````function getRandomLottoNumbers() {
var n = [], i;

for (i = 1; i < 50; i++) {
n.push(i);
}

while ((i = n.length) > 6) {
n.splice(Math.floor(Math.random() * i), 1);
}

return n;
}
``````

Now I changed the algorithm. I switched from a while-loop to a for-loop, which saves another four bytes: 108 bytes.

``````function getRandomLottoNumbers() {
var n = [], i;

for (i = 1; i < 50; i++) {
n.push(i);
}

for (i = 49; i > 6; i--) {
n.splice(Math.floor(Math.random() * i), 1);
}

return n;
}
``````

## Below 100 bytes

Don’t you think, `Math.floor(Math.random() * i)` could be written shorter? Yes, it can. I accidentally stumbled upon a way today. Replace it by `Math.random() * i | 0`. Saves 10 bytes, we’re down to 98.

``````function getRandomLottoNumbers() {
var n = [], i;

for (i = 1; i < 50; i++) {
n.push(i);
}

for (i = 49; i > 6; i--) {
n.splice(i * Math.random() | 0, 1);
}

return n;
}
``````

Save another byte moving the initializing of i one line up. This leaves an empty first statement in the for-loop, but that’s still valid JS. 97 bytes.

``````function getRandomLottoNumbers() {
var n = [], i = 1;

for (; i < 50; i++) {
n.push(i);
}

for (i = 49; i > 6; i--) {
n.splice(i * Math.random() | 0, 1);
}

return n;
}
``````

Now if the first loop starts at 0 and runs until 49, we don’t have to initialize the second for-loop. Saves two bytes, down to 95.

``````function getRandomLottoNumbers() {
var n = [], i = 0;

for (; i < 49; i++) {
n.push(i + 1);
}

for (; i > 6; i--) {
n.splice(i * Math.random() | 0, 1);
}

return n;
}
``````

Save another four bytes by moving the incrementation and decrementation of i. 91 bytes.

``````function getRandomLottoNumbers() {
var n = [], i = 0;

for (; ++i < 50;) {
n.push(i);
}

for (; --i > 6;) {
n.splice(i * Math.random() | 0, 1);
}

return n;
}
``````

## Final solution

Now, Douglas Crockford will hate me for this, but some semicolons are optional in Javascript. Remove them to get my final solution of 88 bytes:

``````function getRandomLottoNumbers() {
var n = [], i = 0;

for (; ++i < 50;) {
n.push(i)
}

for (; --i > 6;) {
n.splice(i * Math.random() | 0, 1)
}

return n
}
``````

Aww, curly braces are optional in my case. Needs two semicolons again, but saves four braces. 86 bytes

``````function getRandomLottoNumbers() {
var n = [], i = 0;

for (; ++i < 50;) n.push(i);

for (; --i > 6;) n.splice(i * Math.random() | 0, 1);

return n
}
``````

Minimized it’s this:

``````function getRandomLottoNumbers() {
var n=[],i=0;for(;++i<50;)n.push(i);for(;--i>6;)n.splice(i*Math.random()|0,1);return n
}
``````