#!perl
#
# $Id: lotto6,v 1.3 1991/12/09 22:36:48 wengland Exp $
#
# $Log: lotto6,v $
# Revision 1.3	1991/12/09  22:36:48  wengland
# Modified terminology to match WSL terms and descriptions.
# Added better statistics collection and a standard deviation
# of percent selected to provied usefull distribution information.
#
# Revision 1.2	1991/12/07  06:36:30  wengland
# Set it up to print out initial auto randomization key.
# Print date and moved cost information around.
#
#
eval "exec perl -S $0 $*"
	if $running_under_some_shell;

## Random Washington State Loto pannel drawing program.
##

##
 #  (c) Copyright 1991, Stephen Software Systems, Inc.
 #
 #  This software is furnished under the terms of the GNU
 #  public license and is freely distributable.
 #
 #  Using this software will in no way change your odds of
 #  winning the Washington State Loto or any other game
 #  of chance.
 #
 #  This software is supplied FREE of charge and comes with
 #  no warrenties expressed or implied.  The author is not
 #  responsible for any damages, monetary or otherwise.
 #
 #		 USE AT YOUR OWN RISK.
##

 ## The following number is system dependant.  You must change it
  # to match the bit size of your systems random number generator.
  #
  # (Actually it only needs to be on the same scale  a minor error
  #   will not make a differance.)
  #
  #   8 bit, 2^7 -1  or 127
  #  16 bit, 2^15 -1 or 32,767
  #  32 bit, 2^31 -1 or 2,147,483,647
  #
 $rand_mod = 2147483647;
  ##
   # IT should be noted however that a random number generator
   # with a Modulus of less than 14M will result in a quite
   # non random selection.  The only way to fix this is by
   # building your perl package with a 'good' random number
   # generator built into it.
   #
   # However your odds are still so low that you really
   # don't need to worry about it.  :-)
  ##

## Parameters.
 # -k Random number key to start with. (Pick your favorite lucky number.
 #     or the prior output of this program labled Next Key:  )
 #    (default, something really wierd and not predictable)
 # -g number of groups to select. (default 1)
 # -n number of numbers per group. (default 10.)
 # -p number of pannels per group. (default 10, one $5 pannel.)
 #

require "getopts.pl";
    if (!&Getopts('k:g:p:n:')){
     print "\nThe following options are available:\n\n".
  "    -k Random number key to start with. (Pick your favorite lucky number.\n".
  "	   or the prior output of this program labled Next Key:  )\n".
  "	  (default, something really wierd and not too predictable)\n".
  "    -g number of groups to select. (default 1)\n".
  "    -n number of numbers per group. (default 10.)\n".
  "    -p number of pannels per group. (default 10, one $5 pannel.)\n";
	exit;
    }

    print `date`;

    if ($opt_k){
	print "User defined key=$opt_k\n\n";
	srand($opt_k);
    } else {
	## Pick a fairly random seed based very on
	 # the time of day.
	&randomize();
    }

    if ($opt_g){
    }else{
       $opt_g = 1;
    }
    if ($opt_p){
    }else{
       $opt_p = 10;
    }
    if ($opt_n){
    }else{
       $opt_n = 10;
    }

   printf("%s Groups, %s Numbers per Group, %s Pannels per Group\n",
		$opt_g, $opt_n, $opt_p );

   printf( "Cost per group: \$%.2f. Cost of all groups: \$%.2f \n\n",
       $opt_p * .5, $opt_p * .5 * $opt_g);

