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,:rank12} 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!

(fnbest-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(mapcard-parsercard-strings)suits(map:suitcards)ranks(map:rankcards)flush?(if(=1(count(setsuits))):flushnil)straight?(let[aces-high(sortranks)aces-low(sort(replace{12-1}ranks))](if(or(=aces-high(take5(iterateinc(firstaces-high))))(=aces-low(take5(iterateinc(firstaces-low))))):straightnil))straight-flush?(if(andflush?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(removenil?[straight-flush?four-of-a-kind?full-house?flush?straight?three-of-a-kind?two-pair?pair?])](if-not(empty?possible-hands)(firstpossible-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