linkakro le 28/06/2011 à 15:59
dernière maj essentielle le 26/07/12
dernière maj mineure 16/11/2013
merci à Maxence d'espace ti dont l'introduction aux booléens m'a inspirée pour améliorer le 25/6/2013
---------- EDIT important 7/2/12
La réduction de la taille du code ne permet pas toujours d'accélérer un programme !
Il arrive parfois qu'une formule optimisée appelle des ressources plus lentes qu'un algorithme simple et (plus) long.
Il n'existe pas de règle générale, ce sera à vous de tester plusieurs possibilitées. Désolé
----------
Vous pouvez vous inspirer des
règles de scrutation dégagé[...]icle sur DelVar pour éviter toute lecture innutile de portions du programme.
La présentation d'une équation logique dans un test peut influer sur le poids du code ou la rapidité.
La rapidité est plus difficile à juger que le poids, mais il arrive assez souvent qu'une formule ai un avantage sur des tests ou un algorithme.
Il est possible de pratiquer des tests sans utiliser la fonction If.
On peut aussi remplacer un test par une variable.
Ou encore stocker des tests dans des listes.
....
Je vous montrerai ici comment simplifier certains programmes en appliquant des principes généraux.
Objectifs :
-tenter d'optimiser la mémoire et/ou la vitesse (difficile à gérer)
-regrouper plusieurs actions en une seule ligne
-simplifier des raisonnements
Tous les principes montrés pour des If s'appliquent aux boucles While et Repeat.
==== Logique et Algèbre de Boole (utiliser les booléens)
Un booléen est une information BINAIRE qui représente VRAI ou FAUX avec les valeurs 1 ou 0 respectivement.
Par exemple, sur l'écran de calcul, si j'execute "1=1", ce qui est vrai, la calculatrice m'affiche "1" pour me dire que c'est vrai. Et si j'execute "1=2", elle m'affiche 0 car cela est faux.
Sachez déjà pour plus tard que la calculatrice TI supporte le nombre zéro comme faux et tout le reste comme vrai (0.1,1.2,-1,-1.2,...) lorsqu'on utilise les fonctions adéquates. .
Mais vous ne pourrez pas toujours vous en servir, les fonctions sont importantes.
L'algèbre de Boole est une manière de rassembler les booléens pour écrire la logique.
Cet algèbre admet des opérations et des propriétés particulières, mais certaines ressemblent à l'algèbre classique.
Il permet de transformer des raisonnements en équations pour faciliter des raisonnements et simplifier les études théoriques avant de coder un programme.
Voici un récapitulatif des opérations et de quelques propriétés.
Code
non(0)=1
non(1)=0
"ou exclusif" peut s'abrèger en "xor"
0 et 0 = 0 0 ou 0 = 0 0 xor 0 = 0
0 et 1 = 0 0 ou 1 = 1 0 xor 1 = 1
1 et 0 = 0 1 ou 0 = 1 1 xor 0 = 1
1 et 1 = 1 1 ou 1 = 1 1 xor 1 = 0
"et" ressemble à la multiplication, on écrira "*"
"ou" ressemble à la somme, on écrira "+"
Malheureusement xor et non n'ont pas de ressemblance avec les maths classiques.
Et on peut contrarier chaque table avec la fonction "non()" pour définir d'autres tables.
Il sera parfois intéressant de se servir de calculs mathématiques à la place des fonctions booléennes.
De plus on peut dans certains cas mélanger les algèbres de Boole et Classique.
Lorqu'on écrit un raisonnement impliquant plusieurs variables, on peut souvent
l'écrire sous deux formats :
"tous vrai" ou "aucun faux"
Or un raisonnement peut être plus facile à écrire dans une calculatrice que l'autre.
L'équivalence est donnée par le théorème de Morgan
not(A et B) == not(A) ou not(B)
not(A ou B) == not(A) et not(B)
Remarque : avec la convention des produits/sommes
not(A*B) = not(A)+not(B)
not(A+B) = not(A)*not(B)
###
Quelques formules booléennes utiles pour réduire certains calculs au niveau du concept
A*(B+C)=(A*B)+(A*C)
A+(B*C)=(A+B)*(A+C)
// attention : uniquement en booléen
not(A*B)=not(A)+not(B)
not(A+B)=not(A)*not(B) // théorème De Morgan
A*B+not(A)*B=B
A xor B = A*not(B)+not(A)*B
A xor A = 0
==== usages dans une TI
Tous les tests donnent 0 ou 1 comme résultat. ( 0=faux , 1=vrai )
De plus, les fonctions de test reconnaissent ces valeurs 1 et 0.
Si on donne à une opération logique le nombre 0, il est faux.
TOUT le reste est VRAI.
Code
Quand on fait un test. exemple : A=B
FAUX ==>> 0
VRAI ==>> 1
Quand on fait une opération logique (à partir de test(s)/nombre(s))
0 ==>> FAUX
1 ==>> VRAI
AUTRE ==>> VRAI ( exemples : 0.2 , 1.3 , 2, 99 , -2 , -2.3 , ...)
Les fonctions de tests sont les opérandes de test (>,=,<=,...) ou opérandes logiques (et,ou,...) ainsi que les fonctions des tests (If, Repeat, While).
Celles-ci sont indispensables pour supporter les valeurs NON-Binaires.
#####
Ordre de priorité des opérations dans une TI :
-parenthèses simples ou parenthèses de fonctions comme non().
-calculs classiques (^,*,+,...)
-nCr et nPr
- relations (=,<,>,...)
-opérateur booléen et
-opérateurs booléens xor ("ou exclusif") / ou
Plus de détails dans le manuel, c'est encore plus compliqué sur ti82 que sur ti82stat. Je résume de mémoire.
#####
:If A
:Disp "OK
Si A=0
, il ne se passe rien.
Sinon
"OK" est affiché.
Et on peut même stocker le résultat d'un test.
:B=2->A
:If A
:Disp "OK
Si B=2
"OK" est affiché.
Sinon,
il ne se passe rien.
If A signifie
If A=/=0
If non(A) signifie
If A=0
If A-X signifie
If A=/=X ou encore
non(A=X)
While 1 et
Repeat 0 seront toujours vrais. (utile pour des boucles infinie)
Pour ceux qui n'ont pas assimilé la première partie :
If A ou B correspond à
If A+B
If A et B correspond à
If AB
Quelques autres équivalences qui me semblent superflues :
If A=B =
If not(A-B
If A>B =
If iPart(A/B //S'écrit également AB^-1 // c'est plus rapide
If A<B =
If iPart(B/A //De même, BA^-1
EDIT 24/02/13 : j'ai remplacé "ent" par "iPart" ci-dessus, explication par Samos en page 2 et
cet autre tuto
==== usage des listes
Approfondissement du
tutoriel du SDZ
Un test sur une liste provoque ce test sur chaque élément de la liste.
Le résultat est une liste remplie de 0 ou de 1 suivant chaque test.
X={A,B,C}
teste X=A,X=B,X=C et revoie une liste remplie de 0 et de 1.
Exemple :
7={2,7,1} // vaut // {0,1,0}
Nous pouvons réaliser de nombreuses conditions en une seule fois puis les rassembler avec des calculs pour imiter des opération ET/OU.
Exemple
Code
Repeat max(codeTouche={21,22,23
End
// quitte si pression d'une des touches 2nde=21,mode=22,suppr=23
Voici quelques fonctions pour effectuer les tests multiples.
MIN~~PROD~~ET
MAX~~SOMME~~OU
Attention :
-veillez à fournir des valeurs du bon domaine aux fonctions de calculs +/*/max/min
-vérifiez que les exploitations sont cohérentes au domaine des résultats
Usages classique :
-Placez tout dans un TEST pour convertir les Réels en Binaire.
-utilisez des nombres de même signe ou même positifs.
Citation
//////// Binaire
//OU
max(0,1) = 1
max(0,0) = 0
//ET
min(1,1)= 1
min(0,1) = 0
//OU
somme(1,1) = 2 !!!!!!! SORTIE PAS BINAIRE !
somme(0,0) = 0
//ET
prod(1,1) = 1
prod(0,1) = 0
//////// réels +++
//OU
max(0,3) = 3
max(0,0) = 0
//ET
min(2,3) = 2
min(0,3) = 0
//OU
somme(2,3) = 5
somme(0,0) = 0
//ET
prod(2,3) = 6
prod(0,0) = 0
//////// réels ---
//ET // !!!!!!!! INVERSE ROLE
max(-2,-3) = -2
max(0,-3) = 0
//OU // !!!!!!!! INVERSE ROLE
min(-2,-3) = -2
min(0,0) = 0
//OU
somme(-2,-3) = -5
somme(0,0) = 0
//ET
prod(-2,-3) = 6 // signe alternatif
prod(0,0) = 0
Ci-dessous des usages courants
Citation
ET
If X=A et X=B et X=C
If min(X={A,B,C})
If prod(X={A,B,C})
OU
If X=A ou X=B ou X=C
If max(X={A,B,C})
If somme(X={A,B,C})
ET (aucun zéro)
If A et B et C
If min({A,B,C})
If prod({A,B,C})
OU (au moins un non-nul)
If A ou B ou C
If max({A,B,C})
If somme({A,B,C})
///// Et avec le théorème De Morgan on en trouve d'autres et des variantes
If non(A) et non(B) et non(C)
If non(A ou B ou C)
If prod(non({A,B,C}))
If min(non({A,B,C}))
If non(somme({A,B,C})
If non(max({A,B,C})
En binaire, cela revient à dire que la liste est nulle.
If non(A) ou non(B) ou non(C)
If non(A et B et C)
If somme(non({A,B,C})
If max(non({A,B,C})
If non(prod({A,B,C}))
If non(min({A,B,C}))
En binaire, cela revient à dire qu'il y a au moins une valeur nulle dans la liste.
Quelques Applications
Citation
If A=X et B=X et C=X
If 2=somme(X={A,B,C})
//// Ici on teste un nombre précis de termes : 2 parmi 3.
exemple de l'intro : détection d'une touche parmi une liste
Code
Repeat max(codeTouche={21,22,23
End
détecte une valeur non-nulle ET LA RENVOIE, en supposant qu'une seule est non-nulle
Je suis en panne d'exemple frais.
----
Un test entre deux listes de même longueur provoque ce test entre les termes de même position (le premier avec le premier, le deuxième avec le deuxième etc)
Le résultat est une liste remplie de 0 ou de 1 selon chaque test.
On peut alors recueuillir de nombreux tests voire même les exploiter plus tard et séparément.
{A,B,C}={D,E,F}
teste A=D,B=E,C=F et revoie une liste de longueur 3 remplie de 0 et de 1.
On peut placer ceci à l'intérieur d'une opération pour l'exploiter.
Exemple :
{2,2,2}={1,2,3} // vaut // {0,1,0}
application 1 :
Pour tester l'égalité de deux listes : prod(L1=L2)
application 2 : (se rapproche des masques de la partie suivante)
Dans un jeu :
max({1,2,3,4}(A={24,25,26,34->D
Si A=24, D=1
Si A=25, D=2
Si A=26, D=3
Si A=34, D=4
application 3 :
Pour tester plusieurs conditions du même type et vérifier qu'un certain nombre précis de ces tests sont vrais :
If 2=somme({A,B,C}={D,E,F}
Ceci vérifie que deux égalités exactement sont vérifiées parmi A=D,B=E,C=F
----
On peut même pratiquer des opérations de masquage comme dans des microcontrôleurs, mais avec plus d'outils.
Seuls certains masquages sont utiles dans une calculatrice.
Ne confondez pas L1={...} pour une calculatrice et pour nous. Pour nous c'est La liste qui est égale et pour la calculatrice c'est une série de tests.
Exemple 1 :
L1*{1,1,0,0}={2,0,0,0}
Pour que le test soit vrai, il faut
L1={2,0,?,?}.
"?" signifie que l'état des termes trois et quatre n'a pas d'importance dans le test.
Le masque est {1,1,0,0}.
Les deux derniers zéros servent à neutraliser les termes de L1 qu'on ne veut pas tester.
Principe :
{w,x,y,z}
*{1,1,0,0}
={w,x,0,0}
Dans la calculatrice : L1*{1,1,0,0}={W,X,0,0}
Sert à tester : L1={W,X,?,?}
Cela évite parfois d'écrire
If L1(?)=? et L1(?)=? et L1(?)=? et L1(?)=? et ...
Exemple 2 :
max(L1{1,2,3}->N
Si L1={1,0,0} alors N=1
Si L1={0,1,0} alors N=2
Si L1={0,0,1} alors N=3
==== Les matrices
On ne peut pas utiliser les fonctions des listes comme somme ou max.
Les tests ne fonctionnent pas en répartissant plusieurs tests.
En revanche le test d'égalité ou de différence fonctionne et les opérations de somme et produit entre matrices fonctionnent lorsqu'elles ont les mêmes dimensions.
Code
Prompt [A],[B]
dim([A]->dim([B]
[A]+2[B] // opération entre termes de mêmes positions
0[A] // matrice nulle de même dimension que [A]
[A]=[B] // test : identiques
[A]=/=[B] // test : différentes
[A]=0[A] // test : matrice nulle
[A]=/=0[A] // test : matrice non-nulle
Astuce : pour créer une matrice carrée nulle d'ordre N, vous pouvez utiliser
Je n'ai pas trouvé d'opération globale pour trouver la présence d'au moins un zéro.
Si vous voulez rassembler plusieurs tests/résulats dans une matrice, vous devrez vous débrouiller avec l'affectation ou des boucles.
Si vous voulez effectuer des masquages, vous devrez utiliser les fonctions de conversion en liste ou la fonction *row(valeur,matrice,ligne) mais hélas sur des lignes entières.
Pour traiter une colonne au lieu d'une ligne et vice-versa, utilisez la transposition.
[A]^t avec "^t" un petit T en exposant dans le menu matrice.
==== intégrer des booléens dans des calculs
Exemple à la fin du
tutoriel du SDZ
Tout test peut être intégré à un calcul entre parenthèses ou via une variable justement parce que les tests génèrent 0 ou 1.
Je commence avec des conditions exclusives les unes par rapport aux autres, je fais un paragraphe pour bien montrer ce qui se passe quand ce n'est pas exclusif.
Ci-dessous vous écrivez chaque condition et la valeur désirée.
Pensez que la valeur par défaut est zéro.
P*(
condition1 )
+Q*(
condition2 )
+R*(
condition3 )
+S*(
condition4 ) ... ->Z
Ci-dessous vous écrivez une valeur par défaut et les écarts à la valeur neutre.
N +
(P-N)*(
condition1 )
+(Q-N)*(
condition2 )
+(R-N)*(
condition3 )
+(S-N)*(
condition4 ) ... ->Z
Les conditions peuvent être n'importe quoi, mais le plus évident pour commencer est d'utiliser des booléens.
Code
If A=1 // condition 1
P->Z
If A=2 // condition 2
Q->Z
If A=3 // condition 3
R->Z
If A=4 // condition 4
S->Z
...
// EST EQUIVALENT A
P*( A=1 ) +Q*( A=2 ) +R*( A=3 ) +S*( A=4 ) ... ->Z
// VOIRE MEME
A=1->J
A=2->K
A=3->L
A=4->M
...
P*J + Q*K + R*L + S*M + ... ->Z
N + 1*( A=B )
+3*( A<B )
-2*( A>B et C=0 )->Z
Si A=B, alors Z=N+1 =N+1*1+3*0-2*0
Si A<B, alors Z=N+3 =N+1*0+3*1-2*0
Si A>B et C=0, alors Z=N-2 =N+1*0+3*0-2*1
Sinon Z=N
Une condition peut être une opération entre des tests.
(A=0)(B=0)+2*(A=1)(B=1)->Z
Si A=0 et B=0 , Z= 1*1+2*0*0 =1
Si A=1 et B=1 , Z= 0*0+2*1*1 =2
Sinon Z=0
(dont Si A=0 et B=1 , Z= 1*0+2*0*1 =0 )
(dont Si A=1 et B=0 , Z= 0*1+2*1*0 =0 )
Attention :
On risque de ne pas prévoir tous les résultats de la formules et ainsi avoir de mauvaises surprises.
=> AU MOINS UNE condition doit être vérifiée SI ON NE VEUT PAS UNE VALEUR PAR DEFAUT
=> Il doit y avoir AU MAXIMUM UNE seule condition de vérifiée à la fois OU BIEN il faut en tenir compte dans les coefficients.
Exemple qui peut commettre un conflit entre les états :
A+1+(A=1)+2(A<2)
Si A<1 : A+1+0+2=A+3
Si A=1 : A+1+1+2=A+4
Si A>1 : A+1+0+0=A+1
On voit que des cas se superposent, il faut bien y réfléchir.