Support the author!
Lulu Editions
Paypal Donation
Other Publications
In earlier puzzles, we had fun playing dominoes. For the next few puzzles, let’s play poker. In particular, let’s say that a player has five cards, and we wish to compare two hands to each other. We will do this, over several puzzles, by building up small functions to answer various questions.
As much as possible, you should use regular expressions to express the logic; however, a few of the questions will require a little bit of non-regex code as well. First, let’s remind ourselves of the ranking of different hands of 5 cards. Our encoding will simplify card representations a little bit. Specifically, the card that might be called, e.g., 10♥
will be called T♥
so that every card is a two symbol combination.
J♣ T♣ 9♣ 8♣ 7♣
A♥ 3♠ 3♥ 3♦ 3♣
K♠ K♣ 6♥ 6♦ 6♣
J♦ 9♦ 6♦ 5♦ 2♦
9♦ 8♣ 7♣ 6♥ 5♣
Q♣ 8♠ 8♦ 8♣ 3♥
J♠ J♣ 9♥ 8♥ 8♦
A♥ K♦ 4♠ 4♥ 3♠
K♠ 9♥ 8♠ 4♥ 2♣
Within the same kind of hand, other rules come into play. Let’s ignore those for now. We’d like two support functions to start. First, you should write a function prettify(hand)
that takes an easier-to-type representation of suits as ‘S’, ‘H’, ‘D’, ‘C’, and turns the hands into their Unicode symbols.
The second and more difficult function for this puzzle asks you to make sure all the cards are sorted in descending order (as in the examples), where aces are always considered high, and the suits are ordered spades, hearts, diamonds, clubs.
This second function, cardsort(hand)
, uses more Python than regular expressions per se, so just read the solution if you are less comfortable with Python itself.
Before you turn the page…
Functions are a big help in larger programs.
The truth is, we do not genuinely need regular expressions for either of these support functions. But we do have the opportunity to use them. First let’s transform any ASCII version of a hand into the Unicode version. Along the way, we make sure the hand consists of five valid ASCII cards.
def prettify(hand):
assert re.search(r'^([2-9TJQKA][SHDC] ?){5}$', hand)
= {'S': '\u2660', 'H': '\u2665',
symbols 'D': '\u2666', 'C': '\u2663'}
for let, suit in symbols.items():
= re.sub(let, suit, hand)
hand return hand
Sorting uses mostly plain Python techniques. In particular, we can rely on the fact that Python’s sort is stable. This means the order will not change between equivalent elements. Therefore, sorting first by suit, then by number will be guaranteed to have the right overall effect.
def cardsort(hand):
def by_num(card):
map = {'T':'A', 'J':'B', 'Q':'C',
'K':'D', 'A':'E'}
= card[0]
num return num if num not in 'AKQJT' else map[num]
def by_suit(card):
map = {'\u2663': 1, '\u2666': 2,
'\u2665': 3, '\u2660': 4}
return map[card[1]]
= re.split(' ', hand)
hand =by_suit, reverse=True)
hand.sort(key=by_num, reverse=True)
hand.sort(keyreturn ' '.join(hand)
Combining these:
>>> cardsort(prettify('8C AS 4H KS 2C'))
'A♠ K♠ 8♣ 4♥ 2♣'
We will need more regular expressions in the next few puzzles which continue this poker theme.