Raiding the Lost Lottery Line

Finnish lottery: pick 7 numbers out of 40.

See also Raiding the Lost Average.

ABC

ABC

Much guesswork here; I didn’t bother installing the (freely available) ABC interpreter on my computer but tried to figure out the syntax from the Quick Reference. See the Lost Average page for more information.

HOW TO RETURN lottery:
    PUT {} IN line
    WHILE #line < 7:
        PUT random * 36 + 1 IN lot
        IF lot not.in line:
            PUT lot IN line
    WRITE line
APL

APL

APL (where the abbreviation really means “a programming language”) is one of the oddest, if not the oddest, programming language ever created. It doesn’t use words in any sense of the word (pun not intended) but mathematical symbols. It is extremely concise for the knowledgeable few and horrendously cryptic for the rest of us.

Anyway, the following code, which I stole from Wikipedia (changing just the values to apply to Finnish lottery) is actually picking up 7 numbers out of 40, and since the result is not stored in a variable, APL by its basic rule displays it.

x[⍋x←7?40]
AWK

AWK

This is not really a task for AWK whose forte is in reading and parsing text files. Here the whole body of a normal AWK program is left empty and only the “BEGIN” and “END” sections, intended for pre- and postformatting respectively, stand. But it works―as soon as you give the end-of-file character from the keyboard…

# Drawing the lottery line in AWK

BEGIN {
    while (chosen < 7) {
        lot = int(rand() * 40) + 1
        if (!lottery[lot]) {
            lottery[lot] = 1
            chosen ++
        }
    }
}

END {
    for (i in lottery)
        print i " "
    print "\n"
}
BASIC

BASIC

This solution is in very primitive BASIC to give the feel of the language as it once was. (Those days are far gone―and we are no poorer for that!)

First a table of 40 cells is defined; this automatically sets the value of the cells to 0. Next we get a random number. If the cell in the table whose index is this number is still 0, the number can be used; otherwise we try another number. When 7 numbers are chosen, we can print the results and quit.

100 REM Drawing the lottery line in BASIC
110 REM
120 DIM L(40)
130 A=INT(RND(1)*40)+1
140 IF L(A)=1 THEN GOTO 130
150 L(A)=1
160 N=N+1
170 IF N<7 THEN GOTO 130
180 FOR I=1 TO 40
190 IF L(I)=1 THEN PRINT I;
200 NEXT I
210 PRINT
220 END
C

C

Follows the lines of the strategy given in the BASIC example above, the control structures are just a bit more advanced.

/* Drawing the lottery line in C */

#include <stdio.h>
#include <stdlib.h>
#define RAND_MAX    36

void main(void)
{
    char lottery[40];
    int lot, chosen = 0, i;

    while (chosen < 7) {
        lot = rand();
        if (!lottery[lot]) {
            lottery[lot] = 1;
            chosen ++;
        }
    }
    for (i = 0; i < 40; i ++) {
        if (lottery[i])
            printf("%n ", i + 1);
        printf("\n");
    }
}
C++

C++

No object-orientedness here: this follows the C solution closely but utilises the new features of C++ (as compared to C).

/* Drawing the lottery line in C++ */

#include <iostream.h>

void main(void) {
    char lottery[40];
    int lot, chosen = 0;

    while (chosen < 7) {
        lot = rand();
        if (!lottery[lot]) {
            lottery[lot] = 1;
            chosen ++;
        }
    }
    for (int i = 0; i < 40; i ++) {
        if (lottery[i])
            cout << i;
        cout << endl;
    }
}
D

D

We could follow the model of C/C++ here but—like Go—D has a strong standard library with which to do various things. Here we utilize slices, a dynamic form of arrays. The find function from the std.algorithm module is used in a similar way to Python’s in operator or Lisp’s member function to find out if a randomly chosen number has already been added to the line.

// Drawing the lottery line in D

import std.stdio;
import std.format;
import std.random;
import std.algorithm;

void main()
{
    int[] chosen;

    while (chosen.length < 7) {
        auto lot = uniform(1, 40);
        if (find(chosen, lot) == [])
            chosen ~= lot;
    }
    sort(chosen);
    writefln("%(%s, %)", chosen);
}
Erlang

Erlang

In a functional language the biggest hurdle to overcome is how to collect a sequence of seven numbers when you cannot change the values of any of the variables. Well, by doing it recursively. I have absolutely no idea if this is idiomatic Erlang or not but it works.

%% Drawing the lottery line in Erlang

-module(lottery).
-export([lottery/0]).

lottery() ->
    lottery([]).

lottery(Chosen) when length(Chosen) < 7 ->
    Lot = random:uniform(40),
    Updated = case lists:member(Lot, Chosen) of
                false -> [Lot|Chosen];
                true -> Chosen
              end,
    lottery(Updated);

lottery(Chosen) ->
    lists:sort(Chosen).
Go

Go

By contrast to C/C++, here we can do something smarter by utilizing the Go standard library. First we seed the random number generator with current time to obtain real (although pseudo-) randomness. Then we permutate the integers from 0 to 36, i.e., place them in a random order, and take the first seven. These are then sorted.

(As the program stands, this is really erroneous: it generates seven random numbers in the range of [0, 36], not [1, 40]. My next task will be to find a simple enough correction for this. Since there seems to be no function in the rand package that allows to set a minimum, I guess the easiest way is to let this stand but correct the numbers by +1 when displayed to the user.)

// Drawing the lottery line in Go

package main

import (
    "fmt"
    "math/rand"
    "sort"
    "time"
)

