IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Contribuez Discussion :

[Sources] Jeu des chiffres et des lettres


Sujet :

Contribuez

  1. #1
    Rédacteur/Modérateur

    Avatar de User
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    8 260
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 8 260
    Points : 19 423
    Points
    19 423
    Billets dans le blog
    63
    Par défaut [Sources] Jeu des chiffres et des lettres
    Titre : Jeu des chiffres et des lettres
    Format du fichier: Access 2000 (utilise une barre de progression)
    Auteur : User

    Intérêt : base de données de plus de 150 000 mots (bd tirés du dico du scrabble disponible sur le net). plus algo de résolution du compte est bon donnant plusieurs solutions détaillées. possibilités d'amélioré ce code...(discussion autour du code).Et biensur tout simplement intérêt ludique


    Description:
    Ce jeu comprend le mot le plus long et le compte est bon.

    Le compte est bon:
    Il existe de nombreuses versions de ce jeu sur le net (en Java, Delphi..).
    Cette version est facile d'utilisation, notamment pour composer les différentes opérations du compte: les résultats intermédiaires étant automatiquement affichés.

    La procédure de recherche des solutions donne plusieurs variantes possibles.

    Le mot le plus long:
    Ce jeu utilise un dictionnaire de plus de 150 mille mots tirés du dico du Scrabble.
    Le tirage des 9 lettres tient compte de la fréquence habituelle d'apparition de chacune des 26 lettres de l'alphabet dans la langue française...

    La formation du mot est très simple: il suffit de cliquer sur les lettres en haut du formulaire, puis on valide son résultat par un simple clique.

    La procédure de recherche des mots les plus longs renvoie de nombreux résultats classés par longueur de mot (8 lettres, 7 lettres...).

    Bon jeu à tous !

    Sources au format Access 2000:
    Jeu des chiffres et des lettres version n°2
    (intègre la méthode de vodiem pour optimiser la recherche des mots les plus longs)

    Jeu des chiffres et des lettres version n°3
    (intègre l'optimisation de philben directement inspirée de celle de vodiem, plus une méthode récursive (non aléatoire) et optimisée de calcul du compte est bon, toujours par philben)

    Jeu des chiffres et des lettres version n°4
    (taille de la base fixe: intègre une methode du calcul du compte est bon non recursive: pour celà utilisation d'une librairie en Delphi, et une brève explication)

    Après téléchargement, décompresser les 2 fichiers "Chiffres_lettres v4.mdb" et "lib_ceb.dll" dans un même répertoire...

    Tirage de 10 lettres pour le mot le plus long:
    Jeu des chiffres et des lettres version n°5
    (intègre la méthode de Vodiem améliorée par Philben pour rechercher le mot le plus long)
    Les verbes conjugués sont à éliminer du dictionnaire.

    Après téléchargement, décompresser les 2 fichiers "Chiffres_lettres v5.mdb" et "lib_ceb.dll" dans un même répertoire...
    Vous trouverez dans la FAQ, les sources ou les tutoriels, de l'information accessible au plus grand nombre, plein de bonnes choses à consulter sans modération

    Des tutoriels pour apprendre à créer des formulaires de planning dans vos applications Access :
    Gestion sur un planning des présences et des absences des employés
    Gestion des rendez-vous sur un calendrier mensuel


    Importer un fichier JSON dans une base de données Access :
    Import Fichier JSON

  2. #2
    Expert confirmé
    Avatar de vodiem
    Homme Profil pro
    Vivre
    Inscrit en
    Avril 2006
    Messages
    2 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Vivre
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2006
    Messages : 2 895
    Points : 4 325
    Points
    4 325
    Par défaut
    Salut User,

    Vraiment sympa,

    je n'ai pas regardé le code pour le compte est bon

    mais pour le mot le plus long:
    je pense qu'il est possible d'obtenir de meilleur temps de réponse, bien que cela soit suffisamment rapide, en créant un index supplémentaire.
    mais peut être au détriment de la lisibilité.

    si tu cherches des idées pour une version 2:
    > inclure un dictionnaire ou un lien sur un site vers une définition (histoire d'être moins bête et de pouvoir le réutiliser le mot )
    > inclure des niveaux: par âge, vocabulaire usuelle/rare... ou thématiques pour orienter le tirage de lettre.
    > paramétrages de la base (délai, alternance du jeu, score, changement de dictionnaire langue étrangère...)
    > améliorer la charte graphique
    > jeu en réseau... lol je plaisante...

    non, c'est vraiment sympa: y a des boutons partout et en plus ils marchent.
    c'est top.

  3. #3
    Rédacteur/Modérateur

    Avatar de User
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    8 260
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 8 260
    Points : 19 423
    Points
    19 423
    Billets dans le blog
    63
    Par défaut
    Merci à toi !

    Je retiens tes idées très interessantes pour une version future...
    (c'est vrai que l'on peut entre autre optimiser le code ..)

    @+

    User
    Vous trouverez dans la FAQ, les sources ou les tutoriels, de l'information accessible au plus grand nombre, plein de bonnes choses à consulter sans modération

    Des tutoriels pour apprendre à créer des formulaires de planning dans vos applications Access :
    Gestion sur un planning des présences et des absences des employés
    Gestion des rendez-vous sur un calendrier mensuel


    Importer un fichier JSON dans une base de données Access :
    Import Fichier JSON

  4. #4
    Expert confirmé

    Homme Profil pro
    consultant développeur
    Inscrit en
    Mai 2005
    Messages
    2 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : consultant développeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 878
    Points : 4 754
    Points
    4 754
    Par défaut
    Bravo, User
    Je trouve cela top moi aussi
    mais aussi que les délais sont un peu trop courts ...pour moi
    "Always look at the bright side of life." Monty Python.

  5. #5
    Expert confirmé

    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 419
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 419
    Points : 4 297
    Points
    4 297
    Par défaut
    bravo !

    toutefois si je puis me permettre:


    la table dico devrait comporter une clef plus fine

    je te propose la méthode suivante

    calculer dans le dictionnaire une clef pour chaque mot cette clef sera composée des lettres formant le mot classées dans l'ordre alphabétique
    évidemment elle sera indexée

    ainsi

    on aura
    mot clef
    CHENI CEHIN
    CHIEN CEHIN
    CHINE CEHIN
    NICHE CEHIN

    dès lors si j'ai au tirage hnice il me suffit de calculer la clef (cehin)et j'ai en lecture directe les 4 résultats dans ma table, les calculs du dico étant faits une fois pour toutes

    je te joins ci dessous une fonction de calcul de clef
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     
    Function creclef(x As String) As String
    Dim boucl1 As Byte
    Dim v1() As Variant
    Dim boucl2 As Byte
    Dim longu As Byte
    Dim tempo As String
    longu = Len(x)
    ReDim v(1 To longu) As Variant
    For boucl1 = 1 To longu
    v(boucl1) = Mid(x, boucl1, 1)
    Next boucl1
    For boucl1 = 1 To longu - 1
        For boucl2 = boucl1 + 1 To longu
            If v(boucl1) > v(boucl2) Then
            tempo = v(boucl1)
            v(boucl1) = v(boucl2)
            v(boucl2) = tempo
            End If
        Next boucl2
    Next boucl1
    tempo = v(1)
    For boucl1 = 2 To longu
    tempo = tempo & v(boucl1)
    Next boucl1
    creclef = tempo
    End Function
    qu'en penses tu ?
    Elle est pas belle la vie ?

  6. #6
    Expert confirmé
    Avatar de vodiem
    Homme Profil pro
    Vivre
    Inscrit en
    Avril 2006
    Messages
    2 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Vivre
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2006
    Messages : 2 895
    Points : 4 325
    Points
    4 325
    Par défaut
    salut User, micniv et random,

    j'ai eu le même réflexe que toi random et j'avais donc fait ce code pour obtenir cette même "clef":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Function creerMotif(champ As String) As String
    Dim a(25) As Byte
     
    For i = 1 To Len(champ)
        c = Asc(Mid(champ, i, 1)) - 65
        a(c) = a(c) + 1
    Next i
    For i = 0 To 25
        For j = 1 To a(i)
            s = s + Chr(i + 65)
        Next j
    Next i
    creerMotif = s
    End Function
    mais cela n'est pas suffisant pour rendre plus rapide le traitement.
    jusqu'à présent je suis parvenu à vu d'œil presque 2 fois plus vite, sans lunette et un œil fermé.
    j'entrevoie encore une piste qui pourrait améliorer significativement encore ce temps.


  7. #7
    Expert confirmé

    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 419
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 419
    Points : 4 297
    Points
    4 297
    Par défaut
    vodiem si je puis me permettre il ne faut pas transposer la clef en numérique (calcul conversion) mais conserver une clef alpha

    d'autre part il faut ajouter la clef à dico

    reste à traiter tirage et ses descendants

    pour cela il suffit de calculer clef(tirage)
    si clef(tirage) n'offre pas de solution
    si clef(tirage) n'offre pas de solution
    itérer
    enlever une lettre de clef(tirage)
    et réessayer avec les combinaisons ainsi trouvées
    le résultat devrait être instantané
    Elle est pas belle la vie ?

  8. #8
    Expert confirmé
    Avatar de vodiem
    Homme Profil pro
    Vivre
    Inscrit en
    Avril 2006
    Messages
    2 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Vivre
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2006
    Messages : 2 895
    Points : 4 325
    Points
    4 325
    Par défaut
    Citation Envoyé par random
    vodiem si je puis me permettre il ne faut pas transposer la clef en numérique (calcul conversion) mais conserver une clef alpha
    je suis d'accord avec toi: ma fonction renvoie un string.

    Citation Envoyé par random
    d'autre part il faut ajouter la clef à dico
    toujours d'accord avec toi.

    Citation Envoyé par random
    pour cela il suffit de calculer clef(tirage)
    si clef(tirage) n'offre pas de solution
    si clef(tirage) n'offre pas de solution
    itérer
    enlever une lettre de clef(tirage)
    et réessayer avec les combinaisons ainsi trouvées
    le résultat devrait être instantané
    c'est là le truc:
    enlever une lettre oui mais laquelle?
    il faut donc faire un test sur 2^9=512 combinaisons possibles réduit à nb clef(combinaison(tirage)) distinct.
    donc savoir si clef(dico.mot) appartient à clef(combinaison(tirage)) distinct.
    et là selon comment on s'y prend le résultat est parfois très loin d'être instantané.


  9. #9
    Rédacteur/Modérateur

    Avatar de User
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    8 260
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 8 260
    Points : 19 423
    Points
    19 423
    Billets dans le blog
    63
    Par défaut
    merci à vous !

    Donc j'attends un peu avant d'appliquer votre conseil d'une meilleure clé...

    Si je n'ai pas de retour avant ce soir j'incorpore le code de vodiem dans ma base...

    encore merci à vous !
    Vous trouverez dans la FAQ, les sources ou les tutoriels, de l'information accessible au plus grand nombre, plein de bonnes choses à consulter sans modération

    Des tutoriels pour apprendre à créer des formulaires de planning dans vos applications Access :
    Gestion sur un planning des présences et des absences des employés
    Gestion des rendez-vous sur un calendrier mensuel


    Importer un fichier JSON dans une base de données Access :
    Import Fichier JSON

  10. #10
    Rédacteur/Modérateur

    Avatar de User
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    8 260
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 8 260
    Points : 19 423
    Points
    19 423
    Billets dans le blog
    63
    Par défaut Merci !
    Merci Random et Vodiem pour votre contribution...

    Je vais essayer d'appliquer votre méthode mais c'est vrai que c'est pas évident...

    @+
    Vous trouverez dans la FAQ, les sources ou les tutoriels, de l'information accessible au plus grand nombre, plein de bonnes choses à consulter sans modération

    Des tutoriels pour apprendre à créer des formulaires de planning dans vos applications Access :
    Gestion sur un planning des présences et des absences des employés
    Gestion des rendez-vous sur un calendrier mensuel


    Importer un fichier JSON dans une base de données Access :
    Import Fichier JSON

  11. #11
    Rédacteur/Modérateur

    Avatar de User
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    8 260
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 8 260
    Points : 19 423
    Points
    19 423
    Billets dans le blog
    63
    Par défaut
    En fait je suis parvenu a environ 1 seconde en changeant un peu le motif et en utilisant un like dans la procedure...

    en faisant:

    Tirage_classé like motif

    ou tirage est par exemple "ABCDEFGHI" et

    motif du style "*C*E*F*H*I*" pour "FICHE"

    mais la base de données est 2 fois plus grosse

    Dernière minute : méthode remplacée par celle de vodiem...

    Des chiffres et des lettres version n°2

    @+
    Vous trouverez dans la FAQ, les sources ou les tutoriels, de l'information accessible au plus grand nombre, plein de bonnes choses à consulter sans modération

    Des tutoriels pour apprendre à créer des formulaires de planning dans vos applications Access :
    Gestion sur un planning des présences et des absences des employés
    Gestion des rendez-vous sur un calendrier mensuel


    Importer un fichier JSON dans une base de données Access :
    Import Fichier JSON

  12. #12
    Expert confirmé
    Avatar de vodiem
    Homme Profil pro
    Vivre
    Inscrit en
    Avril 2006
    Messages
    2 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Vivre
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2006
    Messages : 2 895
    Points : 4 325
    Points
    4 325
    Par défaut
    Tu m'impressionnes User environ: 1s... c'est pas facile de l'atteindre.

    moi, je suis parvenu à avoir presque l'instantané: <1s :p
    voilà mon code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    Option Compare Database
    Option Base 0
     
    Function creerMotif(champ As String) As String
    Dim a(25) As Byte
     
    For i = 1 To Len(champ)
        c = Asc(Mid(champ, i, 1)) - 65
        a(c) = a(c) + 1
    Next i
    For i = 0 To 25
        For j = 1 To a(i)
            s = s + Chr(i + 65)
        Next j
    Next i
    creerMotif = s
    End Function
     
    Function genCombinaison(chaine As String) As String()
    Dim t() As String
    Dim i As Long
    Dim j As Long
     
    n = Len(chaine)
    m = 2 ^ n
    ReDim t(m - 1)
     
    For i = 0 To m - 1
        mx = n - 1    'max pour éviter des décalages inutiles il faudrait: log base 2 +1
        For j = 0 To mx
            s = s + Mid(chaine, j + 1, SHR(i, j) And 1)
        Next j
        t(i) = s
        s = vbNullString
    Next i
    genCombinaison = t
    End Function
     
    Function genCombinaison2(chaine As String) As String()  'renvoie un tableau de motif
    Dim t() As String
    Dim i As Long
    Dim j As Long
    Dim s As String
     
    n = Len(chaine)
    m = 2 ^ n
    ReDim t(m - 1)
     
    For i = 0 To m - 1
        mx = n - 1    'max pour éviter des décalages inutiles il faudrait: log base 2 +1
        For j = 0 To mx
            s = s + Mid(chaine, j + 1, SHR(i, j) And 1)
        Next j
        t(i) = creerMotif(s)
        s = vbNullString
    Next i
    genCombinaison2 = t
    End Function
     
    Sub AfficheSolus(Tirage As String)
    Dim mt() As String
    mt() = genCombinaison2(Tirage)
     
    DoCmd.SetWarnings False
    DoCmd.RunSQL "delete * from combinaison"
    Dim rs As DAO.Recordset
    Set rs = CurrentDb.OpenRecordset("combinaison", dbOpenDynaset)
    For i = 1 To UBound(mt)
        rs.AddNew
        rs!motif = mt(i - 1)
        rs.Update
    Next i
    DoCmd.SetWarnings True
    rs.Close
     
    leSQL = "SELECT t1.mot, len(t1.mot) AS taille " & _
            "FROM dico AS t1 " & _
            "WHERE EXISTS (select t2.motif from combinaison t2 where t2.motif=t1.motif) " & _
            "ORDER BY len(t1.mot) DESC , t1.mot;"
     
    Set rs = CurrentDb.OpenRecordset(leSQL, dbOpenSnapshot)
     
    While Not rs.EOF
        Debug.Print rs!mot, rs!taille
        rs.MoveNext
    Wend
    End Sub
    .genCombinaison() est là en plus et n'est pas utilisé.
    .il faut rajouter une table combinaison avec un champ <motif> indexé
    .avoir [dico] avec un motif "normal"
    .tu n'as pas de doublement, au plus un "surplus" dû au champ <motif>
    .AfficheSolus() ne limite pas le nb de solus, il est possible qu'en adaptant tu puisse encore gagner qq milli seconde...

    j'allais oublier SHR():
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Function SHR(y As Long, k As Long) As Long ' shr(octet ,nombre de décalage)
    SHR = CLng(Int(y / (2 ^ k)))
    End Function
    je te laisse le soin de l'adapter à ton bébé.

    ps: micniv, si ca peut te rassurer: même avec des délais plus long j'ai du mal à trouver de mots de plus de trois lettres. lol


  13. #13
    Rédacteur/Modérateur

    Avatar de User
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    8 260
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 8 260
    Points : 19 423
    Points
    19 423
    Billets dans le blog
    63
    Par défaut
    Impresssionnant !

    je l'intègre de ce pas à la version n°2...

    Encore merci !
    Vous trouverez dans la FAQ, les sources ou les tutoriels, de l'information accessible au plus grand nombre, plein de bonnes choses à consulter sans modération

    Des tutoriels pour apprendre à créer des formulaires de planning dans vos applications Access :
    Gestion sur un planning des présences et des absences des employés
    Gestion des rendez-vous sur un calendrier mensuel


    Importer un fichier JSON dans une base de données Access :
    Import Fichier JSON

  14. #14
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2006
    Messages
    1 399
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 399
    Points : 2 221
    Points
    2 221
    Par défaut
    bonjour,

    mon ami Vodiem a proposé une excellente solution qui mérite seulement une petite optimisation de la requête utilisée.

    En effet la clause Where proposée n'est pas optimisable par un index sur la colonne <motif> de la table <dico>.

    La requête nommée <RqMots> suivante associée à un index avec doublons sur la colonne <motif> permet d'obtenir pratiquement un affichage instantané d'après mes essais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    SELECT DISTINCT D.mot
    FROM combinaison AS C INNER JOIN dico AS D ON C.motif=D.motif;
    Pas besoin d'indexer la colonne <motif> de la table combinaison.

    J'en ai profité pour modifier le code de la fonction <generer_resultats> optimisée pour notre cas (tirage de 9 lettres) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
     
    Public Function generer_resultats(ByVal Tirage As String)
       Dim oDb As DAO.Database, oRs As DAO.Recordset
       Dim i As Integer, j As Integer
       Dim asLettres(0 To 8) As String, tb_str(2 To 9) As String, s As String
     
       DoCmd.Hourglass True
     
       Set oDb = CurrentDb
     
       'supprime les éventuelles anciennes combinaisons
       oDb.Execute "DELETE FROM Combinaison", dbFailOnError
       Set oRs = oDb.OpenRecordset("Combinaison", dbOpenDynaset)
     
       'Créer un tableau des lettres du tirage
       For i = 0 To 8
          asLettres(i) = Mid$(Tirage, i + 1, 1)
       Next i
     
       'Trier ce tableau par ordre croissant pour respecter le motif de la table dico
       TriLettres asLettres
     
       'Génère 502 motifs (motifs de 1 lettre ne sont pas conservés) par une fonction récursive
       For i = 1 To 8
          GenereMotifs oRs, asLettres, asLettres(i - 1), i
       Next i
     
       'suite du code standard...
     
       Set oRs = oDb.OpenRecordset("RqMots", dbOpenForwardOnly)
       Do Until oRs.EOF
          tb_str(Len(oRs!mot)) = tb_str(Len(oRs!mot)) & oRs!mot & " "
          oRs.MoveNext
       Loop
     
       j = 1
     
       For i = 9 To 2 Step -1
          If tb_str(i) <> vbNullString Then
             s = s & "Mots de " & i & " lettres:" & vbCrLf
             s = s & tb_str(i) & vbCrLf & vbCrLf
             j = j + 1
             If j > 3 Then Exit For
          End If
       Next i
     
       Forms!Mot_plus_long!Solutions = s
     
       Set oRs = Nothing
       Set oDb = Nothing
     
       DoCmd.Hourglass False
     
    End Function
    les deux fonctions secondaires :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
     
    'Fonction récursive pour générer les motifs
    Private Sub GenereMotifs(ByRef oRs As DAO.Recordset, ByRef asLettres() As String, _
                             ByVal sBase As String, ByVal iCurLettre As Integer)
       Dim i As Integer
       For i = iCurLettre To 7
          oRs.AddNew
          oRs!motif = sBase & asLettres(i)
          oRs.Update
          GenereMotifs oRs, asLettres, sBase & asLettres(i), i + 1
       Next i
       oRs.AddNew
       oRs!motif = sBase & asLettres(i)
       oRs.Update
    End Sub
     
    'Tri croissant d'un tableau de string de 0 à 8 => iInc = 13
    Private Sub TriLettres(ByRef asTab() As String)
       Dim i As Integer, j As Integer, iInc As Integer
       Dim sLettre As String * 1
     
       iInc = 13   'car tableau de base 0 et ubound = 8
       While iInc > 1
          iInc = iInc / 3
          For i = iInc To 8
             j = i
             sLettre = asTab(i)
             Do While sLettre < asTab(j - iInc)
                asTab(j) = asTab(j - iInc)
                j = j - iInc
                If j < iInc Then Exit Do
             Loop
             asTab(j) = sLettre
          Next i
       Wend
    End Sub
    Pour réduire la taille de la base, on peut éventuellement enlever la clef primaire sur les mots qui n'est utile, je pense, que si on souhaite ajouter des nouveaux mots.
    On peut aussi générer à la volée les index nécessaires au démarrage du programme.

    Voilà, à vérifier que tout fonctionne bien , et humbles félicitations à User et Vodiem .

    Philippe

  15. #15
    Expert confirmé
    Avatar de vodiem
    Homme Profil pro
    Vivre
    Inscrit en
    Avril 2006
    Messages
    2 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Vivre
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2006
    Messages : 2 895
    Points : 4 325
    Points
    4 325
    Par défaut
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    SELECT DISTINCT D.mot
    FROM combinaison AS C INNER JOIN dico AS D ON C.motif=D.motif;


    nan, j'y crois pas! l'INNER JOIN me "plantait" très souvent et m'avait planté sur ce SQL . je lui ai donc préféré un LEFT JOIN et j'avais donc un piste avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    SELECT DISTINCT t2.mot, len(t2.mot) AS taille
    FROM combinaison AS t1 LEFT JOIN dico AS t2 ON t1.motif = t2.motif
    ORDER BY len(t2.mot) DESC , t2.mot;
    moins performant qu'avec la clause EXISTS et IN
    cela dit après zieutage je ne décèle pas de différence de temps entre la requête que tu as choisi et celle que j'ai choisi.
    s'il y a, vous m'excuserez alors d'avoir une mauvaise vue.

    les deux fonctions creerMotif et genCombinaison peuvent être surement optimisé comme l'a fait notre Excellence philben.

    les temps sont trop court pour ma vue.
    il faudrait pouvoir les regarder avec un compteur de temps.

    bien que très respectueux de ton travail, je reste perplexe sur le gain de la récursivité du générateur.
    je crois que le plus performant serait un tableau de constante prédéfini auquel on appliquerait un ET logique pour obtenir un masquage des lettres et où l'on retirerait/ne mettrait pas les lettres vides.

    User tu vas devoir de toute façon faire un comparatif des fonctions avant de les intégrer. pourras tu nous faire connaitre les résultats?
    non pas que je remettes en cause les compétences de notre cher philben mais cela lèverait certain de mes aprioris.

    une piste que j'avais aussi entrevue et qui évite le champ <motif> et donc une taille de la base plus importante, était d'avoir une fonction qui renverrait oui/non si le motif généré avec le mot faisait parti d'un tableau de combinaison de motif préalablement chargé en mémoire.
    on appellerait cette fonction dans une simple requete:
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    select mot from dico where estSolus(mot)
    je n'ai pas exploré plus profondément la question.

    merci philben pour ta participation et ta sérieuse contribution


  16. #16
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2006
    Messages
    1 399
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 399
    Points : 2 221
    Points
    2 221
    Par défaut
    salut Vodiem,

    cela dit après zieutage je ne décèle pas de différence de temps entre la requête que tu as choisi et celle que j'ai choisi.
    Voilà ce que c'est d'avoir un ordi de course...
    Pour ma part avec ma vieille casserole, j'obtiens un gain global d'un facteur 10 soit un passage de plus d'une seconde à 115 ms d'après GetTickCount.
    Cette différence s'explique essentiellement par l'utilisation de l'index.

    je reste perplexe sur le gain de la récursivité du générateur
    Globalement cette partie du code n'a pas ou peu d'impact sur le temps total. Toujours sur ma casserole, je note un gain d'un facteur entre 1,5 et 2.

    Ceci n'enlève rien à la qualité de ton code et du principe que tu as élaboré.
    Je serai heureux de voir le joli Puissance4 que tu vas créer

    Encore Bravo Vodiem et remerciement à Random pour son idée ingénieuse de motif avec lettres ordonnées.

    A+

    Philippe

  17. #17
    Expert confirmé
    Avatar de vodiem
    Homme Profil pro
    Vivre
    Inscrit en
    Avril 2006
    Messages
    2 895
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Vivre
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2006
    Messages : 2 895
    Points : 4 325
    Points
    4 325
    Par défaut
    après mon cambriolage j'ai dû ressouder une ancienne carte mère l'opération à durée 1/2 journée et je lui ai greffé un peu de ram. après l'opération Frankenstein overclocké est reconnu par windows comme: sempron 2500+, 576 ram avec ses 10Go de HDD.

    facteur 10? +d'1s à qq ms...
    il faut que je regarde cela de plus près, je n'observe pas une différence aussi importante. il serait temps que je porte mes lunettes, râaa... zut: ca aussi ils me l'ont piqué!. y aurait il des différences aussi importante selon le matériel?

    Citation Envoyé par philben
    Je serai heureux de voir le joli Puissance4 que tu vas créer
    joli peut être, soigné surement, fonctionnelle c'est autre chose...
    pour ce qui est du jeu, c'est comme le mot le plus long: j'ai du mal à aligner plus de trois lettres alors 4...
    j'ai hâte de voir jusqu'où tu as mis la barre, toi qui a déjà fait un tétris...

    merci pour la requete, je suis un peu surpris ce n'est pas la première fois qu'access me fait des tours de cochon et me laisse croire à certain aprioris.
    merci philben de les remettre en cause.

    merci aussi à random, initiateur du débat.

    on attend le feedback User.

  18. #18
    Rédacteur/Modérateur

    Avatar de User
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    8 260
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 8 260
    Points : 19 423
    Points
    19 423
    Billets dans le blog
    63
    Par défaut
    Désolé pour le retard,

    Bravo philben pour cette optimisation, que dis-je a ce niveau j'ai l'impression d'avoir une Ferrari entre les mains

    philben
    Crée une requête séparée "compilée" RqMots, éliminer les "mots" < 2 lettres
    remplire directement la table combinaison...
    et j'en passe tout cela semble bien améliorer les choses..

    (le tri de vodiem semblait toute fois intéressant)

    Tout ceci ne fait que confirmer la valeur de la méthode de vodiem que vous trouverez toujours en version n°2

    Ta version philben est en n°3

    J'ai supprimée la version n°1

    Merci encore à vous deux !
    Vous trouverez dans la FAQ, les sources ou les tutoriels, de l'information accessible au plus grand nombre, plein de bonnes choses à consulter sans modération

    Des tutoriels pour apprendre à créer des formulaires de planning dans vos applications Access :
    Gestion sur un planning des présences et des absences des employés
    Gestion des rendez-vous sur un calendrier mensuel


    Importer un fichier JSON dans une base de données Access :
    Import Fichier JSON

  19. #19
    Membre chevronné

    Profil pro
    Inscrit en
    Avril 2006
    Messages
    1 399
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 1 399
    Points : 2 221
    Points
    2 221
    Par défaut
    Bonjour,

    Comme la BAL de User est pleine, je me permet d'envoyer mon message ici :

    bonjour User,

    je tenais à m'excuser pour le boulot supplémentaire que je t'ai occasionné, mais j'aime bien chamailler mon ami Vodiem

    Je suis aussi très heureux de ton retour sur le forum.

    Encore Bravo pour ton application

    Amicalement,

    Philippe

  20. #20
    Rédacteur/Modérateur

    Avatar de User
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    8 260
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2004
    Messages : 8 260
    Points : 19 423
    Points
    19 423
    Billets dans le blog
    63
    Par défaut
    Une nouvelle version avec le sql

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    where motif In (l_motifs)
    ca evite la table combinaison et l'ajout des combinaison dans cette table et donc la base reste fixe et la vitesse est comparable

    création de la liste des motifs a partir du tirage:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    Function genCombinaison(chaine As String) As String  'renvoie une liste de motifs
    Dim str As String
    Dim i As Long
    Dim j As Long
    Dim s As String
    Dim n As Integer, mx As Integer
     
    n = Len(chaine)
    m = 2 ^ n
    chaine = creerMotif(chaine)
     
    str = vbNullString
     
    For i = 1 To m
        mx = n - 1    'max pour éviter des décalages inutiles il faudrait: log base 2 +1
        For j = 0 To mx
            s = s + Mid(chaine, j + 1, SHR(i, j) And 1)
        Next j
        If Len(s) > 1 Then
           str = str & Chr(39) & s & Chr(39) & ","
        end if
        s = vbNullString
    Next i
    genCombinaison = str
    End Function
    et la procedure principale:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    Public Function generer_resultats2(ByVal Tirage As String)
       Dim oDb As DAO.Database, oRs As DAO.Recordset
       Dim i As Integer, j As Integer, l_motifs As String, sql_mots As String
       Dim tb_str(2 To 9) As String, s As String
     
       DoCmd.Hourglass True
     
       Set oDb = CurrentDb
     
       l_motifs = genCombinaison(Tirage)
     
       l_motifs = Left(l_motifs, Len(l_motifs) - 1)
     
       sql_mots = "SELECT mot " & _
       "FROM dico " & _
       "WHERE motif In (" & l_motifs & ");"
     
       Set oRs = oDb.OpenRecordset(sql_mots, dbOpenForwardOnly)
       Do Until oRs.EOF
          tb_str(Len(oRs!mot)) = tb_str(Len(oRs!mot)) & oRs!mot & " "
          oRs.MoveNext
       Loop
     
       j = 1
     
       For i = 9 To 2 Step -1
          If tb_str(i) <> vbNullString Then
             s = s & "Mots de " & i & " lettres:" & vbCrLf
             s = s & tb_str(i) & vbCrLf & vbCrLf
             j = j + 1
             If j > 3 Then Exit For
          End If
       Next i
     
       Forms!Mot_plus_long!Solutions = s
     
       Set oRs = Nothing
       Set oDb = Nothing
     
       DoCmd.Hourglass False
     
    End Function
    version n°4


    merci Philben pour ton accueil
    Vous trouverez dans la FAQ, les sources ou les tutoriels, de l'information accessible au plus grand nombre, plein de bonnes choses à consulter sans modération

    Des tutoriels pour apprendre à créer des formulaires de planning dans vos applications Access :
    Gestion sur un planning des présences et des absences des employés
    Gestion des rendez-vous sur un calendrier mensuel


    Importer un fichier JSON dans une base de données Access :
    Import Fichier JSON

Discussions similaires

  1. Simuler le jeu des chiffres et des lettres
    Par iMech dans le forum C
    Réponses: 21
    Dernier message: 12/12/2014, 10h23
  2. Le jeu des chiffres et des lettres
    Par shayw dans le forum Contribuez
    Réponses: 0
    Dernier message: 22/05/2014, 22h56
  3. Ecrire des chiffres en toutes lettres
    Par ali_Imouzzer dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 21/02/2007, 18h44
  4. remplacer des chiffres par des lettres, & vis versa
    Par Argorate dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 16/08/2006, 19h36

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo