Méthode programmation chiffres/lettres

Résolu/Fermé
Odenelle Messages postés 102 Date d'inscription samedi 19 novembre 2011 Statut Membre Dernière intervention 18 mars 2016 - 21 nov. 2011 à 20:42
Katido Messages postés 1 Date d'inscription lundi 18 février 2013 Statut Membre Dernière intervention 18 février 2013 - 18 févr. 2013 à 15:46
Bonjour a tous,

Ayant commencé le java depuis quelques mois, je tente aujourd'hui de perfectionner ma méthode, et pour cela je me lance des petits défis.

Celui qui je me suis lancé est le suivant :

Inspiré du jeu 'des chiffres et des lettres', je souhaiterai écrire un programme qui quand on lui donne en entrée plusieurs entiers et un résultat, il calcule ce résultat en utilisant chaque entier et en les additionnant, multipliant, soustractionnant ou divisant entre eux. En clair un programme qui exécute le raisonnement d'un candidat dans 'des chiffres et des lettres' lors d'une épreuve, a l'exception près que le programme affiche le calcul uniquement si le compte est bon, et que chaque chiffre est utilisé.

La conception de ce programme s'avère je crois complexe et j'aurai donc besoin de méthode ou d'astuces mathématiques si certains se sentent le courage de l'attaquer, de donner une idée de structure. En algorithmique, la fonction ressemblerait a cela, et devrait retourner toutes les étapes de calcul :

fonction chiffres ( A entier, B entier, C entier, D entier, E entier, F entier, G entier, res entier ) entier




et dans le main :

resultat=chiffres (a,b,c,d,e,f,g,result)


Avez vous des idées pour réussir cela ? Merci d'avance.

3 réponses

KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
21 nov. 2011 à 21:25
Le nombre de possibilité est extrêmement important et il est in-envisageable de les itérer toutes, il faudrait je pense que tu ais des bases d'intelligence artificielle, et si tu débutes en Java ça me parait assez compliqué...

Mais bon, je te conseilles d'oublier la partie "chaque chiffre est utilisé", ce n'est pas vraiment un problème. De plus je modifierai ta fonction chiffres pour s'adapter à un appel récursif.

Je préconiserai plutôt une méthode chiffres(int resultat, int...entiers) ça permettrait d'avoir un nombre de paramètres variables et par exemple de faire :

chiffres(15,1,2,3,4) = 2+chiffres(13,2,3,4) = 2+(1+chiffres(12,3,4)) = 2+(1+(4*chiffres(3,3)) = 2+(1+(4*(3*chiffres(1))) = 2+(1+(4*(3)))

Remarque 1 : ici j'ai terminé en remplaçant chiffres(1) par 1 mais on pourrait également envisager de remplacer chiffres(0) par 0 pour permettre une addition à la fin.

Remarque 2 : dans l'exemple j'ai mis tous les opérateurs devant mais on pourrait également envisager de le mettre en interne : chiffres(15,1,2,3,4) = chiffres(15,1+2,3*4) = chiffres(15,1+2+3*4)
1
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
22 nov. 2011 à 13:16
En énumérant tous les cas possibles voici ce que ça pourrait donner (je me limite à + et -)
On a 1, 3 et 8. On cherche tous les résultats possibles (bête et méchant)

Pas 0 : ("",1,3,8)

Pas 1 : 
("1+3=4",8,4), ("1+8=9",3,9), ("3+1=4",8,4), ("3+8=11",1,11), ("8+1=9",3,9), ("8+3=11",1,11)

("1-3=-2",8,-2), ("1-8=-7",3,-7), ("3-1=2",8,2), ("3-8=-5",1,-5), ("8-1=7",3,7), ("8-3=5",1,5)

Pas 2 
("1+3=4, 8+4=12",12), ("1+8=9, 3+9=12",12), ("3+1=4, 8+4=12",12),
("3+8=11, 1+11=12",12), ("8+1=9, 3+9=12",12), ("8+3=11, 1+11=12",12),
("1-3=-2, 8+(-2)=6",6), ("1-8=-7, 3+(-7)=-4",-4), ("3-1=2, 8+2=10",10),
("3-8=-5, 1+(-5)=-5",-4), ("8-1=7, 3+7=10",10), ("8-3=5, 1+5=6",6),
("1+3=4, 4+8=12",12), ("1+8=9, 9+3=12",12), ("3+1=4, 4+8=12",12),
("3+8=11, 11+1=12",12), ("8+1=9, 9+3=12"), ("8+3=11, 11+1=12",12),
("1-3=-2, (-2)+8=6",6), ("1-8=-7, (-7)+3=-4",-4), ("3-1=2, 2+8=10",10),
("3-8=-5, (-5)+1=-5",-4), ("8-1=7, 7+3=10",10), ("8-3=5, 5+1=6",6), 

("1+3=4, 8-4=4",4), ("1+8=9, 3-9=-6",-6), ("3+1=4, 8-4=4",4),
("3+8=11, 1-11=-10",-10), ("8+1=9, 3-9=-6",-6), ("8+3=11, 1-11=-10",-10),
("1-3=-2, 8-(-2)=10",10), ("1-8=-7, 3-(-7)=10",10), ("3-1=2, 8-2=6",6),
("3-8=-5, 1-(-5)=6",6), ("8-1=7, 3-7=-4",-4), ("8-3=5, 1-5=-4",-4),
("1+3=4, 4-8=-4",-4), ("1+8=9, 9-3=6",6), ("3+1=4, 4-8=-4",-4),
("3+8=11, 11-1=10",10), ("8+1=9, 9-3=6"), ("8+3=11, 11-1=10",10),
("1-3=-2, (-2)-8=-10",-10), ("1-8=-7, (-7)-3=-10",-10), ("3-1=2, 2-8=-6",-6),
("3-8=-5, (-5)-1=-6",-6), ("8-1=7, 7-3=4",4), ("8-3=5, 5-1=4",4)

Remarques :
1) il y a énormément de cas possibles, et ça augmente très vite. Là j'ai 3 chiffres et 2 opérations toi tu veux 8 chiffres et 4 opérations !!

2) il y a beaucoup de doublons, mais ça peut se gérer à différents niveaux :
en amont -> ne pas distinguer les cas a+b et b+a (pareil pour a*b)
en aval -> supprimer les résultats partiels qui sont en double : avec les même chiffres de départs, ou négatifs : c=a-b<0 ne pourra être utilisé qu'avec d-c>0, c'est donc pareil que faire (d-a)+b

