Skip to main content

Problem 54 Project Euler Solution with python

Poker hands

In the card game poker, a hand consists of five cards and are ranked, from lowest to highest, in the following way:
  • High Card: Highest value card.
  • One Pair: Two cards of the same value.
  • Two Pairs: Two different pairs.
  • Three of a Kind: Three cards of the same value.
  • Straight: All cards are consecutive values.
  • Flush: All cards of the same suit.
  • Full House: Three of a kind and a pair.
  • Four of a Kind: Four cards of the same value.
  • Straight Flush: All cards are consecutive values of same suit.
  • Royal Flush: Ten, Jack, Queen, King, Ace, in same suit.
The cards are valued in the order:
2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King, Ace.
If two players have the same ranked hands then the rank made up of the highest value wins; for example, a pair of eights beats a pair of fives (see example 1 below). But if two ranks tie, for example, both players have a pair of queens, then highest cards in each hand are compared (see example 4 below); if the highest cards tie then the next highest cards are compared, and so on.
Consider the following five hands dealt to two players:
Hand
Player 1
Player 2
Winner
1
5H 5C 6S 7S KD
Pair of Fives

2C 3S 8S 8D TD
Pair of Eights

Player 2
2
5D 8C 9S JS AC
Highest card Ace

2C 5C 7D 8S QH
Highest card Queen

Player 1
3
2D 9C AS AH AC
Three Aces

3D 6D 7D TD QD
Flush with Diamonds

Player 2
4
4D 6S 9H QH QC
Pair of Queens
Highest card Nine

3D 6D 7H QD QS
Pair of Queens
Highest card Seven

Player 1
5
2H 2D 4C 4D 4S
Full House
With Three Fours

3C 3D 3S 9S 9D
Full House
with Three Threes

Player 1
The file, poker.txt, contains one-thousand random hands dealt to two players. Each line of the file contains ten cards (separated by a single space): the first five are Player 1's cards and the last five are Player 2's cards. You can assume that all hands are valid (no invalid characters or repeated cards), each player's hand is in no specific order, and in each hand there is a clear winner.
How many hands does Player 1 win?


Being new to poker, I had to keep wiki(List of Poker Hands) as reference. Even then I understood the question in a wrong way and had to remodify the program.

I will first explain the question, then the algorithm and then the program itself. This post will be a little bit bigger one, I recommend you to read the whole post so that you will understand the concept perfectly and clearly.

This paragraph has already been explained in the question. But to make you familiar with the question, this paragraph has been written. You can skip if you have already understood the question perfectly. According to the question we will have to give highest priority to the hand having Royal flush and lowest priority to the hand having High Card. It is enough that we will check for one best condition and it is not required to check for all the conditions. In some cases both the players will have a tie, then If they have one pair or two pair or three of a kind or four of a kind or full house, then the rank made up of high value wins. Same example is given in the question. If the tie doesn't break even then, then the highest valued card in the hand wins. The same has been explained about example 4.

Actually algorithm is very simple for this question once you understand the question perfectly. Algorithm is as follows:

1) Open the text file and make a list with the games. This list will have 1000 elements and for each game both the players hands are combined at this stage.
At this stage matrix will look like this:
Games list
 Each column in the above matrix refers to a game, accordingly this matrix will be a row matrix with 1000 elements.

2) Now take each entry in the list and split the list for two players. Matrix format will look like this:
Game list with hands and players divided
Game list with hands and players divided
In the above matrix, column1 is game 1, column 2 is game 2 and so on. Similarly row1 is player 1, row2 is player 2.

3) Now for each player separate the rank of the card and the suite of the card. Matrix will look as follows:
Game list with hands, players, ranks, suites divided
As you can see we have made all the sub divisions required. This will make our work easy.

4) Having organized everything, we will give scores to each and every player to compare the winning. But before we do that, we will make a few priority list so that we can award scores to the players based on the priority list.
Comparision Rating
Royal Flush  10
Straight flush  9
Four of a kind  8
Full house  7
Flush  6
Straight  5
Three of a kind  4
Two pairs  3
One Pair  2
We have not considered the condition for High Card, because this case is only considered when there is a tie between the players for above cases. In high card, the rating is based on value of the cards. The list is as follows:
High Card
Card Rating
A  14
K  13
Q  12
J  11
T  10
9  9
8  8
7  7
6  6
5  5
4  4
3  3
2  2
1  1