func main() {
    generator := rand.New(rand.NewSource(time.Now().UnixNano()))
    lottery := generator.Perm(40)[:7]
    sort.Ints(lottery)
    fmt.Println(lottery)
}
Icon

Icon

These examples are intended to illustrate the peculiarities―and the power―of Icon.

In the first example we first create a list of 40 elements. Then we set the elements to consecutive numerical values from 1 to 40. Next, we randomize the whole list. Note some operators: the asterisk “*” returns the length of a list; the exclamation mark “!” returns the elements from the list one by one (or generates the list); the question mark “?” returns a random element. Icon also allows reversal assignment (e.g., “a :=: b” swaps the values of the variables). Finally, we just print out the first seven numbers of the now randomized list.

# Drawing the lottery line in Icon

link random

procedure main()
    randomize()
    lottery := list(40)
    every !lottery := 1 to 40
    every i := *lottery to 2 by -1 do
        lottery[?i] :=: lottery[i]
    every write(lottery[1 to 7])
end

The second example here uses sets, one of the sequential data types in Icon: it is like a list but the elements are unique. In a way this approximates the working of a real lottery machine.

# Drawing the lottery line in Icon

link random

procedure main()
    randomize()
    lottery := set(1 to 40)
    chosen := set()
    every i := 1 to 7 do {
        lot := ?lottery
        insert(chosen, lot)
        delete(lottery, lot)
    }
    every i := !chosen do write(i)
end
Julia

Julia

Julia is a newish language specialized in high-performance computing. There are obvious influences from Python and Scala, and less obvious ones from Lisp (Julia is object-oriented, for example, but its object-orientedness is much more in the vein of Common Lisp than C++ or Ruby.)

# Drawing the lottery line in Julia

lottery = Int64[]
while length(lottery) < 7
    lot = rand(1:40)
    if !in(lot, lottery)
        push!(lottery, lot)
    end
end
println(join(sort(lottery), ", "))
LISP

LISP

Here each chosen number goes to a list. When drawing the lots again, we just test whether the number already is a member of the list.

;;; Drawing the lottery line in (Common) Lisp

(defun lottery ()
  (do ((chosen nil)) ((= (length chosen) 7) (sort chosen #'<))
    (let ((lot (random 40)))
      (if (not (member lot chosen)) (push lot chosen)))))
Pascal

Pascal

This piece of code follows the “BASIC strategy”.

{ Drawing the lottery line in Pascal }

program DrawLottery;

var
    lottery : array[1..40] of boolean;
    lot, chosen, i : integer;

begin
    randomize;
    chosen := 0;
    for i := 1 to 40 do
        lottery[i] := false;
    while chosen <= 7 do begin
        lot := random(38) + 1;
        if lottery[lot] = false then begin
            lottery[lot] := true;
            chosen := chosen + 1
        end
    end;
    for i := 1 to 40 do begin
        if lottery[i] = true then write(i : 3)
    end;
    writeln
end.
Perl

Perl

Though Perl has lists like Lisp and Python, there seems to be no easy way of checking the existence of an element in the list (Lisp has the “member” function, Python the “in” operator); so this sample uses the same strategy as the BASIC sample above.

The syntactic tricks in this sample are partly intentional. For instance, there is no need for the “if” and “unless” clauses to be tailing the statements they control, and more often than not it would be best if they didn’t, but used that way you save an extra brace pair.

# Drawing the lottery line in Perl

while ($chosen < 7) {
    $lot = int(rand(36)) + 1;
    $lottery[$lot] = 1, $chosen ++ unless ($lottery[$lot]);
}

for ($i = 1; $i < 40; $i ++) {
    print $i + 1 . " " if ($lottery[$i]);
}
print "\n";
Python

Python

Since Python implemented sets, this exercise became a lot easier: there’s no need to check whether a drawn lottery number is already used, since elements in sets are unique by definition.

# Drawing the lottery line in Python

from random import randint

lottery = set()
while len(lottery) < 7:
    lottery.add(randint(1, 40))
print(', '.join([str(num) for num in sorted(lottery)]))
REXX

REXX

Standard REXX does not have array variables. The so-called “stem variables” can sometimes do the trick, as in here, but even though “lottery.1” is pretty much equivalent to “lottery[1]” in some other programming languages (as in Pascal or C), there’s a catch: it is no error for the “index” (which is not really an index in REXX) to be an arbitrary name, such as an erroneously uninitialized variable.

/* Drawing the lottery line in REXX */

lottery.0 = 0
do until lottery.0 = 7
    lot = random(36) + 1
    if lottery.lot = 0 then do
        lottery.lot = 1
        lottery.0 = lottery.0 + 1
    end
end

do i = 1 to 40
    if lottery.i = 1 then
        say i
end
Scheme

Scheme

This is very close to identical to the code in (Common) Lisp, the only differences being (a) instead of nil, the empty list is always written () in Scheme, and (b) there no handy push macro with which to use lists as stacks; instead it is necessary to use append.

;;; Drawing the lottery line in Scheme

(define lottery ()
  (do ((chosen ())) ((= (length chosen) 7) (sort chosen <))
    (let ((lot (random 40)))
      (if (not (member lot chosen)) (append '(lot) chosen)))))
Tcl

Tcl

Tcl is a silly language. You can do almost anything with it, but for a non-adherent it sure requires some keen studying with the manual. Shell-like syntax makes some simple things―like setting a variable to a nonliteral value―needlessly complicated.

# Drawing the lottery line in TCL

package require math

while { [ llength $chosen ] < 7 } {
    set lot [ ::math::random 1 40 ]
    if { [ lsearch chosen $lot ] == -1 } { lappend chosen $lot }
}

foreach i $chosen { puts $i }