Weekly Challenge 291
Each week Mohammad S. Anwar sends out The Weekly Challenge, a chance for all of us to come up with solutions to two weekly tasks. My solutions are written in Python first, and then converted to Perl. It's a great way for us all to practice some coding.
Challenge, My solutions
Task 1: Middle Index
Tasks
You are given an array of integers, @ints.
Write a script to find the leftmost middle index (MI) i.e. the smallest amongst all the possible ones.
A middle index is an index where ints[0] ints[1] … ints[MI-1] == ints[MI 1] ints[MI 2] … ints[ints.length-1].
- If MI == 0, the left side sum is considered to be 0. Similarly,
- if MI == ints.length - 1, the right side sum is considered to be 0.
My solution
This is relatively straight forward. I loop through the position from 0 to one less than the length of the inputs. At each position I see if the condition is met.
def middle_index(ints: list) -> int: for i in range(len(ints)): if sum(ints[:i]) == sum(ints[i + 1:]): # It is, so return this position return i return -1
Examples
$ ./ch-1.py 2 3 -1 8 4 3 $ ./ch-1.py 1 -1 4 2 $ ./ch-1.py 2 5 -1
Task 2: Poker Hand Rankings
Task
A draw poker hand consists of 5 cards, drawn from a pack of 52: no jokers, no wild cards. An ace can rank either high or low.
Write a script to determine the following three things:
- How many different 5-card hands can be dealt?
- How many different hands of each of the 10 ranks can be dealt? See here for descriptions of the 10 ranks of Poker hands: https://en.wikipedia.org/wiki/List_of_poker_hands#Hand-ranking_categories
- Check the ten numbers you get in step 2 by adding them together and showing that they're equal to the number you get in step 1.
My solution
Strap in, because this is going to be a long post. It's also the first time in a long time that a task hasn't required any input. In the challenges I've completed, the last one was #177.
To answer the first question, there are 311,875,200 possible permutations of cards that can be dealt (52 × 51 × 50 × 49 × 48). However, the order of cards does not matter. For any five drawn cards, they can be arranged in 120 ways (5 × 4 × 3 × 2 × 1). Therefore there are 2,598,960 unique combinations.
I start by creating a deck of cards. For this I have a rank (card number) of 1 to 13. 1 is an ace, 2 to 10 are the numbers, 11 is Jack, 12 is Queen and the King is 13. I also have a suit s, c, d and h (spare, club, diamond and heart respectively). Using a double for loop, I generate all 52 cards (a tuple of rank and suit) and store this in a list called deck.
I then loop through each unique five card combination of deck, and determine what hand I hold. Finally I print the results.
def middle_index(ints: list) -> int: for i in range(len(ints)): if sum(ints[:i]) == sum(ints[i + 1:]): # It is, so return this position return i return -1
That's the easy part :)
For the get_hands function, I start by creating a dict of lists sorting by rank (the number on the card) and suit (the symbol on the card). I also count the frequency of ranks, as this is often used to determine the hand.
$ ./ch-1.py 2 3 -1 8 4 3 $ ./ch-1.py 1 -1 4 2 $ ./ch-1.py 2 5 -1
So for the cards 10s, 10h, 9d, 8h, 2d, the following would be set:
- cards_by_rank {10: ['s', 'h'], 9: ['d'], 8: ['h'], 2: ['d']}
- cards_by_suit {'s': [10], 'h': [10, 8], 'd': [9, 2]}
- count_by_rank {1: 3, 2: 1} (there are three ranks that appear once, and one that has two cards)
It's then time to determine what hand I am holding. We'll start with the straight flush and flush. These are the only hands that consider the suit of the cards, and that all fives cards are of the same suit. This is determined when the cards_by_suit dict only has one value.
To determine if it is a straight flush, I order the cards numerically (from 1 to 13). If the first card is 1 (an ace) and the last card is 13 (king), I remove the first card and append 14 to the end of the list. This allows a 10, Jack, Queen, King and Ace to be considered a straight flush. A straight flush occurs when the difference between the first card number and last card is four.
from collections import Counter, defaultdict from itertools import combinations def main(): deck = [(rank, suit) for rank in range(1, 14) for suit in ('s', 'c', 'd', 'h')] hands = defaultdict(int) for cards in combinations(deck, 5): hand = get_hand(cards) hands[hand] += 1 display_results(hands)
For the four of a kind hand (four of one rank, and a random last card) and full house (three of one rank, two of a different rank), I can use the count_by_rank dict to see if the hand matches the specified criteria.
def get_hand(cards): cards_by_rank = defaultdict(list) cards_by_suit = defaultdict(list) for card in cards: number, suit = card cards_by_rank[number].append(card[1]) cards_by_suit[suit].append(card[0]) count_by_rank = Counter(len(cards_by_rank[r]) for r in cards_by_rank)
To determine if the hand is straight, I use a similar logic to the straight flush. I first check that I have five unique ranks (card numbers), order them, move the ace if required, and check if the difference between high and low is 4.
if len(cards_by_suit) == 1: cards = sorted(cards_by_rank) if cards[0] == 1 and cards[4] == 13: cards.pop(0) cards.append(14) if cards[4] - cards[0] == 4: return 'Straight flush' return 'Flush'
Three of a kind (three cards of a single rank, two cards of different ranks), two pairs (two cards of one rank, two cards of a different rank, random last card), one pair (two cards of one rank, three cards of a different rank each) can all be calculated using the count_by_rank dict.
if count_by_rank[4]: return 'Four of a kind' if count_by_rank[3] and count_by_rank[2]: return 'Full house'
And finally if nothing matches, return 'High card'. You definitely won't want to bet your house if you are holding this hand :)
if len(cards_by_rank) == 5: # Get the card ranks in the possible flush cards = sorted(cards_by_rank) if cards[0] == 1 and cards[4] == 13: cards.pop(0) cards.append(14) if cards[4] - cards[0] == 4: return 'Straight'
The display_results function simply displays the results (ordered by rank) in a uniformed layout. As mentioned at the start for each combination there are 120 permutations the card could be ordered in.
if count_by_rank[3]: return 'Three of a kind' if count_by_rank[2] == 2: return 'Two pair' if count_by_rank[2]: return 'One pair'
Output
return 'High card'
This took about 15 seconds to run on my home PC.
As we can see from the bottom row, we have 2,598,960 combinations and 311,875,200 permutations. This matches what we expected to see in the output.
The above is the detailed content of Index and poker games. For more information, please follow other related articles on the PHP Chinese website!

