packages feed

language-Modula2-0.1: examples/Modula-2_Libraries/andrea-m2/lib/generic/shuffle.mod

IMPLEMENTATION MODULE Shuffle;

(* See the definition module for details *)

(* V1.1, John Andrea, Jun.22/93 -add Copy and Duplicate *)
(* V1.0, John Andrea, Apr.5/92 *)
(* This code may be freely used and distributed, it may not be sold *)

IMPORT LargeSets;
FROM Storage IMPORT ALLOCATE;
FROM Randomly IMPORT Choose_1_To_N;

TYPE
    Deck = POINTER TO RECORD
             min, max :CARDINAL;
             size     :CARDINAL;
             n_left   :CARDINAL;
             set      :LargeSets.LargeSet;
           END;

(* ------------------------------------------- *)
PROCEDURE Create( VAR d :Deck; min, max :CARDINAL );
VAR
  i :CARDINAL;
BEGIN
  NEW( d );

  IF min > max THEN
    i   := min;
    min := max;
    max := i;
  END;

  d^.min  := min;
  d^.max  := max;
  d^.size := max - min + 1;

  LargeSets.Build( d^.set, min, max );

  Reset( d );
END Create;

(* ------------------------------------------- *)
PROCEDURE Reset( d :Deck );
BEGIN
  d^.n_left := d^.size;
  LargeSets.Fill( d^.set );
END Reset;

(* ------------------------------------------- *)
PROCEDURE Next( d :Deck ) :CARDINAL;
VAR
  i, n, count :CARDINAL;
BEGIN
 IF d^.n_left = 0 THEN Reset( d ); END;

 n := Choose_1_To_N( d^.n_left );

 (* find the n'th non-zero number in the list *)
 i     := d^.min;
 count := 0;
 WHILE count # n DO
   IF LargeSets.In( d^.set, i ) THEN count := count + 1 END;
   i := i + 1;
 END;
 i := i - 1;

 LargeSets.Excl( d^.set, i );   (* make this number un-available *)
 d^.n_left := d^.n_left - 1;    (* now the list is smaller by one *)

 RETURN i;
END Next;

(* ------------------------------------------- *)
PROCEDURE Copy( d, e :Deck );
BEGIN
  IF ( d^.min = e^.min ) & ( d^.max = e^.max ) THEN
    LargeSets.Copy( d^.set, e^.set );
    e^.n_left := d^.n_left;
  END;
END Copy;

(* ------------------------------------------- *)
PROCEDURE Duplicate( d :Deck; VAR e :Deck );
BEGIN
  Create( e, d^.min, d^.max );
  Copy( d, e );
END Duplicate;

BEGIN
END Shuffle.