Du coup les solutions restantes sont moins nombreuses (je te laisse voir lesquels c'est ^^)

3) ici je n'ai pas précisé la valeur que je cherchais, il est évident que dès qu'on la trouve on s'arrête (du coup il n'est pas nécessaire de se limiter à prendre tous les chiffres). Et si on énumère tout parce qu'on n'a pas trouvé la bonne valeur on peut quand même déterminer la valeur "la plus proche".

4) je ne dis pas que ma méthode est la meilleure, loin de là, mais c'est la seule que j'ai pour l'instant, et à mon avis tu peux t'en sortir comme ça.

5) cette méthode fonctionne quel que soit le nombre de chiffres donnés au départ, par contre ne lance pas tout de suite la recherche avec 8 chiffres car ça va surement ramer --'
0
Odenelle Messages postés 102 Date d'inscription samedi 19 novembre 2011 Statut Membre Dernière intervention 18 mars 2016 20
23 nov. 2011 à 10:57
Mes excuses pour mon temps à répondre.

En effet la programmation s'avère compliquée, néanmoins ta méthode me semble être en effet une des plus efficace !
J'en ai parlé à plusieurs amis étudiants, certains pensaient utiliser le modulo entre chaque nombre ou encore énumérer tous les calculs possible à l'aide de boucle ( comme toi si j'ai bien tout compris...)

Je vais parler a mon prof d'algorithmique sur ce sujet, il travaille justement dans l'intelligence artificielle, voir s'il a une idée sur le sujet :)

Par ailleurs j'ai pu constater ne pas être le seul a vouloir programmer ce genre de chose ( http://j.mochel.free.fr/comptebon.php ; http://mamisab.chez-alice.fr/ ) et je pense que l'exercice bien que complexe sera assez instructif pour moi ! Je vais tenter de coder tout ça prochainement...
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
23 nov. 2011 à 11:12
Il faudrait regarder en effet l'énumération parce que même si l'explosion combinatoire est très importante, toi a priori tu ne vas vouloir aller que jusqu'à n=8 donc ça peux peut-être se faire en temps raisonnable. Au pire, tu peux te placer dans les même conditions qu'à la télé. Et imposer qu'au bout de 20 ou 30 secondes (je ne sais pas à combien de temps les candidats ont droit) le programme te donne la meilleure qu'il a trouvé. Même s'il n'a pas le bon compte (qui n'est pas toujours possible) il pourrait quand même avoir trouvé une solution approchée pas trop mauvaise.
Côté intelligence artificielle je vois difficilement comment s'en sortir, parce le comportement des opérateurs * et + par exemple conduisent à deux voisins très éloignés dans l'espace de solutions et je ne vois pas comment diriger la recherche judicieusement. De toute façon cela t'amènerai surement à manipuler des connaissances que tu n'ais pas encore prêt à comprendre ^^
Après bien sûr il y en a d'autres qui ont déjà fait ce genre de choses, mais regarder ce qu'ils ont fait est peut-être moins intéressant que trouver une méthode par toi même, moi j'ai donné l'idée sur laquelle d'instinct je partirai en premier, je n'ai jamais dit que c'était la meilleure ;-)
0
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
2 déc. 2011 à 20:06
Bonsoir,

J'ai eu un peu de temps cet après-midi et je me suis amusé à faire le code de ton programme.
Alors bonne nouvelle : le temps de calcul est moins important que ce que je pensais, parce qu'en fait il trouve tout le temps une solution. Je mets donc 2 ou 3 secondes maximum avec les 8 chiffres et les 4 opérations. Si vraiment la solution n'existe pas alors dans ce cas ça va ramer et il faut l'arrêter au bout de 45 secondes pour lui demander le mieux qu'il a trouvé...
C'est donc de la force brute avec une méthode d'exploration quasiment identique à celle que j'ai expliqué sur l'exemple. Je n'ai pas mis en place toutes les précautions dont je parlais pour optimiser le programme, ce ne serait vraiment intéressant que lorsque la solution n'existe pas.

Remarque : les calculs de mon programme ne sont pas très humains parce qu'il prend les chiffres de gauche à droite et essaye de faire au mieux comme ça, et puisqu'il trouve le bon compte, il ne cherche pas de solutions plus simples, même si on pourrait l'améliorer dans ce sens ;-)

Exemple : faire 500 avec 100,8,75,3,4,9,6,3.
Humain : 9-4=5, 5*100=500.
Ordinateur : 100+8=108, 108+75=183, 183+3=186, 186*3=558, 558-4=554, 9*6=54, 554-54=500
0
Katido Messages postés 1 Date d'inscription lundi 18 février 2013 Statut Membre Dernière intervention 18 février 2013
18 févr. 2013 à 15:46
Un petit programme sous Excel, très rapide et très efficace (toutes les possibilités envisagées). Si rien n'est trouvé, on accepte les résultats intermédiaires non entiers.
Les 6 entrées doivent être dans les cellules de la ligne 2, colonnes 2, 5, 8, 11, 14, 17 et le résultat à atteindre en ligne 2 colonne 20
La feuille Excel doit avoir pour nom "FeuyCB" (propriété CodeName)
Quand les entrées sont renseignées, on exécute le sous-programme Calcul et tout s'affiche.

---------------------------------------------------

Option Explicit

Private a#(6, 6), s%, ee#, ii%(6), jj%(6), oo%(6), fgfg(6, 6) As Boolean, im%(6), jm%(6), om%(6), am#(6, 6), nm%, m%, finfg As Boolean, amfg(6, 6) As Boolean
--------------------------------------------------------
Public Sub Alea()

Dim i%, a%

Randomize
For i = 2 To 17 Step 3
a = Int(14 * Rnd + 1): If a > 10 Then a = (a - 10) * 25
FeuyCB.Cells(2, i) = a
Next i
FeuyCB.Cells(2, 20) = Int(900 * Rnd + 100)

End Sub
--------------------------------------------------------
Public Sub Calcul()

Dim i%, e#, eee#

' Effacement résultat
EffacerRes

' Lecture
For i = 1 To 6
a(1, i) = FeuyCB.Cells(2, 3 * i - 1): fgfg(1, i) = False
Next i
s = FeuyCB.Cells(2, 20)

ee = 1000
' Comparaison de s avec les 6 valeurs initiales (sans aucun calcul)
For i = 1 To 6
e = Abs(a(1, i) - s)
If e < ee Then ee = e: If ee = 0 Then FeuyCB.Cells(6, 3) = CStr(s) & " = " & CStr(s): MsgBox "OK", vbInformation, "": Exit Sub
Next i

' Calcul
finfg = False
m = 1: Test 1
Sortie
m = 2: eee = ee: Test 1
If ee < eee Then Sortie
m = 3: eee = ee: Test 1
If ee < eee Then Sortie

End Sub
--------------------------------------------------------
Public Sub Test(n%)

Dim i%, j%, o%, k%, l%, e#, r#

For i = 1 To 7 - n
ii(n) = i
For j = i + 1 To 7 - n
jj(n) = j
k = 0: fgfg(n + 1, 6 - n) = True
For l = 1 To 7 - n
If l <> i And l <> j Then k = k + 1: a(n + 1, k) = a(n, l): fgfg(n + 1, k) = fgfg(n, l)
Next l
For o = 1 To 5
Select Case o
Case 1: r = a(n, i) + a(n, j)
Case 2: r = a(n, i) - a(n, j): If r < 0 Then r = -r
Case 3: r = a(n, i) * a(n, j)
Case 4
r = a(n, i) / a(n, j): If r < 1 Then r = a(n, j) / a(n, i)
If m = 1 And Int(r) <> r Then Exit For
Case 5: r = 1 / r: If r = 1 Or m < 3 Then r = 0
End Select
If r Then
a(n + 1, 6 - n) = r: oo(n) = o
e = Abs(r - s)
If e < ee Then
ee = e: nm = n
For k = 1 To 6: im(k) = ii(k): jm(k) = jj(k): om(k) = oo(k): For l = 1 To 6: am(k, l) = a(k, l): amfg(k, l) = fgfg(k, l): Next l: Next k
If ee = 0 Then finfg = True: Exit Sub
End If
Test n + 1
If finfg Then Exit Sub
End If
Next o
Next j
Next i

End Sub
--------------------------------------------------------
Public Sub Sortie()

Dim n%, u#, v#, uv#, cu$, cv$, cr$, ufg As Boolean, vfg As Boolean, uvfg As Boolean, r As Range

For n = 1 To nm
u = am(n, im(n)): v = am(n, jm(n))
ufg = amfg(n, im(n)): vfg = amfg(n, jm(n))
If om(n) = 5 Then
If u > v Then uv = u: u = v: v = uv: uvfg = ufg: ufg = vfg: vfg = uvfg
Else
If u < v Then uv = u: u = v: v = uv: uvfg = ufg: ufg = vfg: vfg = uvfg
End If
cu = CStr(u): cv = CStr(v): cr = CStr(am(n + 1, 6 - n))
Set r = FeuyCB.Cells(6 * m + n - 1, 3)
r.Value = cu & " " & Choose(om(n), "+", "-", "x", "/", "/") & " " & cv & " = " & cr
r.Characters(1, Len(cu)).Font.Color = IIf(ufg, vbMagenta, vbBlack)
r.Characters(Len(cu) + 1, 3).Font.Color = vbBlack
r.Characters(Len(cu) + 4, Len(cv)).Font.Color = IIf(vfg, vbMagenta, vbBlack)
r.Characters(Len(cu) + Len(cv) + 4, 3).Font.Color = vbBlack
r.Characters(Len(cu) + Len(cv) + 7, Len(cr)).Font.Color = vbMagenta
Next n
Set r = FeuyCB.Cells(6 * m + nm - 1, 18)
If finfg Then
r = "OK"
r.Characters.Font.Color = vbGreen
Else
r = "Erreur = " & CStr(ee)
r.Characters.Font.Color = vbRed
End If

End Sub
--------------------------------------------------------
Public Sub EffacerRes()
FeuyCB.Range(FeuyCB.Cells(6, 3), FeuyCB.Cells(22, 18)).ClearContents
End Sub
0
imen123 Messages postés 13 Date d'inscription dimanche 18 novembre 2012 Statut Membre Dernière intervention 2 décembre 2012
20 nov. 2012 à 21:44
si il vous plait le progremme ki pssible KX
-2
KX Messages postés 16734 Date d'inscription samedi 31 mai 2008 Statut Modérateur Dernière intervention 24 avril 2024 3 015
20 nov. 2012 à 21:50
Ce n'est pas à moi de faire ce code que je sache ! Tous les ans à la même époque les même questions qui reviennent, les profs ne se foulent pas trop, mais de toute évidence les élèves non plus !

En plus je t'ai déjà répondu dans ta discussion (ici) : "depuis le temps je n'ai plus le code sous la main"
0
imen123 Messages postés 13 Date d'inscription dimanche 18 novembre 2012 Statut Membre Dernière intervention 2 décembre 2012
21 nov. 2012 à 22:37
merciiii pour votre aide :)
0