Răspunsul la niște provocări. Partea a III-a. Re-citirea problemei cu alți ochelari Tiberiu Socaciu Preambulul Ca urmare a unei provocări primite pe pagina Proful de Mate de pe Facebook 1, de la un elev de clasa a IX-a 2 : am oferit în [3] trei soluții pentru problemă, așa cum am înțeles-o eu, adică: Fie vectorul u = (u1, u2,, un) cu ui = (3i-1) -1 (3i) -1 (3i+1) -1. Să se construiasca vectorul v = (v1, v2,, vn) ştiind că vi = S20+Si, i=1, 2,, n, unde Sk = u1 + u2 + + uk. Observatie. Se va citi de la tastatura doar valoarea lui n. Exemplu. Pentru n=5 se va obţine vectorul v = (0.1787513, 01787764, 0.1787818, 0.1787877)., iar pe final am lansat 3 provocări: 1. Economie de variabile: în varianta cu scalar se poate renunţa la variabila u, iar variabilele S20 şi S pot fi comasate într-o singură variabilă, dat fiind că duratele lor de viaţă sunt disjuncte. 2. Cele 3 aplicaţii se pot asambla într-o singură aplicaţie, folosind directivele de compilare # define, # ifdef şi # endif 3. Reinterpretând enunţul prost scanat se pot obţine noi probleme, cum ar fi vi = S20+I sau vi = S20+7i sau altă formula de acelaşi tip., din care am rezolvat-o deja pe prima 3 și pe a doua 4. A treia provocare cerea ca reinterpretând enunțul (prost scanat), observînd că se pot obține noi probleme, cum ar fi vi = S20+i sau vi = S20+7i sau altă formulă de același tip. Vom rezolva problema pe cazul 1 Vezi [2]. 2 Vezi [1], pagina 52, problema 50, pentru problema originală. 3 Vezi [4]. 4 Vezi [5]. 1
mai general, care acoperă și problema inițială și cele doua propuse, și anume în cazul în care vi = SA+Bi, unde A și B sunt două constante naturale, date 5. Soluția cu funcții Tot ce avem de făcut este să adăugăm macrodefiniția parametrizată pentru formula indicelui: și să ajustăm corespunzător funcția v(). Astfel, programul devine: # include <iostream> using namespace std; float u(int i) return 1./(3*i-2)/(3*i)/(3*i+1); float S(int k) float suma = 0; for (int i=1; i<=k; i++) suma += u(i); return suma; float v(int i) return S(M(i)); int main() int n; cout << "n = "; cin >> n; cout << "v = ("; for(int i=1; i<=n-1; i++) cout << v(i) << ", "; cout << v(n) << ")" << endl; return 0; 5 Eventual la compilare, ca in [4]. 2
Soluția cu vectori Folosind aceași macrodefiniție: programul este: # include <iostream> using namespace std; int main() # ifdef MAXN float S[MAXN+1], u[m(maxn)+1], v[maxn+1]; # else float S[101], u[m(100)+1], v[101]; # endif int m, n; cout << "n = "; cin >> n; m = M(n); for(int i=1; i<=m; i++) u[i]=1./(3*i-2)/(3*i)/(3*i+1); S[1]=u[1]; for(int i=2; i<=m; i++) S[i]=S[i-1]+u[i]; for(int i=1; i<=n; i++) v[i]=s[m(i)]; cout << "v = ("; for(int i=1; i<=n-1; i++) cout << v[i] << ", "; cout << v[n] << ")" << endl; return 0; cu observația că macrodefiniția am folosit-o de două ori: 1) o dată la calculul valorii lui v[i]; 2) a doua oară ca dimensiune maximă a indicelui până la care avem de calculat valorile din vectorul u. De asemenea, de remarcat alocarea vectorilor folosind compilare condițională bazată pe: 3
1) existența definiției lui MAXN; 2) existența macrodefiniției parametrizate a lui M. Soluția cu scalari Folosind aceeasi macrodefiniție transformată: # define A 20 # define B 7 # define M(i) (A + B * i) și adăugînd o macrodefiniție pentru termenul ui care se repetă de două ori: # define U(i) (1./(3*i-2)/(3*i)/(3*i+1)) programul este: # define A 20 # define B 7 # define M(i) (A + B * i) # define U(i) (1./(3*i-2)/(3*i)/(3*i+1)) # include <iostream> using namespace std; int main() float S; int i, j, n, m; cout << "n = "; cin >> n; m = M(n); S = 0; for(i=1; i<=a; i++) S += U(i); cout << "v = ("; for(; i<=m;) for (j=1; j<=b; j++, i++) S += U(i); cout << S; if (i!=m+1) cout << ", "; cout << ")"; 4
Cu mențiunea că se calculează într-o primă etapă suma u1+ +ua în variabila S, iar apoi se adună calupuri de B elemente succesive din șirul u 6 la variabila S care va lua succesiv valorile pentru S1,, Sn. Ultima valoare din șirul u calculată va fi UM(n), adică Um. Întrebări 1. Care este rostul testului if (i!=m+1)? 2. Cum ați rescrie cu un while instrucțiunea for(; i<=m;)? 3. De ce se incrementează variabila i în instrucțiunea for (j=1; j<=b; j++, i++)? Referinţe [1] Carmen Popescu, Culegere de probleme de informatică, accesibilă online la adresa https://www.scribd.com/document/282238460/culegere-de-probleme-informatica- Carmen-Popescu. [2] Proful de Mate, pagina pe Facebook, accesibilă online la adresa https://www.facebook.com/pg/proful-de-info- 1586589874777502/about/?ref=page_internal [3] Tiberiu Socaciu, O problemă care nu este ceea ce pare a fi, in InformaGica, accesibila online la adresa http://www.informagica.ro/2019/02/26/o-problema-care-nueste-ceea-ce-pare-a-fi/. [4] Tiberiu Socaciu, Răspunsul la niște provocări. Partea I. Economia de variabile, în InformaGica, accesibilă online la adresa http://www.informagica.ro/2019/02/26/raspunsul-la-niste-provocari-partea-i-economiade-variabile/. [5] Tiberiu Socaciu, Răspunsul la niște provocări. Partea a II-a. Directive de compilare, în InformaGica, accesibilă online la adresa http://www.informagica.ro/2019/02/27/raspunsul-la-niste-provocari-partea-a-ii-adirective-de-compilare/. Cuprins Preambulul... 1 Soluția cu funcții... 2 Soluția cu vectori... 3 Soluția cu scalari... 4 Întrebări... 5 Referinţe... 5 Cuprins... 5 6 Vezi for-ul bazat pe j. 5
Tiberiu Socaciu este licenţiat în informatică şi doctor în cibernetică. Este cadru didactic la CN Petru Rareş din Suceava şi la Universitatea Ştefan cel Mare din Suceava. 6