Lab 8 Instructions CMPU 145, Spring 2019 For this lab, the probability helper file (prob-helper.scm) contains the standard "asmt-helper.scm" functions (HEADER, PROBLEM, TESTER) plus functions that we already used/demonstrated. These include N-CHOOSE-K, CHOOSE-K-FROM, GEN-AND-TEST, GEN-POKER-HAND, RANK) that you will need for this lab. It also defines the global variable *DECK* containing the numbers from 0 to 51, representing cards in a deck. Problem 0 --------- This problem is already completed; just uncomment the code as you read each of the parts. Be sure to understand this code (i.e. ask questions) as a preparation for the next problem. We will consider 5 card hands of poker. In poker, a "full house" is a five-card hand that contains three cards of one rank and two cards of another rank. For example, a hand containing three kings and two sixes is a full house, as is a hand containing three fours and two jacks. The suit of the cards in a full house do not matter. Part A: Calculate the probability of a hand of five cards being a full house, using standard multiplication, division, and the number of combinations (N-CHOOSE-K). Save the result in the global variable *prob-full-house* and print it with TESTER. Part B: Experimentally verify the probability of getting a full house using the GEN-AND-TEST and GEN-POKER-HAND. You should generate a new function, called HAS-FULL-HOUSE?, that takes a list of five cards - simply numbers from 0 to 51 - and determines whether that list of cards contains a full house. We use an expression such as (sort (map rank cards) <=) in order to generate a sorted list of the ranks of a given list of cards. For a full house, the pattern of such a list should be either (X X X Y Y) or (X X Y Y Y), depending upon whether the rank of the triple is lower or higher than the rank of the pair. Consider the following interactions: > (define *cards* (list 8 10 34 21 23)) > (map card->string *cards*) '("9 of Clubs" "J of Clubs" "9 of Hearts" "9 of Diamonds" "J of Diamonds") > (sort (map rank *cards*) <=) '(9 9 9 11 11) > (has-full-house? *cards*) #t > (define *cards* (list 8 10 35 21 23)) > (sort (map rank *cards*) <=) '(9 9 10 11 11) > (has-full-house? *cards*) #f After you define this function, compare the result obtained by evaluating an expression such as (gen-and-test 1000 gen-poker-hand has-full-house?) How big does the first input of GEN-AND-TEST have to be before your answer gets close to the "real answer"? Problem 1 --------- A five-card hand in poker is called a "straight" if the ranks of the cards can be put into any of the following sequences: A, 2, 3, 4, 5 2, 3, 4, 5, 6 3, 4, 5, 6, 7 4, 5, 6, 7, 8 5, 6, 7, 8, 9 6, 7, 8, 9, 10 7, 8, 9, 10, J 8, 9, 10, J, Q 9, 10, J, Q, K 10, J, Q, K, A Here, too, suits do not matter when determining whether a hand is a straight. Part A: Define a variable, called *NUM-STRAIGHTS*, whose value is the number of distinct 5-card hands that are straights. Define a variable, called *PROB-STRAIGHT*, whose value is the probability of getting dealt a 5-card straight from a standard deck of 52 cards. Part B: Define a function, called HAS-STRAIGHT?, that returns #t if a given list of "cards" (i.e., numbers from 0 to 51, inclusive) contains a "straight". Here are some examples: ("Kangaroo straights" do not count!) > (sort (map rank (list 19 31 7 9 47)) <=) (6 7 8 9 10) > (has-straight? (list 19 31 7 9 47)) #t > (sort (map rank (list 19 32 7 9 47)) <=) (7 7 8 9 10) > (has-straight? (list 19 32 7 9 47)) #f > (sort (map rank (list 1 3 5 7 9)) <=) (2 4 6 8 10) > (has-straight? (list 1 3 5 7 9)) #f Hint: Make your function simple! How can you transform the sorted list of ranks for any straight into one of two lists? After your function is working, evaluate an expression such as: (gen-and-test 1000 gen-poker-hand has-straight?) The answer should come out to be about the same as the probability you calculated in Part A. Problem 2 --------- Recall that in the Monty Hall problem, a contestant is given a choice among three doors, behind one of which is a prize -- a car -- and behind two of which are goats, but are not even goats - they are llamas! After choosing a door, the host opens one of the two doors the contestant did not select, revealing a goat. The player may then stick with her original choice or switch to the other unopened door. In class, we saw that switching is the better strategy, changing the probability of selecting the car from 1/3 to 2/3. Many people find this hard to believe, Ms. vos Savant made clear. We will run a simulation to convince the unbelievers! Continueue to reuse GEN-AND-TEST, but now instead of a hand of cards, an instance will be a list containing the choices of doors that define the decisions made in the game, e.g., '(1 ;; The car is behind Door 1 2 ;; The player's first choice is Door 2 3 ;; The host reveals a goat behind Door 3 1) ;; The player's final choice is to switch to Door 1 In this instance, the player wins the car! '(2 ;; The car is behind Door 2 3 ;; The player's first choice is Door 2 1 ;; The host reveals a goat behind Door 1 3) ;; The player's choice is to keep the original choice of Door 3 In this instance, the player loses the car -- but wins a goat! Write functions GEN-GAME-KEEP and GEN-GAME-CHANGE that generate instances where the player keeps her original choice or changes to the other unopened door, respectively. While there are several ways to approach this problem, one way is: - Define a global variable *DOORS* with the door numbers - Write a function GEN-GAME that takes an input STRATEGY, which is the name of a function that makes the player's final choice given the first-choice and the revealed-goat. You then need a (very short) function to choose to keep the original choice (keep-original or keep-door maybe?) and a *slightly* longer one to change to the other door. (change-door maybe?) - Consider how you can use CHOOSE-ONE-FROM and REMOVE to randomly choose the appropriate doors. Write a function WON-GAME? that takes a game instance as input and checks if the player won the car. Run simulations for both strategies with GEN-AND-TEST. Do you get the right ratio of wins (1/3 for keeping; 2/3 for switching)? If not, there may be an error with the code... or the game show! (probably, it is an error with the code) An example: (tester '(gen-and-test 1000 gen-game-keep win-car?)) ---- When you are done, ask me or one of the coaches to come over and check your work. Then submit electronically, using the submit script. . . submit145 lab