## This program uses a group method of selecting
 # lotto pannel.  First 10 numbers are selected
 # from the 40 available,  then  5 combinations of
 # the 10 numbers are chosen.
 #
 # The idea is that it is a lot more likely to pick
 # 10 possible numbers than to pick only 6 and
 # chosing combinations of the 10 gives an illusion
 # that you are somehow more likely to win.
 #
 # The odds are unchanged of course and your chances
 # of winning are still 14M to one.
 #

    ## Number of members in group must be greator than
     # 6 and less than 50.
     #
    if ($opt_n <7 || $opt_n > 49){
	print STDERR
	"Number of members in group must be greator than 6 and less than 50.\n";
       exit 1;
   }

    ## Initialize.
     #
    @selection=split(/ /,"01 02 03 04 05 06 07 08 09 10 ".
			"11 12 13 14 15 16 17 18 19 20 ".
			"21 22 23 24 25 26 27 28 29 30 ".
			"31 32 33 34 35 36 37 38 39 40 ".
			"41 42 43 44 45 46 47 48 49" );

    %Group=();
    while( (@ttl_Groups=keys(%Group)) < $opt_g ){
	## Draw one number at random and put it in line of group.
	 #
	@r_group=();
	while( @selection ){
	    push (@r_group, splice(@selection, rand @selection, 1 ));
	}
	@selection = @r_group;
	@r_group = ();

	$ctr = $opt_n;	# Total numbers in group.
	while( $ctr--){
	    $r_group[$ctr] = $selection[$ctr];
	}

	$group =  join(" ", sort @r_group);

       ## Check for duplicates.
	#
	 if( defined $Group{$group} ){
		printf("Dup Group: %s \n\n", $group);
		next;
	    }
       $Group{$group} = join(" ", @r_group);
    }

     ## Print out all groups.
      #
     foreach $group ( sort(keys %Group )){
	&do_a_group( split(/ /, $Group{$group}) );
    }

    print "Next Key: ", int(rand($rand_mod)), "\n";

##
 #
##
sub do_a_group{
    local(@r_group)= @_;
    local($ctr,$ctr1);
    local(%Group_stats,@stat_group)=();

    printf("Group: %s \n", join(" ", sort @r_group));

    foreach $group_member( @r_group){
       $Group_stats{$group_member} = 0;
   }


    ## Pick a pannel.
     #
    %Pannel  = ();
    @Dup_Pannel=();
    while( (@ttl_Pannel=keys(%Pannel)) < $opt_p ){

	@r_pannel =();
	while( @r_group ){
	    push (@r_pannel, splice(@r_group, rand @r_group, 1 ));
	}
	@r_group = @r_pannel;
	@r_pannel = ();

	$ctr = 6;  # Total numbers in pannel.
	while( $ctr--){
	    $r_pannel[$ctr] = $r_group[$ctr];
	}

       $pannel =  join(" ", sort @r_pannel);

       ## Check for duplicates.
	#
	 if( defined $Pannel{$pannel} ){
		push(@Dup_Pannel, $pannel);
		next;
	    }

       ## Collect group statitistic.
	#
       foreach $group_member( @r_pannel ){
	   $Group_stats{$group_member}++;
       }

       $Pannel{$pannel} = 0;
    }

    ##	Print calculate group statistics.
     #
    foreach $group_member( sort(keys %Group_stats )){
       push( @stat_group,
	   sprintf("%2s", int($Group_stats{$group_member}/($opt_p*6)*100) ));
    }

    ## Calculate  and print  s.
     #
     # s =   E(x-x')^2
     #	   ---- n-1 ----
     $xx = 0;
     foreach $group_stat( @stat_group){
	 $xx += $group_stat;
     }
     $xx /= @stat_group;  # Calculate mean.

     $s = 0;
     foreach $group_stat( @stat_group ){
	 local($a, $b) = (0,0);
	 $a = $group_stat - $xx;
	 $s += $a*$a;
     }

     $s /= ($#stat_group);  # Calculate s.

    printf(" Gstt: %s  sd=%.2f\n", join(" ", @stat_group), sqrt($s));


     ## Print all Dup pannel.
      #
     foreach $dup_pannel ( sort @Dup_Pannel ){
	 printf("  Dup: %s \n", $dup_pannel);
    }


     ## Print out all ten pannel.
      #
     foreach $pannel ( sort(keys %Pannel )){
	printf("    P: %s \n", $pannel );
    }
    print "\n";
}
##
 #
##
sub randomize {
   $time = (time % 100)*10000;
   srand($time);
   local($cycle) = int(rand(1000));

   ## We can still do better.
    #
   rand() while $cycle-- > 0;

   srand($cycle = rand($rand_mod));
   printf("Auto randomization key=%s\n\n", $cycle);
}
