Lire une matrice carrée en zig-zag
Bonjour, :salut:
Rien à redire aux instructions en soi légitimes, dont tu nous a donné la traduction; et l'algorithme fonctionne correctement, puisqu'il conduit aux matrices et listes attendues lorsque (n) vaut 3, 4 ou 5. Donc bravo, un trophée de plus pour la section du Forum.
Il découle de ceci:
1°) que l'émulation est une excellente chose
Citation:
Envoyé par
Flodelarab
J'avais la flemme de faire les calculs concrets, mais devant votre courage à tous pour écrire du code, je vais le faire ...
2°) que l'algorithmique n'est pas incompatible avec l'humour
Code:
1 2
| $ ./lineariser.awk diagonale3.txt
la fin justifie aussi parfois des moyens tordus efficaces |
3°) ... mais aussi que les instructions les plus tordues (*) peuvent dissimuler les plus simples algorithmes :mrgreen:
(*) soyons francs, ce n'est pas le cas ici
J'aperçois en effet dans le texte la fonction Abs(x) définie (quelle horreur !) par les instructions conditionnelles;
Code:
1 2
| IF x<0 THEN Abs:= -x
ELSE Abs:= x ; |
ce qui fait que la longueur (e) d'une diagonale, définie par la relation: e = n - | ind - n - 1 | relève aussi de consignes prohibées:
Code:
1 2
| IF ind<(n + 1) THEN e:= ind - 1 // e = n - (n + 1 - ind) = ind - 1 , variant de 1 à n - 1
ELSE e:= 2*n + 1 - ind ; // e = n - (ind - n - 1) = 2*n + 1 - ind , variant de n à 1 |
et quelques lignes plus loin l'expression
Code:
x=(ind%2)*(e+1-2*lec)+lec+(ind-e-1)/2;
équivalente à
Code:
1 2
| IF Odd(ind) THEN x:= (1 + e + ind)/2 - lec // x = e + 1 - 2*lec +lec + Ind/2 -(1 + e)/2 = (1 + e + ind)/2 - lec
ELSE x:= lec+(ind-e-1)/2; // heureusement, (e) et (ind) sont toujours de parités opposées ! |
On retrouve ainsi les deux conditions concernant la longueur et la parité de la rangée.
Citation:
Conclusion: Aucune condition n'est requise. Que du calcul.
De même que Monsieur Jourdain faisait de la prose sans le savoir, qui recourt aux fonctions Abs(x) et (x MOD 2) insère à son insu des opérations logiques dans son calcul.
Lire une matrice carrée en zig-zag
Bonjour, :D
@anapurna
Hier soir, l'appel de Round(x) dans le calcul d'une fonction entière de variables entières m'a intrigué, mais j'ai d'abord mis cela sur le compte des nombreux mystères de la programmation.
Citation:
Envoyé par
anapurna
... Etant curieux j'ai programmé la fonction définie plus haut ...
voici les codes utiles pour les curieux ^^
Code:
1 2 3 4 5 6 7 8
|
Function zz(n,i,j : Integer) :Integer;
begin
if (i+j) < n Then
Result := Round(((i+j)*(i+j+2+Power(-1,i+j))/2)-(power(-1,i+j)*i))
else
Result := Round(Power(n,2)-1-zz(Round(power(n,2)),n-1-i,n-1-j));
end; |
C'est seulement ce matin que je me suis aperçu qu'on y était contraint, dès lors qu'intervenait aussi la fonction réelle power(x, y); un calcul plus simple ne serait-il pas possible, en n'utilisant que des entiers ? Par exemple:
Code:
1 2 3 4 5 6 7
|
BEGIN
s:= i + j; IF Odd(s) THEN u:= -1
ELSE u:= 1;
t:= s + 2; Inc(t, u);
p:= s * t; q:= p DIV 2; Result:= q - u
END; |
Cordialement, W
Aucune condition n'est requise. Que du calcul.
Bonjour, :D
Que du calcul.
Symptomatique, cette réaction d'évitement !
"Que du calcul", entendre par là: on peut foncer sans réfléchir, y a pas de trucs ch mesquins du genre < si ... alors ... sinon ... > qui vous gâchent l'ambiance. Les lycéens présentent tous le même réflexe, lorsqu'ils sont par exemple confrontés à des valeurs absolues. J'avais le même comportement, à l'époque.
On peut comprendre que l'insertion de consignes de validité soit encombrante, et que l'on préfère programmer sur une (très) ancienne calculatrice dépourvue d'opérations logiques: F(n) = (1/2)*(a(n) + b(n)) + ((-1)n /2)*(a(n) - b(n)) au lieu de
Code:
1 2
| IF Odd(n) THEN F:= b(n)
ELSE F:= a(n) |
D'autres subterfuges (au départ tout aussi séduisants, j'en conviens) conduisent à des expressions analogues, relativement lourdes - elles peuvent compliquer singulièrement le contrôle des éventuelles erreurs et la recherche des cas où le calcul deviendrait difficile, voire impossible.
La formule citée plus haut peut même conduire à des résultats surprenants: essayez donc le cas suivant: a = 1010 et b = 10-10 ...
Aucune condition n'est requise
F(x) = │x│ et la condition
Code:
1 2
| IF x<0 THEN F:= -x
ELSE F:= x; |
sont indissociablement liés par la définition même de la valeur absolue, et il est enfantin d'espérer que ces instructions logiques disparaîtront comme par magie en usant de travestissements comme Fx) = (x2 )1/2 ; c'est croire qu'un nouvel habillage supprimera ce qu'il y a à l'intérieur.
Il existe d'autres exemples de produits de fonctions élémentaires non exactement réciproques, comme G(x) = Arctan(tan(x)) ou (Hx) = Arccos(cos(x),) et dont le comportement est surprenant.
L'une d'entre elles a un rapport étroit avec le reste euclidien mod((x, a). :mrgreen: Je ne dis cela pour personne, en particulier.
Soit par exemple la fonction Max(a, b) définie par:
Code:
IF b>a THEN Max:= b ELSE Max:= a;
un programmeur animé d'une aversion particulière pour les instructions conditionnelles lui substituera une expression plus sympathique:
Max(a, b) = (1/2)*(a + b) + (1/2)*(a2 + b2 - 2*a*b)1/2 , nettement plus simple, tout le monde en conviendra.
Et s'il entreprend de rechercher le plus grand volume d'un prisme oblique constructible sur 4 points dans un nuage qui en comporte (N), il lui faudra comparer (N4/24) termes: rapidité optimale garantie.
Petit exercice de géométrie analytique niveau seconde, garanti sans conditions - que du calcul !
C'est un sujet tout simple, non sans rapport avec le parcours en zig-zag d'un matrice carrée: déterminer les points d'intersection d'une droite d'équation (y = a*x + b) avec un carré de côté 2, centré à l'origine et d'arêtes parallèles aux axes du repère.
Un programmeur au raz des pâquerettes définirait les 4 côtés successifs par les conditions:
Code:
1 2 3 4 5
|
IF ((-1< y) AND (y< 1)) THEN CASE n OF 1: x:= 1;
3: x:= -1 END;
IF ((-1<=x) AND (x<=1)) THEN CASE n OF 2: y:= 1;
4: y:= -1 END; |
On rougit de confusion devant une démarche aussi prosaïque.
Un puriste ennemi de toute compromission aura recours à l'équation polaire du carré: r = 1 / cos[(1/2)*Arcsin(sin(2*t))] .
Ouf ! Enfin deux équations, que du calcul ! Pas de conditions !