5) We know that we will have to check for the highest valued card if there is a tie. But in the cases of pair cases(One pair, two pairs, three of a kind, full house, four of a kind), we will have to check for the rank that makes the highest value(Example 1 given in the question). But in all the other cases we will have to check for the high card in the given hand. So we will create a temporary variable flag and its value will be changed to True when there are pair cases.

6) Now take each and every game, then in a game the player, then now based on the requirement we have have to select either the value of card or suite of the card or both of them. Start checking for the best condition, the given hand can handle. For example if the cards have royal flush then stop checking for all the other conditions and award the player a score of 10. For another example, if the player doesn't satisfy the Royal flush, then start checking for the next best condition. Award the player the value based on the condition satisfied. 

7) If the value of player 1 is greater than player 2 then we will increase the counter by 1, else if the value of player 2 is greater than player 1, nothing has to be done because we are not cared about the player 2 score. But if the value of player 1 and player 2 is equal, then go for step 8.

8) Check if flag is True(i.e cards are pair cases), then check for the rank that makes the highest. Even if there is a tie(Example 4 in question) then go for step 10.

9) If flag is flase(i.e cards are not pair cases), check for the high card and if the value of high card of player 1 is greater than player 2 then increase the counter by 1.

10) If there is a tie after Step 8, then check for the high card  and if high card of player 1 is greater than player 2 then increase the counter by 1.

11) Print the score of player 1 after all the iterations are over.

As you can see, algorithm is very simple. I have implemented the same in the program.

Program

high_card function
This function will return the value of highest valued card in the given hand.
For example: high_card(['5', '6', 'A', 'J']) will give 14

convert_to_lists function
We have discussed about this function in Step 3 of algorithm. This function will convert a given string to lists with the value of cards and the suit of the cards.
For example: convert_to_lists('5S 6S AC JS') will return [['5', '6', 'A', 'J'],['S', 'S', 'C', 'S']]

number_of_pairs functoin
This function will return the number of pairs a given hand has according to the priority list. If there is one pair then 2 is returned, if there are two pairs then 3 is returned. This is according to the priority list.
For example: number_of_pairs(['5','5','7','6','3']) will give 2
number_of_pairs(['5','5','6','6','7']) will give 3
number_of_pairs(['4','3','Q','K','T']) will give 0

three_of_a_kind function
This function will return 4 if there are three cards of same value. Again we are returning 4 in accordance with the priority list that we have created earlier.
For example: three_of_a_kind(['5','5','5','T','Q']) will give 4
three_of_a_kind(['5', '7', 'Q', 'T', 'K']) will return 0

We have used Counter in this function. Using {]Counter(some_list) - Counter(set(some_list)) will return a dictionary with the duplicates and the number of times they have been duplicated. You can see about the Counter from collections module. You can see more about sets from official python.

straight function
 As we know according to the priority list that the rating for straight is 5 and this function will return 5 if all the cards are consecutive values.
For example: straight(['K', 'Q', 'J', 'T', '9']) will give 5
straight(['Q', 'T', '3', '2', '1']) will give 0

flush function
According to the priority list this function will return 6 if all cards are of same suit. 
For example: flush(['S', 'S', 'S', 'S', 'S']) will give 6
flush(['S', 'S', 'S', 'C', 'H']) will give 0

full_house function
According to the priority list this function will return 7 if there is three of a kind and a pair. 
For Example: full_house(['T', 'T', 'T', 'A', 'A']) will give 7
full_house(['A', '9', '8', 'Q', 'T']) will give 0

four_of_a_kind function
According to priority list this function will return 8 if there are four cards of same value. 
For example: four_of_a_kind(['K', 'K', 'K', 'K', '3']) will give 8
four_of_a_kind(['Q', 'K', 'T', '5', '3']) will give 0

straight_flush function
According to priority list this function will return 9 if all cards are consecutive values of same suit.
For Example: straight_flush(['4', '5', '6', '7', '8'],['S', 'S', 'S', 'S', 'S']) will give 9
straight_flush(['3', '9', 'Q', 'T', '2'],['C', 'D', 'H', 'S', 'S']) will give 0

