Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Programme] Besoin aide ou développeur

Création d'un programme pour créer des histoires de CP

Sujet résolu
    12 avril 2020 à 22:26:27

    Pour le même test, la durée est passée 2249 ms pour la nouvelle fonction.

    Je fournis les 2 codes à 95 % semblables mais au moins, on peut les lancer à condition d'avoir le fichier /usr/share/dict/french :

    import math
    import time
    
    def produit_des_premiers(mot, correspondance_lettres_nombres_premiers):
        produit = 1
        for lettre in mot:
            produit *= correspondance_lettres_nombres_premiers[lettre]
        return produit
    
    def est_un_nombre_premier(nombre):
        racine_superieure_du_nombre = int(math.sqrt(nombre))
        for i in range(2, racine_superieure_du_nombre):
            if nombre % i == 0:
                return False
        return True
    
    def est_un_anagramme(mot, autre_mot, dictionnaire_des_produits):
        if dictionnaire_des_produits[mot] == dictionnaire_des_produits[autre_mot]:
            return True
        return False
    
    fichier = "/usr/share/dict/french"
    
    lettres = [
        ['a', 'à', 'â', 'ä'],
        'b',
        ['c', 'ç'],
        'd',
        ['e', 'é', 'è', 'ê', 'ë'],
        'f',
        'g',
        'h',
        ['i', 'î', 'ï'],
        'j',
        'k',
        'l',
        'm',
        'n',
        ['o', 'ô', 'ö'],
        'p',
        'q',
        'r',
        's',
        't',    
        ['u', 'ù', 'û', 'ü'],
        'v',    
        'w',
        'x',
        'y',
        'z',
        '-',
        ' ',
        'œ',
        'æ',
        '.',
        "'",
    ]
    
    correspondance_lettres_nombres_premiers = {}
    
    nombres_premiers_26 = []
    compteur = 0
    total = len(lettres)
    nombre = 2
    
    while compteur < total:
        if est_un_nombre_premier(nombre):
            nombres_premiers_26.append(nombre)
            compteur += 1
        nombre += 1
    
    for cle, valeur in zip(lettres, nombres_premiers_26):
        if isinstance(cle, list):
            for i in cle:
                correspondance_lettres_nombres_premiers[i] = valeur
        else:
            correspondance_lettres_nombres_premiers[cle] = valeur
    
    with open(fichier, 'r') as traitement_de_lecture:
        mots = {}
        for ligne in traitement_de_lecture:
            mot = ligne.rstrip()
            produit_mot = produit_des_premiers(mot, correspondance_lettres_nombres_premiers)
            mots[mot] = produit_mot
    
    debut = time.time()
    for _ in range(1500000):
        est_un_anagramme("abaisser", "rabaisse", mots)
    print(f'durée vaut {time.time() - debut}')
    import math
    import time
    
    def produit_des_premiers(mot, correspondance_lettres_nombres_premiers):
        produit = 1
        for lettre in mot:
            produit *= correspondance_lettres_nombres_premiers[lettre]
        return produit
    
    def est_un_nombre_premier(nombre):
        racine_superieure_du_nombre = int(math.sqrt(nombre))
        for i in range(2, racine_superieure_du_nombre):
            if nombre % i == 0:
                return False
        return True
    
    def est_un_anagramme(mot, autre_mot, correspondance_lettres_nombres_premiers, dictionnaire_des_produits):
        produit_mot = produit_des_premiers(mot, correspondance_lettres_nombres_premiers)
        if autre_mot in dictionnaire_des_produits[produit_mot]:
            return True
        return False
    
    def est_un_anagramme2(mot, autre_mot, correspondance_lettres_nombres_premiers):
        if produit_des_premiers(mot, correspondance_lettres_nombres_premiers) == produit_des_premiers(autre_mot, correspondance_lettres_nombres_premiers):
            return True
        return False
    
    fichier = "/usr/share/dict/french"
    
    lettres = [
        ['a', 'à', 'â', 'ä'],
        'b',
        ['c', 'ç'],
        'd',
        ['e', 'é', 'è', 'ê', 'ë'],
        'f',
        'g',
        'h',
        ['i', 'î', 'ï'],
        'j',
        'k',
        'l',
        'm',
        'n',
        ['o', 'ô', 'ö'],
        'p',
        'q',
        'r',
        's',
        't',    
        ['u', 'ù', 'û', 'ü'],
        'v',    
        'w',
        'x',
        'y',
        'z',
        '-',
        ' ',
        'œ',
        'æ',
        '.',
        "'",
    ]
    
    correspondance_lettres_nombres_premiers = {}
    
    nombres_premiers_26 = []
    compteur = 0
    total = len(lettres)
    nombre = 2
    
    while compteur < total:
        if est_un_nombre_premier(nombre):
            nombres_premiers_26.append(nombre)
            compteur += 1
        nombre += 1
    
    for cle, valeur in zip(lettres, nombres_premiers_26):
        if isinstance(cle, list):
            for i in cle:
                correspondance_lettres_nombres_premiers[i] = valeur
        else:
            correspondance_lettres_nombres_premiers[cle] = valeur
    
    with open(fichier, 'r') as traitement_de_lecture:
        anagrammes = {}
        mots = {}
        for ligne in traitement_de_lecture:
            mot = ligne.rstrip()
            produit_mot = produit_des_premiers(mot, correspondance_lettres_nombres_premiers)
            mots[mot] = produit_mot
            anagrammes.setdefault(produit_mot, []).append(mot)
    
    debut = time.time()
    for _ in range(1500000):
        est_un_anagramme2("abaisser", "rabaisse", correspondance_lettres_nombres_premiers)
    print(f'durée vaut {time.time() - debut}')




    • Partager sur Facebook
    • Partager sur Twitter
      12 avril 2020 à 22:51:21

      Passionnante discussion ! Ça donne des idées pour améliorer mon programme d'anagrammes... plus tard.

      En gros, ce que je retiens, c'est qu'il faut modifier la première partie de mon programme. Au lieu de juste créer la liste des mots du fichier, on pourrait ajouter une liste contenant, pour chaque indice i, la liste des mots associés au nombre i, liste qui se construira lors de cette première étape. Cette partie me semble la plus difficile, et je me demande quelle taille aurait cette liste...

      Ensuite, pour chaque mot, le critère serait :

      # mot : mot courant
      # liste_codes : liste des codes. L'élément d'indice i est une liste,
      #               la liste des mots qui ont leur code égal à i.
      if mot in liste_codes[code(mot)] :
          # c'est un anagramme

      (C'est un anagramme à condition que ce ne soit pas le mot lui même, donc que la liste contienne au moins deux mots.)

      -
      Edité par robun 12 avril 2020 à 22:56:40

      • Partager sur Facebook
      • Partager sur Twitter
        13 avril 2020 à 0:47:46

        Voilà, j'ai écrit plusieurs trucs en Python. J'ai plusieurs fonctions pour quelques opérations. Et on peut obtenir les anagrammes de mots/vérifier que deux mots sont anagrammes même s'ils ne sont pas dans le dictionnaire. Je me suis amusé un peu avec la fonction pou calculer la valeur d'un mot. J'ai un générateur pour les nombres premiers et ils sont générés quand il sont nécessaires.

        from operator import mul
        from functools import reduce
        from math import sqrt
        import unicodedata
        
        def prime_gen():
            primes = [2]
            n = 3
            yield 2
            while True:
                l = sqrt(n+1)
                for i in primes:
                    if i &gt;= l:
                        primes.append(n)
                        yield n
                        break
                    if n % i == 0:
                        break
                n += 1
        
        def char_value(c):
            return char_value.dict_value.get(c) or char_value.dict_value.setdefault(c, next(char_value.next_gen))
        char_value.next_gen = prime_gen()
        char_value.dict_value = {}
        
        def normalize_word(s):
            s = unicodedata.normalize('NFD', s).encode('ascii', 'ignore').decode("utf-8")
            return s.lower()
        
        def word_value(s):
            return reduce(mul, map(char_value, normalize_word(s)))
        
        def create_anagrams_hash(lines):
            anagrams_dict = {}
            values_dict = {}
            for w in lines:
                w = w.rstrip()
                v = word_value(w)
                values_dict[w] = v
                anagrams_dict.setdefault(v, []).append(w)
            return (anagrams_dict, values_dict)
        
        def has_anagram(w, anagrams_dict):
            return len(anagrams_dict.get(word_value(w), [])) &gt; 1
        
        def are_anagrams_2(w1, w2):
            return word_value(w1) == word_value(w2)
        
        def are_anagrams_1(w1, w2, values_dict):
            return values_dict.get(w1, word_value(w1)) == values_dict.get(w2, word_value(w2))
        
        def are_anagrams_3(w1, w2, anagrams_dict):
            return w2 in anagrams_dict.get(word_value(w1), [])
        
        def get_anagrams_1(w, anagrams_dict):
            return anagrams_dict.get(word_value(w), [])
        
        def get_anagrams_2(w, anagrams_dict, values_dict):
            return anagrams_dict.get(values_dict.get(w, word_value(w)), [])
        
        def print_anagrams(anagrams_dict, lines):
            for w in lines:
                w = w.rstrip()
                if has_anagram(w, anagrams_dict):
                    print(w, ':', end = ' ')
                    for w1 in get_anagrams_1(w, anagrams_dict):
                        if w1 != w:
                            print(w, end = ' ')
                    print()
        

        J'ai pas fait de test (c'est pas le plus drôle à faire)...

        PS : comme d'habitude, les &lt; à remplacer par < et les &gt; par >.

        -
        Edité par yo@n97one 13 avril 2020 à 0:58:33

        • Partager sur Facebook
        • Partager sur Twitter
        Tutoriel Ruby - Bon tutoriel C - Tutoriel SDL 2 - Python avancé - Faîtes un zeste, devenez des zesteurs

        [Programme] Besoin aide ou développeur

        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
        • Editeur
        • Markdown