Chaque semaine, Mohammad S. Anwar envoie The Weekly Challenge, une chance pour nous tous de trouver des solutions à deux tâches hebdomadaires. Mes solutions sont d'abord écrites en Python, puis converties en Perl. C'est une excellente façon pour nous tous de pratiquer le codage.
Défi, Mes solutions
Vous recevez un tableau d'entiers, @ints.
Écrivez un script pour trouver l'index du milieu (MI) le plus à gauche, c'est-à-dire le plus petit parmi tous les possibles.
Un index intermédiaire est un index où ints[0] ints[1] … ints[MI-1] == ints[MI 1] ints[MI 2] … ints[ints.length-1].
C'est relativement simple. Je boucle la position de 0 à un de moins que la longueur des entrées. A chaque position je vois si la condition est remplie.
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
$ ./ch-1.py 2 3 -1 8 4 3 $ ./ch-1.py 1 -1 4 2 $ ./ch-1.py 2 5 -1
Une main de poker à tirage se compose de 5 cartes, tirées d'un paquet de 52 : pas de jokers, pas de jokers. Un as peut être classé haut ou bas.
Écrivez un script pour déterminer les trois choses suivantes :
Attachez-vous, car cela va être un long article. C'est aussi la première fois depuis longtemps qu'une tâche ne nécessite aucune intervention. Dans les défis que j'ai relevés, le dernier était le n°177.
Pour répondre à la première question, il existe 311 875 200 permutations possibles de cartes pouvant être distribuées (52 × 51 × 50 × 49 × 48). Toutefois, l’ordre des cartes n’a pas d’importance. Pour cinq cartes tirées, elles peuvent être disposées de 120 façons (5 × 4 × 3 × 2 × 1). Il existe donc 2 598 960 combinaisons uniques.
Je commence par créer un jeu de cartes. Pour cela j'ai un rang (numéro de carte) de 1 à 13. 1 est un as, 2 à 10 sont les chiffres, 11 est Valet, 12 est Reine et le Roi est 13. J'ai aussi une couleur s, c, d et h (de rechange, club, diamant et cœur respectivement). À l'aide d'une boucle double for, je génère les 52 cartes (un tuple de rang et de couleur) et les stocke dans une liste appelée deck.
Je parcoure ensuite chaque combinaison unique de cinq cartes du jeu et détermine quelle main je détiens. Enfin j'imprime les résultats.
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
C'est la partie la plus facile :)
Pour la fonction get_hands, je commence par créer un dict de listes triées par rang (le numéro sur la carte) et par couleur (le symbole sur la carte). Je compte aussi la fréquence des rangs, car elle est souvent utilisée pour déterminer la main.
$ ./ch-1.py 2 3 -1 8 4 3 $ ./ch-1.py 1 -1 4 2 $ ./ch-1.py 2 5 -1
Donc pour les cartes 10s, 10h, 9d, 8h, 2d, ce qui suit serait réglé :
Il est alors temps de déterminer quelle main je tiens. Nous allons commencer par la quinte flush et la quinte flush. Ce sont les seules mains qui prennent en compte la couleur des cartes et que les cinq cartes sont de la même couleur. Ceci est déterminé lorsque le dict cards_by_suit n'a qu'une seule valeur.
Pour déterminer s'il s'agit d'une quinte flush, j'ordonne les cartes numériquement (de 1 à 13). Si la première carte est 1 (un as) et la dernière carte est 13 (roi), je retire la première carte et j'ajoute 14 à la fin de la liste. Cela permet à un 10, un Valet, une Dame, un Roi et un As d'être considérés comme une quinte flush. Une quinte flush se produit lorsque la différence entre le premier numéro de carte et la dernière carte est de quatre.
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)
Pour le carré (quatre d'un même rang et une dernière carte aléatoire) et le full (trois d'un même rang, deux d'un rang différent), je peux utiliser le dict count_by_rank pour voir si la main correspond les critères spécifiés.
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)
Pour déterminer si la main est droite, j'utilise une logique similaire à celle de la quinte flush. Je vérifie d'abord que j'ai cinq rangs uniques (numéros de carte), je les ordonne, je déplace l'as si nécessaire et je vérifie si la différence entre le haut et le bas est de 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'
Brolan (trois cartes d'un même rang, deux cartes de rangs différents), deux paires (deux cartes d'un même rang, deux cartes d'un rang différent, dernière carte aléatoire), une paire (deux cartes d'un rang, trois cartes d'un rang différent chacune) peuvent toutes être calculées à l'aide du dict count_by_rank.
if count_by_rank[4]: return 'Four of a kind' if count_by_rank[3] and count_by_rank[2]: return 'Full house'
Et enfin si rien ne correspond, retournez 'High card'. Vous ne voudrez certainement pas parier votre maison si vous détenez cette main :)
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'
La fonction display_results affiche simplement les résultats (classés par classement) dans une présentation uniforme. Comme mentionné au début, pour chaque combinaison, il existe 120 permutations dans lesquelles la carte peut être commandée.
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'
return 'High card'
Cela a pris environ 15 secondes pour s'exécuter sur mon PC personnel.
Comme nous pouvons le voir sur la rangée du bas, nous avons 2 598 960 combinaisons et 311 875 200 permutations. Cela correspond à ce que nous nous attendions à voir dans le résultat.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!