royal_flush function
This function will return 10 if TEN, JACK, QUEEN, KIND, ACE are in same suit.
for Example: royal_flush(['T', 'J', 'Q', 'K', 'A'], ['H', 'H', 'H', 'H', 'H']) will give 10
royal_flush(['3', 'T', '9', '8', 'A'], ['S', 'D', 'H', 'S', 'S']) will give 0

paired_number function
This function will return the rank made up to highest card. Values returned will be according to the High card priority ratings, which we have discusses in the algorithm section.

two_hands = games.strip().split('\n')
This line of code does the job, we have discussed in the algorithm step 1

fh = convert_to_lists(i[:14])
We are using slicing operation to separate first players hand from second player hand. Then we are converting these values to values and suite format which we have discussed earlier.

All the remaining code is according to the algorithm discussed earlier and is easy to understand.

As always you can download the source code from Github Gist pep54.py

Output


Summary

When I first saw the problem, I was confident that I can solve it easily. At the first glance I got the idea to give ratings and few other things. But it took me 2 days to write the code carefully. Even then as I was not able to understand the poker game correctly, I made a silly mistake and had to correct few functions, which added to some more time. But, I am very happy that I have solved a question which is directly related to the real world and that too the execution time was very little. I personally liked this question. I never tried optimizing the code because I was satisfied with the performance of the program.

As always please do correct me if my grammar is wrong or if it is in an ambiguous way.

Comment in the comment box below if you have a doubt or didn't understand anything. I will be glad to help you.

Please do comment in the comment box below if you have found any typo or have a better program or have a different program. Please don't hesitate to comment if you have any suggestion. I will be very happy to view each of them.

You can also contact me.

Thank you. Have a nice day😃!

Popular posts from this blog

Problem 60 Project Euler Solution with python

Prime pair sets The primes 3, 7, 109, and 673, are quite remarkable. By taking any two primes and concatenating them in any order the result will always be prime. For example, taking 7 and 109, both 7109 and 1097 are prime. The sum of these four primes, 792, represents the lowest sum for a set of four primes with this property. Find the lowest sum for a set of five primes for which any two primes concatenate to produce another prime. This problem is j u st a brute force problem. If you have come here because you don't know the limit upto which you will h ave to gener ate the prime numbers t hen go ahe ad and t r y with 10,000 . When I first start ed solving the problem I chose 1 million(beca use most of the problem s on project E uler have this limit ), but it took very long for the computer to fin d the solution. After searching on the internet then I found many people choosing 10, 000 so I have changed my in put f rom 1 million to 10000 and the output was f ast. He...

Add/Embed SVG to Blogger website

In this post I will tell you my method(trick) of adding SVG images in a blogger website or blog. Before starting , the first thin g I am assu m ing is that you are aware of SVG if you are here. If not please see S calable V ec tor G raphics Recently when I tried to embed a SVG image for a post on pygal, I tried uploading the SVG file and blogger Image uploader came up with an error, because of which I had to find some other way.  SVG File upload Error in Blogger  I started sea rc hing Google " Embed SVG in Blogger " . I found blogorrhea , w h ich gave some i nformatio n on add ing SVG directly as a markup , which worked , but I faced another problem using this . Also th is guy has used lot of Javascript which was confusin g for me, being new to using SVG.   So I first t houg ht of learning on h ow to embed SVG in HTML and t his on e worked out. Actually we can embed SVG in HTML i n following ways: Using Object tag Using Iframe tag Using embed...

Making a quiz web app with python and flask

Edit : When you are creating a web app with h tml templates, then y ou will have to sa ve the html file in templates folder in the Current Wor ki ng Directory( CWD). If you save the file in the C W D directl y you will get a TemplateNotFound error. Thank you Udhay for pointing it out.   In this post we will create a quiz website using python . I will be using the flask framework . After reading this tutorial you will learn form submission , flask templates , python code in flask templates , shuffling the questions and options with the random module and few others.  Please note that this tutorial is not big as it seems to be. Some of the code has been rewritten to maintain consistency and also font size is somewhat big so that your eyes won't get stressed reading this tutorial. Also the content has not occupied the full width of the page. In this tutorial I am assuming that you are having a very basic understanding of the flask framework . Please refer the documenta...