J'essaie de faire cet exo mais je bloque (débutant inside). Le code "fonctionne", par contre je ne vois pas comment je pourrais faire pour chercher n-1 lettre si il n'y a pas de mots avec n lettres. Je pensais faire une permutations de self.letters, le tirage, en virant la dernière lettre puis l'avant dernière, etc, mais je ne vois pas comment le mettre proprement dans mon usine à gaz. J'ai regardé vos codes, mais je ne les comprends pas tous (trop de fonctions python que je ne connais pas), et je ne vois pas où vous gérez ça. Une coupure de courant avant de poster ce message m'a fait me replonger dans vos codes (itertools.combination()) et j'ai trouvé.
J'ai essayé de le faire en POO pour m'entrainer à la POO et essayer d'en comprendre le fonctionnement. (vous allez me dire que ça sert à rien sur cet exo et que je l'ai mal fait en plus) Si vous pouvez me donner des corrections/conseils...
C'est en python3, le code met dans les 13s à s’exécuter.
# -*- coding:utf-8 -*-
# Algo pour trouver le mot le plus long à partir de 9 letttres.
# Inspiré du jeu télé "Des chiffres et des lettres"
from random import randrange
from string import ascii_lowercase
from itertools import combinations
class Dico(object):
"""La classe pour contenir le dictionnaire des mots"""
def __init__(self):
self.dico = []
def remplissage_dico(self):
# ouverture du fichier
self.f = open("chiffres_lettres_dico.txt", "r")
# boucle pour remplir le dictionnaire
temp_dico = []
word = self.f.readline() #pour sauter la première ligne
letter = 'a' #pour gérer les listes en fonction de la première lettre
while 1:
word = self.f.readline()
if word:
first_letter = word[0]
if first_letter != letter:
self.dico.append(temp_dico)
temp_dico = []
letter = first_letter
else:
temp_dico.append(word[:-1])
#[:-1] pour virer les caractères de fin de ligne
else:
self.dico.append(temp_dico)
break
# fermeture du fichier
self.f.close()
return self.dico
class PlusLong(object):
"""Classse permettant de trouver le mot le plus long"""
def __init__(self, letters, dico):
# on tranforme letters en liste et on trie
self.letters = list(letters)
self.letters.sort()
self.dico = dico
self.mot_trouve = [] #liste des mots trouvés
def cherche(self):
"""cherche le mot le plus long"""
z = len(self.letters)
# tant qu'on ne trouve pas de mots et qu'on est >= 3 lettres
while not self.mot_trouve and z>=3:
# on essaie les combinaisons possibles de lettres
for m in combinations(self.letters, z):
c = self.compare(m)
z -= 1
print("Les mots les plus longs que l'on peut former avec {} sont : {}"
.format(self.letters, self.mot_trouve))
def compare(self, chaine):
"""""Compare la chaine avec le dico"""
for letter in chaine:
# on choisi le dico commencant par letter
first_letter_dico = self.dico[ascii_lowercase.index(letter)]
for mot in first_letter_dico:
# on vire le trait d'union s'il y en a un
mot = mot.replace("-", "")
# si le mot du dico a la même longueur
# que celui recherché on continue
if len(mot) == len(chaine):
# on transforme mot en liste et on trie
mot_trie = list(mot)
mot_trie.sort()
i = 0
t = True
while i<len(mot):
if mot_trie[i] != chaine[i]:
t = False
i+=1
# si t est toujours vrai on ajoute le mot
if t:
self.mot_trouve.append(mot)
class Application(object):
"""Corps de l'application"""
def __init__(self, nb):
self.letters = ''
self.nb = nb # nombre de lettres
self.choix = self.choix_voy_cons()
self.dico = Dico().remplissage_dico()
self.mot_le_plus_long = PlusLong(self.letters, self.dico).cherche()
def choix_voy_cons(self):
consonnes = 'bcdfghjklmnpqrstvwxz'
voyelles = 'aeiouy'
compt_voy = 0 #pour compter les voyelles
for i in range(0, self.nb):
while 1:
# vérifie s'il y a au moins 2 voyelles
if i >= self.nb-2 and compt_voy < 2:
self.letters += voyelles[randrange(0,5)]
print("Le nombre de voyelles n'a pas été atteint, la \
voyelle {} a été ajoutée.".format(self.letters[-1]))
compt_voy += 1
break
l = input('(c)onsonne ou (v)oyelle ? ')
# [:-1] pour échapper le \r, je ne sais pas pourquoi il est là
# on choisi une lettre au pif
if l[:-1] == 'c':
self.letters += consonnes[randrange(0, 19)]
break
elif l[:-1] == 'v':
self.letters += voyelles[randrange(0,5)]
compt_voy +=1
break
else: #si la lettre n'est pas c ou v
print("J'ai dis c ou v")
if __name__ == '__main__':
import time
debut = time.clock()
test = Application(9)
fin = time.clock()
print("Éxécution en {:5.4f}s".format(fin-debut))
#print(test.letters)
#test de vitesse de chargement de Dico()
#import time
#debut = time.clock()
#dico = Dico()
#fin = time.clock()
#print("Le fichier dictionnaire se charge en {:5.4f}s".format(fin-debut))
edit: petite modif + commentaires
Pourquoi il me met des mots en double ?
Je pense que l'on peut allégé le dico, car la plupart des mots font plus de 9 lettres. (+ de 50% des mots). Je comprend bien que ce n'est pas la vitesse qui compte mais l'algo.
Sinon, l'exercice est intéressant, tout comme les idées d'ailleurs.
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles- ♡ Copying is an act of love.
J'ai rajouter la limite de nombre de lettres pour le remplissage du dico
Python3:
# -*- coding:utf-8 -*-
# Algo pour trouver le mot le plus long à partir de n letttres.
from random import randrange
from string import ascii_lowercase
from itertools import combinations
class Dico(object):
"""La classe pour contenir le dictionnaire des mots"""
def __init__(self, nb):
self.dico = []
self.nb = nb # nombre de lettres
def remplissage_dico(self):
# ouverture du fichier
self.f = open("chiffres_lettres_dico.txt", "r")
# boucle pour remplir le dictionnaire
temp_dico = []
word = self.f.readline() #pour sauter la première ligne
letter = 'a' #pour gérer les listes en fonction de la première lettre
while 1:
word = self.f.readline()
if word:
first_letter = word[0]
if first_letter != letter:
self.dico.append(temp_dico)
temp_dico = []
letter = first_letter
else:
#on ne garde que les mots de longueurs<= à ceux que l'on cherche
if len(word[:-1])<=self.nb:
temp_dico.append(word[:-1])
#[:-1] pour virer les caractères de fin de ligne
else:
self.dico.append(temp_dico)
break
# fermeture du fichier
self.f.close()
return self.dico
class PlusLong(object):
"""Classse permettant de trouver le mot le plus long"""
def __init__(self, letters, dico):
# on tranforme letters en liste et on trie
self.letters = list(letters)
self.letters.sort()
self.dico = dico
self.mot_trouve = [] #liste des mots trouvés
def cherche(self):
"""cherche le mot le plus long"""
z = len(self.letters)
# tant qu'on ne trouve pas de mots et qu'on est >= 3 lettres
while not self.mot_trouve and z>=3:
# on essaie les combinaisons possibles de lettres
for m in combinations(self.letters, z):
c = self.compare(m)
z -= 1
print("Les mots les plus longs que l'on peut former avec {} sont : {}"
.format(self.letters, self.mot_trouve))
def compare(self, chaine):
"""""Compare la chaine avec le dico"""
for letter in chaine:
# on choisi le dico commencant par letter
first_letter_dico = self.dico[ascii_lowercase.index(letter)]
for mot in first_letter_dico:
# on vire le trait d'union s'il y en a un
mot = mot.replace("-", "")
# si le mot du dico a la même longueur
# que celui recherché on continue
if len(mot) == len(chaine):
# on transforme mot en liste et on trie
mot_trie = list(mot)
mot_trie.sort()
i = 0
t = True
while i<len(mot):
if mot_trie[i] != chaine[i]:
t = False
i+=1
# si t est toujours vrai on ajoute le mot
if t:
self.mot_trouve.append(mot)
class Application(object):
"""Corps de l'application"""
def __init__(self, nb):
self.letters = ''
self.nb = nb # nombre de lettres
self.choix = self.choix_voy_cons()
self.dico = Dico(self.nb).remplissage_dico()
self.mot_le_plus_long = PlusLong(self.letters, self.dico).cherche()
def choix_voy_cons(self):
consonnes = 'bcdfghjklmnpqrstvwxz'
voyelles = 'aeiouy'
compt_voy = 0 #pour compter les voyelles
for i in range(0, self.nb):
while 1:
# vérifie s'il y a au moins 2 voyelles
if i >= self.nb-2 and compt_voy < 2:
self.letters += voyelles[randrange(0,5)]
print("Le nombre de voyelles n'a pas été atteint, la \
voyelle {} a été ajoutée.".format(self.letters[-1]))
compt_voy += 1
break
l = input('(c)onsonne ou (v)oyelle ? ')
# [:-1] pour échapper le \r, je ne sais pas pourquoi il est là
# on choisi une lettre au pif
if l[:-1] == 'c':
self.letters += consonnes[randrange(0, 19)]
break
elif l[:-1] == 'v':
self.letters += voyelles[randrange(0,5)]
compt_voy +=1
break
else: #si la lettre n'est pas c ou v
print("J'ai dis c ou v")
if __name__ == '__main__':
import time
debut = time.clock()
test = Application(9)
fin = time.clock()
print("Éxécution en {:5.4f}s".format(fin-debut))
Ce sujet commence à dater un peu, mais j'ai fait ça et c'est plutôt rapide je trouve (y'a ptetre une erreur ?) :
#coding: utf8
import random
import time
VOYELLES = ["a", "e", "i", "o", "u", "y"]
CONSONNES = ["b", "c", "d", "f", "g", "h", "j", "k", "l", "m", "n", "p", "q", "r", "s", "t", "v", "w", "x", "z"]
def tirage_lettres_comme_tv(VOYELLES):
nb_lettre = 0
nb_voyelle = 0
liste_lettre = []
while nb_lettre < 9:
choix = raw_input("Consonne ou voyelle ? c ou v (minimum 2 voyelles)").lower()
while choix != "c" and choix != "v":
choix = raw_input("On a dit v ou c").lower()
if choix == "c" and nb_lettre >= 7 and nb_voyelle < 2:
while choix == "c":
choix = raw_input("IL FAUT MINIMUM 2 VOYELLES. Vous n'avez plus le choix : demandez une voyelle.").lower()
if choix == "c":
lettre = random.choice(CONSONNES)
else:
lettre = random.choice(VOYELLES)
nb_voyelle += 1
liste_lettre.append(lettre)
print "lettre tirée : ", lettre
nb_lettre += 1
return liste_lettre
def demander_tirage():
tirage = raw_input('entrez votre tirage').lower()
return tirage
def creation_dictionnaire_ordonne():
with open("dictionnaire.txt", "r") as fichier_dico:
dict_ord_len = {}
for longueur in range(26):
dict_ord_len[longueur+1] = []
while True:
mot = fichier_dico.readline()
if mot == '':
break
mot = mot.strip('\n')
if '-' in mot:
mot = mot.replace('-','')
dict_ord_len[len(mot)].append(mot)
fichier_dico.close()
return dict_ord_len
def trouver_mot_plus_long(longueur_max_mot, dico, tirage):
longueur_mot = longueur_max_mot
solution= []
set_tirage = set(tirage)
while longueur_mot > 0:
for mot in dico[longueur_mot]:
if set(mot).issubset(set_tirage) :
tirage_test = list(tirage)
try:
for lettre in mot:
tirage_test.remove(lettre)
except:
continue
solution.append(mot)
if solution != []:
return solution
longueur_mot -= 1
t_pre_dico = time.time()
dict_ord_len = creation_dictionnaire_ordonne()
time_post_dico = time.time()-t_pre_dico
print 'Le dico a mis ' + str(time_post_dico) +' sc a se charger'
on_joue = True
while on_joue:
tirage = demander_tirage()
t = time.time()
solution = trouver_mot_plus_long(len(tirage), dict_ord_len, tirage)
time_post_solution = time.time()-t
print 'Le script a mis ' + str(time_post_solution) +' sc pour trouver la solution'
print solution
rejouer = raw_input('Rejouer ? Oui/Non')
if rejouer == "non":
on_joue = False
Chez moi : 0.6 sc pour charger le dico
~0.15 sc pour trouver la meilleure combine de 5 lettres
~0.25sc pour trouver la meilleure combine de 10 lettres
~0.5 sc pour trouver la meilleure combine de 17 lettres
× Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
× Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
🍊 - Étudiant - Codeur en C | Zeste de Savoir apprenez avec une communauté | Articles - ♡ Copying is an act of love.