C'est l'aventure, la vraie, notre voyage vers Desert Island, les bords du Nil-dans-les-nuages, croisière tout compris, hôtel de luxe, etc, ben en fait c'est un aller-simple pour les dunes, sous le cagnard torride de cet hiver nuageux, à dos de dromadaire.
Et là, paf, un elfe qui nous demande les morceaux de machine piur réparer la machine à faire des trucs pour que des bidules se passent et qu'on ait enfin de la neige loin d'ici.
Si vous vous demandez quelles parties de quelle machine, z'en êtes au même point que moi.
Comme l'elfe en question a pas l'air plus malin que ses copains, on va jouer au poker, à dos de dromadaire, donc une version spéciale du poker.
Avec des cartes spéciales : 2 à 9, valet, pas-enore-joker, dame, roi, et as, dans l'ordre de puissance.
On a une main de cinq cartes et on compare les figures :
- toutes différentes ;
- une paire ;
- deux paires ;
- brelan ;
- full ;
- carré ;
- carré-à-5-carte-des-tricheurs.
Oui, en fait on joue sans les couleurs, l'elfe doit être dischromatopsique, ou alors le soleil affadi tellement les couleurs qu'on ne les reconnait plus depuis le temps.
Et on mélange les paquets, donc on peut avoir 5 cartes identiques, et on sait bien ce qu'il arrive aux cowboys qui sortent 5 as au poker, ils gagnent un cinquième trou de balle, et rendent visite au croque-mort.
Bref, pas ici apparemment.
Et alors la subtilité, c'est qu'on ne trie pas ses cartes, l'ordre compte quand deux mains sont du même type.
Par exemple A2222 et 99997, deux carrés, un de 2 et l'autre de 9, et bien c'est celui de 2 qui l'emporte parce que la main commence par un As qui est plus balaise que le 9.
Autant dire que c'est un poker pour surchauffés cérébraux, les insolations doivent être communes dans les parages.
Bref, on s'entraîne en triant des mains de pas-tout-à-fait-poker, savoir laquelle est plus forte que l'autre.
Et là, coup de symbale, coup de théatre, ou encore un de ces mauvais joueurs qui ne te donnent pas une règle super spéciale avant de t'avoir mis minable : la carte que j'ai fort (peu) subtilement nommée « pas-enore-joker » est un joker.
Elle ne vaut rien au classement, mais se combine avec n'importe quelle autre carte pour déterminer le type de main, qui va de fait devenir meilleure et être mieux classée.
Ah, bah on comprend mieux comment on peut avoir cinq cartes identiques maintenant !
Parce qu'en y regardant de plus près, dans les mains fournies, on n'a jamais 5 cartes identiques, on aurait donc pu flairer le piège et se douter qu'il y avait un Joker dans la liste des cartes.
Bref, tout ça fait passer le temps, pendant qu'on brûle sous le soleil nuageux du désert dans les airs.
Allez, à vos modélisations :)
- Yth.
# Moi, aujourd'hui, je modélise tout propre tout joli !
Posté par Yth (Mastodon) . Évalué à 2.
Surtout que quand j'ai voulu faire mon malin, j'avais une erreur que je n'ai jamais trouvée, mais qui s'est corrigée d'elle-même en remplaçant des chiffres par des trucs lisibles.
Comme quoi coder propre, contrairement à la rumeur, ben c'est utile même pour soi-même aujourd'hui.
Voilà, avec ça on corrige des bugs, et on supprime plein de commentaires devenus inutiles aussi :
Comme ça on peut comparer le HandType entre deux mains, et le plus grand est plus fort.
L'autre étape c'est de renommer les cartes pour pouvoir comparer deux mains du même type :
Et pour l'exercice 2, on initialise les données (hands2) tout pareil sauf qu'on fait :
str.maketrans("TJQKA", "a0cde")
comme ça le Joker a une valeur plus petite que les autres cartes lors de la comparaison. Et en plus on va pouvoir bosser avec la même classe Hand, et compter les Jokers, donc les "0", et comme il n'y en a pas dans les données transformées pour l'exercice 1, ça va fonctionner pour les deux !Maintenant notre classe
Hand
peut être initialisée avec les données :hand
etbid
, et on la décore pour pouvoir ordonner directement une liste de mains. Lecached_property
permet de s'assurer qu'on ne recalculera jamais deux fois le score d'une main lors de l'exécution (an pratique ça divise le temps d'exécution par 2 environ, ça aurait pu être bien pire…). On utilise unefrozen dataclass
parce qu'on ne modifie pas une main, là aussi c'est de l'optimisation qui peut s'avérer déterminante en cas de problème vraiment gros.Ouaip, on simplifie en disant que deux mains sont toujours différentes, à toutes fins utiles, ça va plus vite, hein ?
Parce qu'on suppose, vu l'exercice, que toutes les mains fournies sont différentes, sinon le calcul final donnera un résultat différent (sauf si elles ont le même « bid », auquel cas osef).
De plus
cut -d\ -f1 < 07.input | sort -u | wc -l; wc -l 07.input
nous retourne 1000 lignes pour chaque, on a donc bien des mains uniques dans les données en entrée.En pratique on ne gagne rien, avec la cached_property sur le score, de toute façon on va calculer le score une seule fois par main, et ça coûte pas lourd comme comparaisons. Mais là aussi c'est lié finalement à la toute petite quantité de données.
Bref, il ne nous reste plus qu'à résoudre, avec la fonction
sorted()
qui va faire tout le boulot à notre place, magique !Et enfin, voilà le code de la méthode
Hand.score
, là où on se rend compte que tous les magiciens ont leur « trucs ». Je ne sais pas si j'aurais pu faire plus « intelligent », mais c'est assez clair je pense.Et voilà :)
Et une fois n'est pas coutume : PyPy est largement moins efficace que Python là-dessus, on passe de 70 à 370 millisecondes, même avec les 150ms de démarrage de PyPy, c'est amplement trois fois moins bon pour l'exécution en elle-même.
Dans tous les cas : pas de quoi faire chauffer la pièce à coups de CPU.
[^] # Re: Moi, aujourd'hui, je modélise tout propre tout joli !
Posté par 🚲 Tanguy Ortolo (site web personnel) . Évalué à 3.
Je découvre
cached_property
, merci ![^] # Re: Moi, aujourd'hui, je modélise tout propre tout joli !
Posté par barmic 🦦 . Évalué à 2.
Personnellement je l'ai pris en compte pendant de calcul du jocker :
J'augmente la plus grand nombre de carte identique par le nombre de jocker.
https://linuxfr.org/users/barmic/journaux/y-en-a-marre-de-ce-gros-troll
# T means 10
Posté par 🚲 Tanguy Ortolo (site web personnel) . Évalué à 4.
Petite subtilité sémantique, les cartes disponibles sont 23456789TJQK, ce qui signifie :
La raison d'utiliser la lettre T pour le dix vient de la nécessité de l'écrire en un seul caractère. 10, ça fait deux caractères…
[^] # Re: T means 10
Posté par Yth (Mastodon) . Évalué à 2.
Et A pour As aussi, au bout.
[^] # Re: T means 10
Posté par mac__ . Évalué à 1.
Il est d'ailleurs probablement malin de ré-écrire les nom des cartes dans la chaîne de caractères qui correspond à une main, pour faciliter le tri en utilisant l'ordre lexicographique quand on a besoin de comparer des mains qui sont ex-aequo…
Pour ma part, j'ai fait (pour la partie 1):
A -> E
K -> D
Q -> C
J -> B
T -> A
De même, il est aussi malin de trier les mains - ça rend le repérage des combinaisons trivial avec quelques regexp bien placées (il y a juste une subtilité pour le Full qui peut être XXXYY ou XXYYY)
# Besoin d'énumérations ordonnées
Posté par 🚲 Tanguy Ortolo (site web personnel) . Évalué à 3.
Comme j'aime bien modéliser, c'est un sujet où j'utilise naturellement des énumérations. Pour les cartes, comme pour les types de mains.
L'avantage en donnant aux cartes la valeur correspondant au caractère qui les représente, c'est que ça permet de les parser très facilement :
Le problème, c'est que je veux comparer les cartes. Et des énumérations, eh bien ça ne se compare pas. Pas sans implémenter au moins une fonction de comparaison. Et ça, c'est… pénible.
Je rêve donc d'une solution propre pour définir une classé énumérée dont les membres se comparent, simplement avec leur ordre de définition.
[^] # Re: Besoin d'énumérations ordonnées
Posté par 🚲 Tanguy Ortolo (site web personnel) . Évalué à 3.
https://blog.yossarian.net/2020/03/02/Totally-ordered-enums-in-python-with-ordered_enum
https://stackoverflow.com/questions/42369749/use-definition-order-of-enum-as-natural-order
[^] # Re: Besoin d'énumérations ordonnées
Posté par Yth (Mastodon) . Évalué à 2. Dernière modification le 07 décembre 2023 à 15:27.
Une idée :
Un peu du hack puisque la définition même de la classe est bancale, et qu'il faut modifier après initialisation et avant utilisation, mais ça fonctionne.
[^] # Re: Besoin d'énumérations ordonnées
Posté par Yth (Mastodon) . Évalué à 2.
Et en rajoutant deux lignes tu peux les utiliser dans des Set, ou en clé de dictionnaires etc :
Avec ça je n'ai quasiment rien à changer dans mon algorithme pour utiliser cette classe à la place des caractères "23456789abcdef" comme je l'ai fait dans ma solution.
J'aime bien l'élégance de la chose, et le côté vraiment lisible, zéro hack dans le reste du code.
Bon, par contre je n'ai besoin que de
Card.JOKER
de façon explicite.Il faut juste faire un
line.replace(Card.JACK.value, Card.JOKER.value
pour la seconde partie de l'exercice, à la place desa.translate(str.maketrans("TJQKA", "a0cde"))
, c'est plus joli.Je perd un poil en perfs par contre : 85ms au lieu de 70ms.
Je suppose que c'est au niveau de la comparaison d'un tuple de Card par rapport à celle de deux str dans mon code initial.
Pas très sûr, mais c'est dommage…
[^] # Re: Besoin d'énumérations ordonnées
Posté par 🚲 Tanguy Ortolo (site web personnel) . Évalué à 3.
Une énumération n'est pas nativement utilisable dans des ensembles ou en clef de dictionnaire ???
[^] # Re: Besoin d'énumérations ordonnées
Posté par Yth (Mastodon) . Évalué à 2.
Ah non, ma faute, en fait il ne faut pas redéfinir
__eq__()
, si on le fait alors ça fait sauter le hash (enfin, disons que ça casse quelque chose quelque part) et on ne peut plus l'utiliser dans les set(), mais on n'a pas besoin de surcharger cette méthode : elle fonctionne très bien nativement.Donc on définit uniquement
__lt__()
avec le @total_ordering, et on est bon :)# Python
Posté par alberic89 🐧 . Évalué à 1.
C'est très très très louche : on est un jour impair et la difficulté est raisonnable. Nous sommes trahis.
POur aujourd'hui, j'ai défini deux classes Hand et HandJoker très semblables et qui ont certains opérateurs surchargés pour pouvoir utiliser la fonction
sorted()
.Après les avoir triés dans des listes par catégories, ont les tris et on récupère le score.
L'informatique n'est pas une science exacte, on n'est jamais à l'abri d'un succès
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.