1 #!/usr/bin/perl
    2
    3 use strict;
    4 use warnings;
    5
    6 my $usage = "$0 --switch=[true|false] --iterations=[num]";
    7
    8 #
    9 # grab command line
   10 #
   11 my $switch = $ARGV[0];
   12 my $iterations = $ARGV[1];
   13
   14 #
   15 # parse and validate command line
   16 #
   17 my $numArgs = $#ARGV + 1;
   18 if( $numArgs != 2 ) {
   19    die "Invalid command line. Usage: $usage\n";
   20 }
   21 my( @switchAry ) = split /=/, $switch;
   22 if( $switchAry[0] ne '--switch' ||
   23     ( $switchAry[1] ne 'true' && $switchAry[1] ne 'false' ) ) {
   24    die "Invalid switch arg. Usage: $usage\n";
   25 }
   26 my $switchDoors = $switchAry[1] eq 'true' ? 1 : 0;
   27 my( @iterationsAry ) = split /=/, $iterations;
   28 if( $iterationsAry[0] ne '--iterations' || $iterationsAry[1] !~ /^\d+$/ ) {
   29    die "Invalid iterations arg. Usage: $usage\n";
   30 }
   31 my $numTimesToPlay = $iterationsAry[1] + 0;
   32
   33 #
   34 # Run the simulation $numTimesToPlay times
   35 #
   36 my $numWins = runSimulation( $numTimesToPlay, $switchDoors );
   37
   38 #
   39 # Display the results
   40 #
   41 print '' .
   42       ( $switchDoors ? '' : 'NOT ' ) .
   43       'Switching... Won ' . $numWins . " out of $numTimesToPlay Times!\n";
   44 exit;
   45
   46 ########################################################################
   47
   48 sub runSimulation {
   49    my $numSimulations = shift;
   50    my $switchDoors = shift;
   51    my $numWins = 0;
   52
   53    for( my $i = 0 ; $i < $numSimulations ; $i++ ) {
   54       my $initialChoice = getRandomNum( 1, 3 );
   55       my $correctDoor = getRandomNum( 1, 3 );
   56       if( playGame( $initialChoice, $switchDoors, $correctDoor ) ) {
   57          $numWins++;
   58       }
   59    }
   60    return $numWins;
   61 }
   62
   63 #
   64 # Return true if you won the new car
   65 #
   66 sub playGame {
   67    my $initialChoice = shift;
   68    my $switchDoors = shift;
   69    my $correctDoor = shift;
   70    my $finalChoice;
   71
   72    my $choiceDisplayedAsWrong = getChoiceDisplayedAsWrong( $initialChoice,
   73                                                            $correctDoor );
   74
   75    if( $switchDoors ) {
   76       $finalChoice = getLastRemainingChoice( $initialChoice, $choiceDisplayedAsWrong );
   77    }
   78    else {
   79       $finalChoice = $initialChoice;
   80    }
   81    return ( $finalChoice == $correctDoor );
   82 }
   83
   84 #
   85 # Get the door number of the door that the game show
   86 # host opens to show that it's not the correct door.
   87 # I'm sure there are much more efficient ways to do this...
   88 #
   89 sub getChoiceDisplayedAsWrong {
   90    my $initialChoice = shift;
   91    my $correctDoor = shift;
   92
   93    my $randomNumber = getRandomNum( 1, 2 );
   94    if( $initialChoice == $correctDoor ) {
   95       #
   96       # The game show host has to choose between 2 doors,
   97       # so if $randomNumber is 1, then he'll choose the 1st
   98       # door, and if $randomNumber is 2, then he'll choose
   99       # the 2nd door.
  100       #
  101       for( my $i = 1 ; $i <= 3 ; $i++ ) {
  102          if( $initialChoice == $i ) {
  103             next;
  104          }
  105          # random number == 1, return the 1st incorrect door number
  106          if( $randomNumber == 1 ) {
  107             return $i;
  108          }
  109          # random number must be 2, return the 2nd incorrect door number
  110          return $i;
  111       }
  112       print 'shouldnt get here... LINE: ' . __LINE__ . "\n";
  113    }
  114    else {
  115       #
  116       # $initialChoice was not the correct door, so the host
  117       # only has one choice of which door to open.
  118       #
  119       for( my $i = 1 ; $i <= 3 ; $i++ ) {
  120          if( $i == $initialChoice || $i == $correctDoor ) {
  121             next;
  122          }
  123          return $i;
  124       }
  125       print 'shouldnt get here... LINE: ' . __LINE__ . "\n";
  126    }
  127    print 'shouldnt get here... LINE: ' . __LINE__ . "\n";
  128 }
  129
  130 #
  131 # Get the door number of the door that was not your first
  132 # selection and was also not the one that the game show
  133 # host opened to taunt you.
  134 #
  135 sub getLastRemainingChoice {
  136    my $initialChoice = shift;
  137    my $choiceDisplayedAsWrong = shift;
  138    for( my $i = 1 ; $i <= 3 ; $i++ ) {
  139       if( $i == $initialChoice || $i == $choiceDisplayedAsWrong ) {
  140          next;
  141       }
  142       return $i;
  143    }
  144    print 'shouldnt get here... LINE: ' . __LINE__ . "\n";
  145 }
  146
  147 sub getRandomNum {
  148    my $min = shift;
  149    my $max = shift;
  150    return int(rand($max)) + $min;
  151 }
  152
  153 1;