Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > fr.comp.lang.python > #4113 > unrolled thread
| Started by | Dominique <dominique.sextant@orange.fr.invalid> |
|---|---|
| First post | 2023-11-28 11:33 +0100 |
| Last post | 2023-11-28 19:23 +0100 |
| Articles | 19 — 4 participants |
Back to article view | Back to fr.comp.lang.python
Tricher au scrabble... Dominique <dominique.sextant@orange.fr.invalid> - 2023-11-28 11:33 +0100
Re: Tricher au scrabble... Dominique <dominique.sextant@orange.fr.invalid> - 2023-11-28 16:39 +0100
Re: Tricher au scrabble... Dominique <dominique.sextant@orange.fr.invalid> - 2023-11-28 16:43 +0100
Re: Tricher au scrabble... yves <yves@free.invalid> - 2023-12-01 17:39 +0000
Re: Tricher au scrabble... yves <yves@free.invalid> - 2023-12-01 17:56 +0000
Re: Tricher au scrabble... Michel <michel@domain.invalid> - 2023-12-02 03:48 +0100
Re: Tricher au scrabble... yves <yves@free.invalid> - 2023-12-06 22:22 +0000
Re: Tricher au scrabble... Michel <michel@domain.invalid> - 2023-12-07 10:28 +0100
Re: Tricher au scrabble... Thierry Pinelli <olmia2b+news@gmail.com> - 2023-12-07 16:35 +0100
Re: Tricher au scrabble... Thierry Pinelli <olmia2b+news@gmail.com> - 2023-12-07 17:52 +0100
Re: Tricher au scrabble... yves <yves@free.invalid> - 2023-12-07 18:00 +0000
Re: Tricher au scrabble... yves <yves@free.invalid> - 2023-12-07 18:07 +0000
Re: Tricher au scrabble... yves <yves@free.invalid> - 2023-11-28 16:05 +0000
Re: Tricher au scrabble... yves <yves@free.invalid> - 2023-11-28 16:17 +0000
Re: Tricher au scrabble... Dominique <dominique.sextant@orange.fr.invalid> - 2023-11-29 05:55 +0100
Re: Tricher au scrabble... yves <yves@free.invalid> - 2023-11-28 20:16 +0000
Re: Tricher au scrabble... Michel <michel@domain.invalid> - 2023-11-28 17:52 +0100
Re: Tricher au scrabble... Dominique <dominique.sextant@orange.fr.invalid> - 2023-11-29 05:57 +0100
Re: Tricher au scrabble... Michel <michel@domain.invalid> - 2023-11-28 19:23 +0100
| From | Dominique <dominique.sextant@orange.fr.invalid> |
|---|---|
| Date | 2023-11-28 11:33 +0100 |
| Subject | Tricher au scrabble... |
| Message-ID | <uk4fm4$852n$1@dont-email.me> |
Bonjour,
Je m'amuse à faire un logiciel de triche au Scrabble. J'ai bien les
presque 350 000 mots en français au format txt.
Voici mes débuts :
-----------------------------------------
f=open('/home/USER/dico.txt')
scrabble=dict()
for i in f:
j=i[:-1]
mot=list(j)
mot.sort()
mot=''.join(mot)
scrabble[str(mot)]=j
del (mot)
del (i)
del(j)
del (f)
print('Création du dictionnaire terminée')
test='xx'
while test=='xx':
lettres=input('Lettres ')
lettres=list(lettres)
lettres.sort()
lettres=''.join(lettres)
if lettres!='xx':
if lettres in scrabble.keys():
print(scrabble[lettres])
else:
test=9
-----------------------------------------
Ce script fonctionne en deux blocs. Le premier, qui ne tourne qu'une
fois, charge le dico.text. Il parcourt chaque mot, le transforme en
liste, met les lettre par ordre alpha croissant, reconstitue un string
avec join. Il affecte comme values à cette keys le mot d'origine j.
Le deuxième bloc me demande mes lettres, les transforme en liste, les
classe par ordre alpha, reconstitue un string et voit si cette variable
existe en keys dans mon dictionnaire scrabble, ce à quoi il me donne la
values correspondant.
Il répond à la question, dès lors que les lettres que je lui soumets
existent à l'identique en clef. J'ai des limites. Par exemple, avec les
lettre aberv, il me proposera brave mais pas baver.
La vraie limite vient de ce que je ne vois pas trop comment faire pour
que l'application cherche un mot avec mes 7 lettres, en cas d'échec,
avec 6 lettres etc. Je pense que je pourrais utiliser les outils
d'itertools (combination ou permutations. mais j'ai peur que les temps
de traitements deviennent très longs...
Comment verriez-vous les choses ?
Merci et belle journée à vous tous,
--
Dominique
Esto quod es
[toc] | [next] | [standalone]
| From | Dominique <dominique.sextant@orange.fr.invalid> |
|---|---|
| Date | 2023-11-28 16:39 +0100 |
| Message-ID | <uk51jt$auel$1@dont-email.me> |
| In reply to | #4113 |
Le 28/11/2023 à 12:30, Stefan Ram a écrit : > Dominique <dominique.sextant@orange.fr.invalid> writes: >> del (mot) > > Tout d'abord, juste une remarque sur ce qui est cité ci-dessus : > > Au lieu de « del(x) », on peut souvent écrire simplement > « del x », sans les parenthèses. > > Ensuite, on peut souvent remplacer > > x = 1 > print( x ) > del x > > par > > def ecris_1(): > x = 1 > print( x ) > > ecris_1() > > . Cela comprend certes plus de lignes, mais correspond > probablement plus au style habituel. La variable « x » > n'existe plus non plus après cela. > > Effectivement, par une fonction, les variables disparaissent après exécution. Merci pour le rappel :) -- Dominique Esto quod es
[toc] | [prev] | [next] | [standalone]
| From | Dominique <dominique.sextant@orange.fr.invalid> |
|---|---|
| Date | 2023-11-28 16:43 +0100 |
| Message-ID | <uk51rm$auel$2@dont-email.me> |
| In reply to | #4113 |
Le 28/11/2023 à 13:22, Stefan Ram a écrit : > > Il y a encore une remarque à faire sur le style de programmation : > si un script est composé de deux blocs, il sera plus clair > pour le lecteur si chaque bloc est défini comme une fonction > et nommé par sa tâche. J'y ai bien pensé, mais le premier bloc n'est exécuté qu'une fois, lors de la création du dictionnaire. Je n'ai pas jugé utile de faire une fonction... Je testerai le listing que tu me proposes dès que j'ai un peu de temps. Merci pour cette approche :) -- Dominique Esto quod es
[toc] | [prev] | [next] | [standalone]
| From | yves <yves@free.invalid> |
|---|---|
| Date | 2023-12-01 17:39 +0000 |
| Message-ID | <656a1a3b$0$10088$426a74cc@news.free.fr> |
| In reply to | #4119 |
Le Tue, 28 Nov 2023 16:43:50 +0100, Dominique a écrit:
>> Il y a encore une remarque à faire sur le style de programmation :
>> si un script est composé de deux blocs, il sera plus clair pour le
>> lecteur si chaque bloc est défini comme une fonction et nommé par sa
>> tâche.
>
> J'y ai bien pensé, mais le premier bloc n'est exécuté qu'une fois, lors
> de la création du dictionnaire. Je n'ai pas jugé utile de faire une
> fonction...
>
> Je testerai le listing que tu me proposes dès que j'ai un peu de temps.
> Merci pour cette approche
J'ai séché aujourd'hui sur un problème wordle qui s'apparentait pour le
coup à un problème de scrabble.
Du coup, j'ai réimplémenté quelques idées de ce fil de façon très brute,
et j'ai été surpris par la rapidité de traitement.
Voici un exemple, avec une séquence de lettres qui a de nombreux
anagrammes :
dictionnaire = "/usr/share/dict/french"
with open(dictionnaire) as f:
b= [mot.rstrip() for mot in f.readlines()]
c= [mot for mot in b if sorted(mot) == sorted("acenrt")]
print(len(b))
print(len(c))
print(c)
print('terminé')
#+RESULTS:
: 346200
: 9
: ['canter', 'cantre', 'carnet', 'centra', 'crante', 'encart', 'nectar',
'tancer', 'tanrec']
: terminé
@+
--
Yves
[toc] | [prev] | [next] | [standalone]
| From | yves <yves@free.invalid> |
|---|---|
| Date | 2023-12-01 17:56 +0000 |
| Message-ID | <656a1e57$0$10088$426a74cc@news.free.fr> |
| In reply to | #4138 |
Le 01 Dec 2023 17:39:07 GMT, yves a écrit:
> Voici un exemple, avec une séquence de lettres qui a de nombreux
> anagrammes :
Encore plus concis, la ligne va sans doute être coupé par les lecteurs de
news:
dictionnaire = "/usr/share/dict/french"
with open(dictionnaire) as f:
resultat = [mot.rstrip() for mot in f.readlines() if
sorted(mot.rstrip()) == sorted("acenrt")]
print(resultat)
print('terminé')
#+RESULTS:
: ['canter', 'cantre', 'carnet', 'centra', 'crante', 'encart', 'nectar',
'tancer', 'tanrec']
: terminé
0.4 secondes sur mon ordi, quand même.
@+
--
Yves
[toc] | [prev] | [next] | [standalone]
| From | Michel <michel@domain.invalid> |
|---|---|
| Date | 2023-12-02 03:48 +0100 |
| Message-ID | <874jh1tlp1.fsf@gnus.org> |
| In reply to | #4139 |
Le 1 décembre 2023 yves a écrit :
> dictionnaire = "/usr/share/dict/french"
> with open(dictionnaire) as f:
> resultat = [mot.rstrip() for mot in f.readlines() if
> sorted(mot.rstrip()) == sorted("acenrt")]
Pour les anagrammes c'est bon mais pour le scrabble on peut avoir des
lettres qui ne seraient pas utilisées et donc cet algo ne marcherait pas.
> 0.4 secondes sur mon ordi, quand même.
Sur le mien 0.280. Mais en reprenant le même principe que pour le
scrabble, en chargeant le fichier dans une array par longueur de mot,
j'obtiens 0.170.
fichier = "/usr/share/dict/french"
# on suppose que les mots font 27 caractères maxi
# (désinstitutionnalisassions)
MAX = 27
def charge_dico():
dictionnaire = [[] for i in range(MAX + 1)]
with open(fichier, 'r') as fp:
while line := fp.readline().rstrip():
dictionnaire[len(line)].append(line)
return dictionnaire
def recherche(lettres, dictionnaire):
resultat = [mot for mot in dictionnaire[len(lettres)]
if sorted(mot) == sorted(lettres)]
return resultat
tests = ['acenrt']
dictionnaire = charge_dico()
for lettres in tests:
print(lettres, ':', recherche(lettres, dictionnaire))
[toc] | [prev] | [next] | [standalone]
| From | yves <yves@free.invalid> |
|---|---|
| Date | 2023-12-06 22:22 +0000 |
| Message-ID | <6570f414$0$27068$426a74cc@news.free.fr> |
| In reply to | #4140 |
Le Sat, 02 Dec 2023 03:48:09 +0100, Michel a écrit: >> 0.4 secondes sur mon ordi, quand même. > > Sur le mien 0.280. Mais en reprenant le même principe que pour le > scrabble, en chargeant le fichier dans une array par longueur de mot, > j'obtiens 0.170. Oui, c'est clair que c'est mieux. > while line := fp.readline().rstrip(): Tiens, je ne connaissais pas cet opérateur ( := ) ni cette syntaxe. En espérant qu'il ne va pas se transformer en émoji. @+ -- Yves
[toc] | [prev] | [next] | [standalone]
| From | Michel <michel@domain.invalid> |
|---|---|
| Date | 2023-12-07 10:28 +0100 |
| Message-ID | <87o7f2pdo8.fsf@gnus.org> |
| In reply to | #4148 |
Le 6 décembre 2023 yves a écrit : >> while line := fp.readline().rstrip(): > > Tiens, je ne connaissais pas cet opérateur ( := ) ni cette syntaxe. Je viens du Perl où il est dit qu'il y a plusieurs façons de faire un truc :) Mais en python je ne suis pas sûr d'utiliser une syntaxe mainstream...
[toc] | [prev] | [next] | [standalone]
| From | Thierry Pinelli <olmia2b+news@gmail.com> |
|---|---|
| Date | 2023-12-07 16:35 +0100 |
| Message-ID | <uksonl$1ae09$1@dont-email.me> |
| In reply to | #4148 |
Le 06/12/2023 à 23:22, yves a écrit : > Le Sat, 02 Dec 2023 03:48:09 +0100, Michel a écrit: > >>> 0.4 secondes sur mon ordi, quand même. >> >> Sur le mien 0.280. Mais en reprenant le même principe que pour le >> scrabble, en chargeant le fichier dans une array par longueur de mot, >> j'obtiens 0.170. > > Oui, c'est clair que c'est mieux. > >> while line := fp.readline().rstrip(): > Tiens, je ne connaissais pas cet opérateur ( := ) ni cette syntaxe. du bon vieux Pascal PPP Perl Python Pascal
[toc] | [prev] | [next] | [standalone]
| From | Thierry Pinelli <olmia2b+news@gmail.com> |
|---|---|
| Date | 2023-12-07 17:52 +0100 |
| Message-ID | <ukst92$1b7cb$1@dont-email.me> |
| In reply to | #4148 |
Le 07/12/2023 à 16:57, Stefan Ram a écrit :
> Il y a aussi un exemple :
>
> |while chunk := file.read(9000):
> | process(chunk)
>
> ("The Python Language Reference", Release 3.13.0a0).
oui, 6.12. Assignment expressions
[toc] | [prev] | [next] | [standalone]
| From | yves <yves@free.invalid> |
|---|---|
| Date | 2023-12-07 18:00 +0000 |
| Message-ID | <6572083e$0$10105$426a74cc@news.free.fr> |
| In reply to | #4148 |
Le 7 Dec 2023 15:57:34 GMT, Stefan Ram a écrit:
> ("The Python Language Reference", Release 3.13.0a0).
Oui, j'en profite pour rappeler l'aide intégrée au prompt python :
Python 3.10.12 (main, Nov 20 2023, 15:14:05) [GCC 11.4.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> help("while")
The "while" statement
*********************
The "while" statement is used for repeated execution as long as an
expression is true:
while_stmt ::= "while" assignment_expression ":" suite
["else" ":" suite]
This repeatedly tests the expression and, if it is true, executes the
first suite; if the expression is false (which may be the first time
it is tested) the suite of the "else" clause, if present, is executed
and the loop terminates.
A "break" statement executed in the first suite terminates the loop
without executing the "else" clause’s suite. A "continue" statement
executed in the first suite skips the rest of the suite and goes back
to testing the expression.
Related help topics: break, continue, if, TRUTHVALUE
@+
--
Yves
[toc] | [prev] | [next] | [standalone]
| From | yves <yves@free.invalid> |
|---|---|
| Date | 2023-12-07 18:07 +0000 |
| Message-ID | <657209f5$0$10105$426a74cc@news.free.fr> |
| In reply to | #4148 |
Le 7 Dec 2023 15:57:34 GMT, Stefan Ram a écrit: > |while_stmt ::= "while" assignment_expression ":" suite On peut noter que cette syntaxe, (:=, également appelé "opérateur d'affectation de l'expression") a été introduite dans la version 3.8 de python, sortie fin 2019*. * juste un peu avant l'épidémie de Covid. Coïncidence ? JE POSE LA QUESTION. @+ -- Yves
[toc] | [prev] | [next] | [standalone]
| From | yves <yves@free.invalid> |
|---|---|
| Date | 2023-11-28 16:05 +0000 |
| Message-ID | <65660fc0$0$6447$426a34cc@news.free.fr> |
| In reply to | #4113 |
Le Tue, 28 Nov 2023 11:33:38 +0100, Dominique a écrit:
> Bonjour,
>
> Je m'amuse à faire un logiciel de triche au Scrabble. J'ai bien les
> presque 350 000 mots en français au format txt.
>
> Voici mes débuts :
>
> -----------------------------------------
> f=open('/home/USER/dico.txt')
> scrabble=dict()
> for i in f:
> j=i[:-1]
> mot=list(j)
> mot.sort() mot=''.join(mot) scrabble[str(mot)]=j
> del (mot)
> del (i)
> del(j)
> del (f)
> print('Création du dictionnaire terminée')
> Comment verriez-vous les choses ?
J'aime bien cogiter sur du concret limpide.
Un petit exemple minimal pour la partie "création de dictionnaire" :
En entrée :
dico.txt :
pomme
fraise
orange
En sortie :
le dictionnaire scrabble :
{'emmop': 'pomme', 'aefirs': 'fraise', 'aegnor': 'orange'}
@+
--
Yves
[toc] | [prev] | [next] | [standalone]
| From | yves <yves@free.invalid> |
|---|---|
| Date | 2023-11-28 16:17 +0000 |
| Message-ID | <6566129a$0$6447$426a34cc@news.free.fr> |
| In reply to | #4121 |
Le 28 Nov 2023 16:05:20 GMT, yves a écrit:
> Un petit exemple minimal pour la partie "création de dictionnaire" :
Encore mieux:
En entrée :
dico.txt :
pomme
fraise
orange
brave
baver
En sortie :
le dictionnaire scrabble :
{'emmop': 'pomme', 'aefirs': 'fraise', 'aegnor': 'orange', 'aberv':
'baver'}
@+
--
Yves
[toc] | [prev] | [next] | [standalone]
| From | Dominique <dominique.sextant@orange.fr.invalid> |
|---|---|
| Date | 2023-11-29 05:55 +0100 |
| Message-ID | <uk6g75$ltg0$1@dont-email.me> |
| In reply to | #4122 |
Le 28/11/2023 à 17:17, yves a écrit :
> Le 28 Nov 2023 16:05:20 GMT, yves a écrit:
>
>> Un petit exemple minimal pour la partie "création de dictionnaire" :
>
> Encore mieux:
>
> En entrée :
> dico.txt :
>
> pomme
> fraise
> orange
> brave
> baver
>
> En sortie :
> le dictionnaire scrabble :
>
> {'emmop': 'pomme', 'aefirs': 'fraise', 'aegnor': 'orange', 'aberv':
> 'baver'}
>
> @+
C'est exactement ce que j'ai fait:)
--
Dominique
Esto quod es
[toc] | [prev] | [next] | [standalone]
| From | yves <yves@free.invalid> |
|---|---|
| Date | 2023-11-28 20:16 +0000 |
| Message-ID | <65664ab1$0$8256$426a34cc@news.free.fr> |
| In reply to | #4121 |
Le 28 Nov 2023 16:19:20 GMT, Stefan Ram a écrit:
> dico = 'pomme', 'fraise', 'orange'
> scrd ={ ''.join( sorted( mot )) : mot for mot in dico }
> print( scrd )
ah oui, ça c'est du concis.
Sympathique :
print(sorted('citron')
Résultat :
['c', 'i', 'n', 'o', 'r', 't']
Mais pas facile à décrypter avant d'avoir bien étudié cette syntaxe.
avec la version étendue, on constate aussi la limite de l'approche par ce
dictionnaire :
dico = 'pomme', 'fraise', 'orange', 'baver', 'brave'
scrd ={ ''.join( sorted( mot )) : mot for mot in dico }
print( scrd )
{'emmop': 'pomme', 'aefirs': 'fraise', 'aegnor': 'orange', 'aberv':
'brave'}
Comme ça :
srcd1 = {mot : ''.join( sorted( mot )) for mot in dico}
print(srcd1)
Résultat:
{'pomme': 'emmop', 'fraise': 'aefirs', 'orange': 'aegnor', 'baver':
'aberv', 'brave': 'aberv'}
Ensuite, il reste à écrire le code pour faire une inversion key/value qui
traite le cas des anagrammes.
@+
--
Yves
[toc] | [prev] | [next] | [standalone]
| From | Michel <michel@domain.invalid> |
|---|---|
| Date | 2023-11-28 17:52 +0100 |
| Message-ID | <87y1eh4ydw.fsf@gnus.org> |
| In reply to | #4113 |
Le 28 novembre 2023 Dominique a écrit : > if lettres in scrabble.keys(): > print(scrabble[lettres]) De passer par un dict ça impose que tu n'auras toujours qu'un seul mot fourni pour un ensemble de lettres. Je ne pense pas que ce soit le mieux pour jouer. Et de plus si tu as des lettres supplémentaires qui ne rentrent pas dans un mot tu n'obtiendras aucun résultat.
[toc] | [prev] | [next] | [standalone]
| From | Dominique <dominique.sextant@orange.fr.invalid> |
|---|---|
| Date | 2023-11-29 05:57 +0100 |
| Message-ID | <uk6gbd$lu0d$1@dont-email.me> |
| In reply to | #4124 |
Le 28/11/2023 à 17:52, Michel a écrit : > Le 28 novembre 2023 Dominique a écrit : > >> if lettres in scrabble.keys(): >> print(scrabble[lettres]) > > De passer par un dict ça impose que tu n'auras toujours qu'un seul mot > fourni pour un ensemble de lettres. Je ne pense pas que ce soit le mieux > pour jouer. Et de plus si tu as des lettres supplémentaires qui ne > rentrent pas dans un mot tu n'obtiendras aucun résultat. Je sais, et c'est bien là ma limite :) -- Dominique Esto quod es
[toc] | [prev] | [next] | [standalone]
| From | Michel <michel@domain.invalid> |
|---|---|
| Date | 2023-11-28 19:23 +0100 |
| Message-ID | <87sf4p4uek.fsf@gnus.org> |
| In reply to | #4113 |
Le 28 novembre 2023 Stefan Ram a écrit :
> Voici une approche possible (sans essayer d'optimiser quoi que ce
> soit) :
J'ai optimisé ton algo en passant par un dictionnaire pour chaque
longueur de mot. Ca permet de limiter les parcours sur le sous-ensemble.
Ca accélère nettement quand on a plein de lettres qui ne collent pas, et
donc qu'on doit chercher plusieurs longueurs.
# apt install wfrench
fichier = '/usr/share/dict/french'
# on suppose que les mots font 27 caractères maxi
# (désinstitutionnalisassions)
MAX = 27
tests = [ 'emmop', 'aefirs', 'aegnor', 'aberv',
'axy', 'emmo', 'emmop', 'emmoepat', 'emoepat',
'aefirs', 'aegnor', 'aegnorer' ]
def possible( mot, mes_lettres ):
'''
les lettres de mes_lettres sont-elles suffisantes pour former le mot ?
'''
for lettre in mot:
if mot.count(lettre) > mes_lettres.count(lettre):
return False
return True
def mots_possibles( dictionnaire, mes_lettres ):
'''
Tous les mots du dictionnaire et qui
peuvent être formés avec les lettres du « mes_lettres ».
'''
résultat = []
for mot in dictionnaire:
if possible(mot, mes_lettres):
résultat.append(mot)
return résultat
def mots_de_longueur_maximale( dictionnaire, mes_lettres ):
'''
Trouve dans le dictionnaire des mots de longueur maximale qui
peuvent être formés avec les lettres indiquées.
'''
for longueur in range( len( mes_lettres ), 1, -1 ):
résultat = mots_possibles( dictionnaire[longueur], mes_lettres )
if résultat: return résultat
return []
def charge_dico():
'''
on passe par une array par longueur de mot
pour lors de la recherche ne parcourir que N mots
au lieu de N x longueurs recherchées
ça augmente le temps de chargement mais
ça divise le temps de recherche par 10
'''
dictionnaire = [[] for i in range(MAX + 1)]
with open(fichier, 'r') as fp:
while line := fp.readline().rstrip():
dictionnaire[len(line)].append(line)
return dictionnaire
dictionnaire = charge_dico()
for lettres in tests:
print(f'{lettres:8s}:', mots_de_longueur_maximale(dictionnaire, lettres))
[toc] | [prev] | [standalone]
Back to top | Article view | fr.comp.lang.python
csiph-web