Aujourd'hui je vous présente mon nouveau projet, il s'agit d'un solveur d'équations de type linéaire (1er degré) et entièrement en TIbasic z80.
~ Avant propos ~
Je tiens à préciser que j'ignore totalement si le projet a déjà été réalisé. Mon programme ne se base sur aucun autre programme ou projet. De plus, même si mon programme n'est pas terrible (à vous d'en juger), merci de respecter le travail effectué et de ne pas partager ou vous approprier le programme sans mon autorisation. Merci.
~ Présentation globale ~
La première chose que vous devez vous dire, c'est pourquoi développer un resolveur d'équations car la calculatrice en a déjà un, la fonction solve()? Et bien, pour plusieurs raisons :
- Elle ne résout que si l'équation est nulle, autrement dit, par exemple : 3X+2=0. Elle ne résout pas: 3X=-2. C'est bête, mais peux pratique dans certaines longues équations. Il faut tout transposer, c'est long et pas vraiment bénéfique au final.
- Le résultat ne s'affiche pas sous sa forme exacte, alors que mon programme affiche le nombre fractionnaire le plus proche de la solution!
Voilà en gros pourquoi ignorer, pour le moment, le solveur d'équation intégré à votre calculatrice.
Mais ce programme est également là pour
~ Fonctionnalités du programme ~
Le programme sera compatible pour toutes les calculatrices z80, incluant la TI82/STAT/FR. (pas sûr à 100%, mais très probable). Il est codé en TIbasic z80, sans bibliothèque externe.
Il sera capable de résoudre une équation comme celle-ci:
3X+3*2+(1/2)X - 13*24X = 10X - 3 +0,2683X
Ceci est à titre d'exemple.
En revanche, il sera incapable de résoudre une équation contenant :
- Des X sous une racine
- Des X élevés à une puissance > 1 (appartenant aux entiers naturels)
- Des X dans une fraction : 2/3X sera calculé comme (2/3)X. Le programme est amené à évoluer pour ignorer ce genre de problèmes.
~ Fonctionnement & Explications ~
Le fonctionnement est simple:
Partons de l'équation: 10X = 5X+2
- Je sépare les 2 parties de l'équation pour les traiter séparément.
Nous avons donc: 10X et 5X+2
- Ensuite, je recherche dans la chaîne 10X, puis dans 5X+2 si il y a un X.
C'est le cas dans 10X.
- Ensuite, je cherche dans la chaîne, en partant cette fois ci du X vers la droite de la chaîne, vers sa base un "+" ou un "-", ou l'origine du la chaîne. Je trouve un nombre qui se situe "entre les deux".
Dans notre exemple, on trouve 10 et 5 .
Je stock ces résultats.
- Ensuite, dans chaque partie, je stocke 0 à X et j'utilise la fonction expr() pour donner le résultat de la partie. En fait, cela me donne le nombre de chiffre "autre que des X".
- Enfin, une simple transposition des X/chiffre d'un côté à l'autre et je finis par trouver un résultats sous forme d'une fraction exacte (non simplifiée pou l'instant)
- Pour afficher le "trait de fraction", je recherche le plus grand nombre de la fraction (si il y en a un de négatif, je le passe positif) , et je met autant de trait de fraction que ce nombre comporte d'unités. C'est du pure détail anecdotique.
~ Screenshoot (v1.2)~
~ Code source ~
- v1.2 (dernière):
:DelVar XDelVar L26→dim(L2
:1→C
:ClrHome
:Output(4,1,"EQUATION SOLVER
:Output(5,1,"v1.2 - Wistaro
:For(A,1,16
: Output(6,A,"+
: Output(3,A,"+
:End
:Lbl 1
:DelVar L1
:Input "?>",Str1
:ClrHome
:Disp "PLEASE WAIT...
:Str1→Str9
:length(Str9→L
:inString(Str9,"="→P
:If not(P:Goto 1
:Lbl 9
:Str9→Str1
:If C=1:Then
: sub(Str9,1,P-1→Str1
: length(Str1→V
: expr(Str1→L2(C+2
:End
:If C=2:Then
: inString(Str9,"=")→P
: sub(Str9,P+1,length(Str9)-P→Str1
: length(Str1→V
: expr(Str1→L2(C+2
:End
:If not(inString(Str1,"X"):Then
: {0}→L1
: Goto 6
:End
:1→T
:Lbl 5
:length(Str1→V
:If inString(Str1,"X":Then
: inString(Str1,"X"→A
: Repeat Str3="+" or Str3="-" or A=1
: If A>1:A-1→A
: sub(Str1,A,1)→Str3
: End
: If A=1:sub(Str1,1,inString(Str1,"X")-A→Str4
: If A>1:sub(Str1,A+1,inString(Str1,"X")-(A+1)→Str4
:End
:T→dim(L1
:sub(Str4,1,1
:If Ans="+" or Ans="-" or Ans="*" or Ans="/":sub(Str4,2,length(Str4)-A)→Str4
:expr(Str4→L1(T
:inString(Str1,"X"→P
:If V-P:Then
: inString(sub(Str1,P+1,V-P),"X")→Q:Else:Goto 6:End
:If V>P and Q
:Then
: sub(Str1,P+1,V-P)→Str1
: T+1→T
: Goto 5
:End
:Lbl 6:ClrHome
:ClrDraw
:DelVar Esum(L1→L2(C
:If C=1:Then
: 2→C:Goto 9
:End
:L2(1)-L2(2→A
:L2(4)-L2(3→B
:If A<0:Then
: ‾A→A:‾B→B:End
:ClrHome
:DelVar Y1
:Text(0,0,Str9
:Text(7,0,"<=> ",L2(1),"X+",L2(3),"=",L2(2),"X+",L2(4
:Text(14,0,"<=> ",A,"X+",L2(3),"=",L2(4)
:Text(21,0,"<=> ",A,"X=",B
:If not(A:Goto 8
:Text(30,0,"<=> X="
:If not(fPart(B/A:Then
: Text(47,0,B/A
:Else
: If not(fPart(A) and not(fPart(B):Then
: If A<0:Then:‾A→F:Else:A→F:End
: If B<0:Then:‾B→G:Else:B→G:End
: A/gcd(F,G)→A
: B/gcd(F,G)→B
: End
: Text(40,0,B
: Text(54,0,A
: StorePic 1
: If A<0:Then:‾A→A:1→E:End
: If B<0:Then:‾B→B:1→E:End
: max({A,B→M
: {0,1→L1:{0,M→L2
: LinReg(ax+b)L1,L2,Y1
: Equ►String(Y1,Str1
: sub(Str1,1,length(Str1)-3→Str1
: DelVar Y1
: For(D,0,length(Str1)+E
: Text(47,3D,"-
: End
: RecallPic 1
:End
:Pause :ClrDraw
:Disp "
:Stop
:Lbl 8
:Text(30,0,"S= <ensemble vide>
:Pause
- v0.1a:
:DelVar XDelVar L24→dim(L2
:1→C
:ClrHome
:Output(4,1,"EQUATION SOLVER
:Output(5,1,"v0.1a - Wistaro
:For(A,1,16
: Output(6,A,"+
: Output(3,A,"+
:End
:Lbl 1
:DelVar L1
:Input "?>",Str1
:ClrHome
:Disp "PLEASE WAIT...
:Str1→Str9
:length(Str9→L
:inString(Str9,"="→P
:If not(P:Goto 1
:Lbl 9
:Str9→Str1
:If C=1:Then
: sub(Str9,1,P-1→Str1
: length(Str1→V
: expr(Str1→L2(C+2
:End
:If C=2:Then
: inString(Str9,"=")→P
: sub(Str9,P+1,length(Str9)-P→Str1
: length(Str1→V
: expr(Str1→L2(C+2
:End
:If not(inString(Str1,"X"):Then
: {0}→L1
: Goto 6
:End
:1→T
:Lbl 5
:length(Str1→V
:If inString(Str1,"X":Then
: inString(Str1,"X"→A
: Repeat Str3="+" or Str3="-" or A=1
: If A>1:A-1→A
: sub(Str1,A,1)→Str3
: End
: If A=1:sub(Str1,1,inString(Str1,"X")-A→Str4
: If A>1:sub(Str1,A+1,inString(Str1,"X")-(A+1)→Str4
:End
:T→dim(L1
:sub(Str4,1,1
:If Ans="+" or Ans="-" or Ans="*" or Ans="/":sub(Str4,2,length(Str4)-A)→Str4
:expr(Str4→L1(T
:inString(Str1,"X"→P
:If V-P:Then
: inString(sub(Str1,P+1,V-P),"X")→Q:Else:Goto 6:End
:If V>P and Q
:Then
: sub(Str1,P+1,V-P)→Str1
: T+1→T
: Goto 5
:End
:Lbl 6:ClrHome
:sum(L1→L2(C
:If C=1:Then
: 2→C:Goto 9
:End
:L2(1)-L2(2→A
:L2(4)-L2(3→B
:If not(A:Then
: ‾A→A:‾B→B:End
:ClrHome
:Output(1,1,"Resultat:
:Output(2,1,"X=
:Output(4,1,B
:Output(6,1,A
:If A<0:‾A→A
:If B<0:‾B→B
:max({A,B→M
:{0,1→L1:{0,M→L2
:LinReg(ax+b)L1,L2,Y1
:Equ►String(Y1,Str1
:sub(Str1,1,length(Str1)-3→Str1
:For(D,1,length(Str1
: Output(5,D,"-
:End
:Pause
~ Annexe ~
L'équation doit respecter le règles suivantes:
- Si il y a un X tout seul, il doit s'écrire "1X" et pas "X"
- Il faut mettre "+ - X" et pas "-x" sauf en début de terme.
Je tiens à préciser que ce programme est à l'état de projet, et il n'est pas nécessairement voué à être abouti, si il est parfaitement inutile. De plus, je pense pouvoir réussir à traiter les "pie" et "racines" comme eux-même, c'est à dire qu'ils pourront apparaître comme tel, simplifié dans le résultat, ce qui serait déja un gros avantage. De plus, comme vous pouvez le voir, la fraction donnée n'est pas simplifié, et le programme devra par la suite effectuer cette simplification (j'y travaille actuellement)
Dernière édition par Wistaro le Mer 16 Juil 2014 - 9:41, édité 8 fois