Quantcast
Channel: dave yarwood
Viewing all articles
Browse latest Browse all 64

4Clojure Problem #178

$
0
0

On a whim today, I decided to take on 4Clojure Problem #178, which gives you as input a collection of 5 strings like "HA" (ace of hearts) or "D2" (2 of diamonds), representing a poker hand, and asks you to write a function that determines the best hand you could play with those cards (straight flush, full house, etc.)

I had already done Problem #128, which asks for a function that will take a string like "HA" or "D2" and return a map with the suit and rank (from 0-12, where 0-8 are 2-10, 9 is Jack, 10 is Queen, 11 is King and 12 is Ace), for example {:suit :heart, :rank 12} for the ace of hearts. So I simply reused my solution for that problem within a let binding.

I should note that this solution is presented here as a single function only because that’s the way you have to write it in order for 4Clojure to test it. Otherwise, I probably would have written each part of the let binding as a def or defn at the top level. Nonetheless, I think this is a good example of how easy it is to write concise, readable code in Clojure. Enjoy!

(fn best-hand[card-strings](let [card-parser(fn [[sr]](let [suit({\S:spade, \H:heart, 
                                   \D:diamond, \C:club}s)rank(if (> (Character/digitr10)-1)(- (Character/digitr10)2)({\T8, \J9, 
                                     \Q10, \K11, \A12}r))]{:suitsuit, :rankrank}))cards(map card-parsercard-strings)suits(map :suitcards)ranks(map :rankcards)flush?(if (= 1(count (set suits))):flushnil)straight?(let [aces-high(sort ranks)aces-low(sort (replace {12-1}ranks))](if (or(= aces-high(take 5(iterate inc (first aces-high))))(= aces-low(take 5(iterate inc (first aces-low))))):straightnil))straight-flush?(if (and flush?straight?):straight-flushnil)pair?(if (some (fn [[rnum]](>= num2))(frequenciesranks)):pairnil)three-of-a-kind?(if (some (fn [[rnum]](>= num3))(frequenciesranks)):three-of-a-kindnil)four-of-a-kind?(if (some (fn [[rnum]](= num4))(frequenciesranks)):four-of-a-kindnil)two-pair?(if (or (some (fn [[rnum]](>= num4))(frequenciesranks))(= 2(count (filter (fn [[rnum]](>= num2))(frequenciesranks))))):two-pairnil)full-house?(if (and(some (fn [[rnum]](= num3))(frequenciesranks))(some (fn [[rnum]](= num2))(frequenciesranks))):full-housenil)possible-hands(remove nil? [straight-flush?four-of-a-kind?full-house?flush?straight?three-of-a-kind?two-pair?pair?])](if-not (empty?possible-hands)(first possible-hands):high-card)))

I’d be curious to see your own solutions to this problem, either in Clojure or any other language!


Viewing all articles
Browse latest Browse all 64

Trending Articles