TomergelistsinPython,youcanusethe operator,extendmethod,listcomprehension,oritertools.chain,eachwithspecificadvantages:1)The operatorissimplebutlessefficientforlargelists;2)extendismemory-efficientbutmodifiestheoriginallist;3)listcomprehensionoffersf

In Python 3, two lists can be connected through a variety of methods: 1) Use operator, which is suitable for small lists, but is inefficient for large lists; 2) Use extend method, which is suitable for large lists, with high memory efficiency, but will modify the original list; 3) Use * operator, which is suitable for merging multiple lists, without modifying the original list; 4) Use itertools.chain, which is suitable for large data sets, with high memory efficiency.

Using the join() method is the most efficient way to connect strings from lists in Python. 1) Use the join() method to be efficient and easy to read. 2) The cycle uses operators inefficiently for large lists. 3) The combination of list comprehension and join() is suitable for scenarios that require conversion. 4) The reduce() method is suitable for other types of reductions, but is inefficient for string concatenation. The complete sentence ends.

PythonexecutionistheprocessoftransformingPythoncodeintoexecutableinstructions.1)Theinterpreterreadsthecode,convertingitintobytecode,whichthePythonVirtualMachine(PVM)executes.2)TheGlobalInterpreterLock(GIL)managesthreadexecution,potentiallylimitingmul

Key features of Python include: 1. The syntax is concise and easy to understand, suitable for beginners; 2. Dynamic type system, improving development speed; 3. Rich standard library, supporting multiple tasks; 4. Strong community and ecosystem, providing extensive support; 5. Interpretation, suitable for scripting and rapid prototyping; 6. Multi-paradigm support, suitable for various programming styles.

Python is an interpreted language, but it also includes the compilation process. 1) Python code is first compiled into bytecode. 2) Bytecode is interpreted and executed by Python virtual machine. 3) This hybrid mechanism makes Python both flexible and efficient, but not as fast as a fully compiled language.

Useaforloopwheniteratingoverasequenceorforaspecificnumberoftimes;useawhileloopwhencontinuinguntilaconditionismet.Forloopsareidealforknownsequences,whilewhileloopssuitsituationswithundeterminediterations.

Pythonloopscanleadtoerrorslikeinfiniteloops,modifyinglistsduringiteration,off-by-oneerrors,zero-indexingissues,andnestedloopinefficiencies.Toavoidthese:1)Use'i


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

SublimeText3 English version
Recommended: Win version, supports code prompts!

MinGW - Minimalist GNU for Windows
This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

ZendStudio 13.5.1 Mac
Powerful PHP integrated development environment

Zend Studio 13.0.1
Powerful PHP integrated development environment

Notepad++7.3.1
Easy-to-use and free code editor
