Probability of winning a game of Lotto

Skapad 3 år sedan, skriven i Perl, med 257 visningar.
URL http://kod.perl.se/view/653e38ce Bädda in
Ladda hem koden eller visa koden i råformatVisa bredare version
  1. #! /usr/bin/perl -w
  2. #
  3. ##### Program description
  4. #
  5. # Title: lotto.pl
  6. #
  7. # Author(s): Mattias Ohlsson
  8. #
  9. # Description:
  10. #    This program will estimate the probability of winning a game of
  11. #    Lotto. The method used here is a Monte Carlo simulation of the
  12. #    lottery. This means that 7 numbers are randomly generated from the
  13. #    interval [1,35] without doublets and then 7+4 winner
  14. #    numbers are randomly generated from the same interval. According to
  15. #    the rules of Lotto the following situations will result in a winnings:
  16. #
  17. #    4   correct numbers
  18. #    5   correct numbers
  19. #    6   correct numbers
  20. #    6+1 correct numbers
  21. #    7   correct numbers
  22. #
  23. #
  24. # List of subroutines:
  25. #
  26. #    iRnd: This function takes two integers, i1 and i2, as
  27. #       arguments and returns random integer in the interval [i1, i2].
  28. #
  29. #    GetNumbers: This function returns a vector of random numbers
  30. #       in the interval [1,35], with all numbers different from each other.
  31. #       The length of this vector is given as an argument and must be <= 35.
  32. #
  33. # Procedure:
  34. #    1. Get the number of Monte Carlo runs to perform from STDIN.
  35. #    2. Start the main Monte Carlo loop
  36. #       2a. Get an array of 7 numbers (my Lotto row) and one with 11 numbers
  37. #           (the "winner numbers").
  38. #       2b. Make a loop over all the 7 numbers and check if each of them are
  39. #           present in the array of 7+4 winner numbers. Add hits to the two variables
  40. #           $Corr7 and $Corr4, representing the real hits or
  41. #           "tilläggsnummer" hits.
  42. #       2c. Check the possible combinations for a winnings and record such an
  43. #           event. Also record the different combinations.
  44. #    3. Print a summary of the results found.
  45. #
  46. # Usage:
  47. #        ./lotto.pl [number of MC runs]
  48. #
  49. #
  50. ##################################
  51.  
  52. use strict;
  53. use IO::Handle;
  54. use feature ':5.10';
  55. autoflush STDOUT 1;
  56.  
  57. #### Main program ####
  58. my(%Stat);
  59.  
  60. # Get the number of Monte Carlo runs
  61. my $Runs = 50000;
  62. if ( scalar @ARGV >= 1 && $ARGV[0] =~ /^d+$/ ) {
  63.    $Runs = $ARGV[0];
  64. }
  65.  
  66. # Zero the number of winnings variable
  67. my $Nwin = 0;
  68.  
  69. # Main Monte Carlo loop
  70. for ( my $i = 1; $i <= $Runs; $i++ ) {
  71.  
  72.    # "Fill in the Lotto sheet"
  73.    my @Student = GetNumbers(7);
  74.  
  75.    # "Watch the Lotto on TV at Saturday evening"
  76.    my @Teacher = GetNumbers(11);
  77.  
  78.    # Divide into 7 + 4 numbers
  79.    my @Teacher7 = splice @Teacher, 0, 7;
  80.    my @Teacher4 = @Teacher;
  81.  
  82.    # Check the Student for winnings
  83.    my $Corr7 = 0;
  84.    my $Corr4 = 0;
  85.    foreach my $num (@Student) {
  86.       if ($num ~~ @Teacher7) {
  87.          $Corr7++;
  88.       } elsif ($num ~~ @Teacher4) {
  89.          $Corr4++;
  90.       }
  91.    }
  92.  
  93.    # Determine if it was a win!
  94.    if ( $Corr7 >= 4 || ($Corr7 == 6 && $Corr4 > 0) ) {
  95.       $Nwin++;
  96.    }
  97.  
  98.    # Collect statistics
  99.    $Stat{"$Corr7-$Corr4"}++;
  100.  
  101.    # Some nice online printing during the MC simulation
  102.    printf "Probability of winnings: %5.2f %%  game $i out of $Runsr",  
  103.    100 * ($Nwin / $i) if($i % 10000 == 0);
  104.  
  105. }
  106.  
  107. # Print the summary
  108. print "nn";
  109. print "Summary after $Runs simulated games of lotto:nn";
  110.  
  111. my $mp = 0;
  112. my $idx = '';
  113. for ( my $i = 0; $i <= 7; $i++ ) {
  114.    for ( my $j = 0; $j <= 4; $j++ ) {
  115.       if ( defined $Stat{"$i-$j"} ) {
  116.          printf "Got $i + $j correct numbers in %7d gamesn", $Stat{"$i-$j"};
  117.          if ( $Stat{"$i-$j"} > $mp ) {
  118.             $mp = $Stat{"$i-$j"};
  119.             $idx = "$i + $j";
  120.          }
  121.       }
  122.    }
  123. }
  124. printf "nThe most probable outcome is: $idx correct numbers occuring $mp timesn";
  125. printf "nProbability of winnings: %5.2f %%n", 100 * ($Nwin / $Runs);
  126.  
  127.  
  128. ## Subroutines follows here
  129.  
  130. sub iRnd {
  131.    my ($i1, $i2) = @_;
  132.    
  133.    # A random integer between i1 and i2
  134.    return int( rand($i2 - $i1 + 1) ) + $i1;
  135.    
  136. } # End of Rnd
  137.  
  138.  
  139. sub GetNumbers {
  140.    
  141.    # How many numbers to generate, given as an argument
  142.    my ($HowMany) = @_;
  143.    
  144.    # Check that it is <= 35
  145.    if ( $HowMany > 35 ) {
  146.       print "Error in GetNumbers: Lenght of random array must be <= 35n";
  147.       exit(-1);
  148.    }
  149.    
  150.    my @Tmp;
  151.    foreach my $i (1..35) {
  152.       $Tmp[$i] = $i;
  153.    }
  154.    
  155.    my $len = 35;
  156.    my @Numbers;
  157.    for ( my $i = 0; $i < $HowMany; $i++ ) {
  158.      
  159.       # Get random index
  160.       my $idx = iRnd(1, $len);
  161.      
  162.       # Add to the Numbers array
  163.       my $num = $Tmp[$idx];
  164.       push @Numbers, $num;
  165.      
  166.       # Rearrange the Tmp array
  167.       my $dum = $Tmp[$len];
  168.       $Tmp[$len] = $Tmp[$idx];
  169.       $Tmp[$idx] = $dum;
  170.       $len -= 1;
  171.  
  172.    }
  173.    
  174.    # Return the array of random numbers
  175.    return @Numbers;
  176.    
  177. } # End of GetNumbers
  178.  

Svara på "Probability of winning a game of Lotto"

Här kan du skriva ett svar till kodsnutten ovan