Created
November 23, 2013 12:39
-
-
Save richhollis/7614183 to your computer and use it in GitHub Desktop.
Clojure Week 3 Homework - Poker hand
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(defn deck [] | |
(for [suit [:clubs :hearts :spades :diamonds] | |
pip (range 2 15)] | |
{:suit suit | |
:pip pip})) | |
(defn hand-frequencies [hand] | |
(frequencies (map :pip (hand)))) | |
(defn n-of-a-kind? | |
[n hand] | |
(some #{n} (vals (hand-frequencies hand)))) | |
(defn full-house? [hand] | |
(and (n-of-a-kind? 2 hand) (n-of-a-kind? 3 hand))) | |
(defn hand [] | |
(take 5 (shuffle (deck)))) | |
(full-house? hand) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Well done! This is good stuff.
There's one thing here that's a little confusing though, which you may not have noticed. Here's a question for you: What should the argument to
full-house?
be? A list of 5 cards? Or a function that deals them?Either is legal. There's nothing wrong with supplying a function as an argument. (In fact, it can lead to serious Function Programming-fu.) But for this exercise, I think
full-house?
should take 5 cards and return true or false, so we need to change things.I'd lean strongly towards naming values with nouns, functions with verbs. So let's change your last few lines to:
If you do that, you'll get this error:
What does that mean? If we read it from right to left, it's saying, "On line 8, in the hand-frequencies function, I was expecting a function (something that implements IFn), but got a LazySeq (one of the list classes) instead."
If we look on line 8, yup, you're calling
(hand)
. What you've been doing is passing the function-that-does-dealing down through the chain, and only invoking it when you get tohand-frequencies
. I think what you want to do is deal those cards right at the top, then pass the 5 cards down the chain. So another quick change:And it will work again. We've now got this code:
hand
means 5 cards.deal-hand
is a function that creates a new list of 5 cards. Variable names and functions are named more clearly.So...let's ask a question of this system. And it's the one you raised: How do you repeat this 30 times looking for a full house? Well, let's look at one of those FP-fu functions that takes a function as an argument.
repeatedly
takes a function and calls it over-and-over again to make a list of its results. We can say:And get 30 hands. Then we could just run
full-house?
over those 30 with map:That's us done.
Except...
If you run that I'll bet you get a list of 30
nil
s, right? That's not the code's fault. That's poker's fault. The odds of a full house are 693/1, so 30 hands isn't enough dealing. Maybe we should ask a different question. "How many hands do we need to deal before we get a full house?" I'm going to give you one possible approach, which for now I leave you to decipher. Hopefully we can break down in detail next week: