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