forked from unknownliviu/Unibuc-Programming
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Teme.txt
362 lines (315 loc) · 19.7 KB
/
Teme.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
F1. (0.5 puncte) Scrieti un program care primeste ca argumente in linia de
comanda doi intregi si afisaza cmmdc al lor.// DONE
F2. (0.5 puncte) Scrieti un program care primeste ca argument in linia de
comanda un intreg si verifica daca este prim.//DONE
F3. (2.5 puncte) Scrieti un program care primeste ca argument in linia de
comanda un intreg si afisaza descompunerea sa in factori primi.//DONE
F4. (1 punct) Scrieti un program care primeste ca argument in linia de
comanda un intreg si afisaza suma cifrelor sale.//DONE
F5. (1 punct) Scrieti un program care primeste ca argument in linia de
comanda un intreg si afisaza imaginea sa in oglinda (ex: 1234 -> 4321).
F6. (0.5 puncte) Scrieti un program care converteste un fisier (text) cu
reprezentari externe zecimale de intregi intr-un fisier (binar) cu
reprezentarile lor interne. Specificatorii fisierelor sunti dati ca
argumente in linia de comanda.
F7. (0.5 puncte) Scrieti un program care converteste un fisier (binar) cu
reprezentari interne de intregi intr-un fisier (text) cu reprezentarile
lor externe zecimale. Specificatorii fisierelor sunti dati ca argumente
in linia de comanda.
F8. (0.5 puncte) Simularea comenzii "cp" in forma cea mai simpla: program
ce copiaza un fisier intr-alt fisier; specificatorii fisierelor sunti dati
ca argumente in linia de comanda.//DONE
F9. (0.5 puncte) Scrieti un program care concateneaza un fisier la sfarsitul
altui fisier. Specificatorii fisierelor sunti dati ca argumente in linia de
comanda.
F10. (2 puncte) Scrieti un program care concateneaza mai multe fisiere sursa
intr-unul destinatie. Se va lansa sub forma:
concat f1 + f2 + ... + fn f
unde f1, ..., fn sunt fisierele sursa iar f este fisierul destinatie.
Daca n=1, va copia pe f1 in f.
F11. (2 puncte) Scrieti un program care compara din punct de vedere
lexicografic continutul a doua fisiere (privite ca sir de caractere).
Specificatorii fisierelor sunti dati ca argumente in linia de comanda.//DONE
F12. (1.5 puncte) Scrieti un program care inverseaza ordinea caracterelor
intr-un fisier al carui specificator este dat ca argument in linia de
comanda. Nu se vor folosi fisiere auxiliare.
F13. (0.5 puncte) Scrieti un program care numara aparitiile unui caracter
intr-un fisier dat. Caracterul si specificatorul fisierului sunt dati ca
argumente in linia de comanda.//DONE
F14. (3 puncte) Scrieti un program care numara aparitiile unui string
intr-un fisier dat. Stringul si specificatorul fisierului sunt dati ca
argumente in linia de comanda.//DONE
F15. (1.5 puncte) Scrieti un program ce simuleaza comanda "cat", cu tot cu
cazul cand specificatorul fisierului este dat ca argument in linia de
comanda. Programul va putea fi lansat astfel astfel:
cat f ==> citeste din f si scrie la stdout
cat ===> citeste de la stdin si scrie la stdout //DONE
F16. (5 puncte) Scrieti un program ce simuleaza comanda "wc", cu tot cu
cazul cand specificatorul fisierului este dat ca argument in linia de
comanda si avem optiuni. Programul va putea fi lansat astfel astfel:
wc f ==> citeste din f si scrie la stdout
wc -optiuni f ==> citeste din f si scrie la stdout
wc ==> citeste de la stdin si scrie la stdout
wc -optiuni ==> citeste de la stdin si scrie la stdout
Optiunile pot fi orice sir nevid format din literele l,w,c.
F17. (2 puncte) Scrieti un program ce simuleaza comanda "grep" in forma cea
mai simpla. Programul va putea fi lansat astfel astfel:
grep sir ===> citeste de la stdin si scrie la stdout
F18. (2 puncte) Scrieti un program care sorteaza caracterele dintr-un fisier
al carui specificator este dat ca argument in linia de comanda. Nu se vor
folosi fisiere auxiliare.
F19. (3 puncte) Scrieti un program care sorteaza intregii dintr-un fisier
(binar) continand reprezentari interne de intregi. Specificatorul
fisierului este dat ca argument in linia de comanda. Nu se vor folosi
fisiere auxiliare. Nota: acest program se poate testa cu fisiere produse
de programele de la F6 si F7.
F20. (10 puncte) Implementarea matricilor dreptunghiulare de numere reale ca
fisiere binare: O matrice va fi stocata intr-un fisier binar continand
elementele sale pe linii (in format intern), plus o informatie suplimentara
din care sa se poata deduce numarul de linii si de coloane. Scrieti functii
pentru urmatoarele operatii:
void new(m,n) ==> creaza o matrice m x n initializata cu 0;
float get(f,i,j) ==> returneaza elementul de pe pozitia i,j din matricea
stocata in fisierul f;
void set(f,i,j,x) ==> scrie elementul real x pe pozitia i,j in matricea
stocata in fisierul f.
Scrieti programe care folosesc aceste functii pentru a calcula suma
si produsul a doua matrici. Programele se vor apela sub forma:
sum f1 f2 f
pro f1 f2 f
unde f1, f2 sunt specificatorii fisierelor continand matricile sursa, iar
f specificatorul fisierului care va contine matricea destinatie. Fisierele
f1 si f2 vor fi generate in prealabil cu alte programe ajutatatoare (a se
vedea de exemplu problema F6).
A1. (2 puncte) Scrieti un program "copy" care se va lansa sub forma:
copy f1 + ... + fn f
(unde f1, ..., fn, f sunt fisiere) si are ca efect crearea lui f continand
concatenarea lui f1, ..., fn; daca n=1 se copiaza f1 in f. Se vor folosi
doar functiile de la nivelul inferior de prelucrare a fisierelor.
A2. (3 puncte) Scrieti un program "sortint" care se va lansa sub forma:
sortint f
unde f este un fisier continand reprezentari interne de intregi si sorteaza
intregii din acest fisier. Se vor folosi doar functiile de la nivelul
inferior de prelucrare a fisierelor si nu se vor folosi fisiere auxiliare.
A3. (1 punct) Scrieti o functie "creaza" care primeste ca parametri un
specificator de fisier si un string continand o bara de drepturi, de exemplu:
creaza("f","rwxr_xr_x")
si creaza fisierul respectiv, cu drepturile respective, returnand 0. Daca
fisierul exista sau nu se poate crea, va returna un cod nenul. Functia va
folosi doar functii de la nivelul inferior de prelucrare a fisierelor.
Scrieti un program ilustrativ pentru aceasta functie - programul va primi
ca argumente in linia de comanda fisierul si bara de drepturile si va crea
fisierul respectiv; in caz ca nu reuseste, va afisa un mesaj de eroare.
A4. (3.5 puncte) Simulati functia "int mkstemp(char *sablon)" (avand
prototipul in "stdlib.h"), care creaza un fisier nou avand un nume unic
inspirat de "sablon". Sirul "sablon" trebuie sa aibe ultimele sase caractere
"XXXXXX"; functia va genera pe aceste pozitii toate combinatiile de caractere
posibile (modificand deci zona pointata de "sablon", care nu trebuie sa fie o
zona constanta) si pentru fiecare sir (complet) "sablon" obtinut va incerca
sa creeze un fisier cu numele respectiv folosind la "open" modul O_EXCL
(aceasta va garanta ca fisierul creat e unul nou); in momentul cand va reusi
prima data, va iesi returnand descriptorul alocat. Functia creaza noul fisier
cu drepturi de citire si scriere pentru proprietar si il deschide pentru
citire si scriere. In caz de eroare functia returneaza -1 si seteaza "errno"
la valorile: EINVAL (daca ultimele sase caractere ale lui sablon nu sunt
"XXXXXX"), EEXIST (daca pentru toate inlocuirile incercate ale lui "XXXXXX"
exista deja un fisier cu numele respectiv si astfel nu s-a putut crea un
fisier nou); in cazul EINVAL, "sablon" ramane nemodificat.
Pentru scrierea functiei "mkstemp" se vor folosi doar functii de la nivelul
inferior de prelucrare a fisierelor.
Scrieti un program demonstrativ pentru aceasta functie.
A5. (3.5 puncte) Scrieti o functie "getint" care primeste ca argument un
descriptor de fisier (presupus a fi deschis in prealabil pentru citire) si
citeste cu format zecimal un intreg din fisierul respectiv, returnand acel
intreg. Functia nu va folosi decat functii de la nivelul inferior de
prelucrare a fisierelor. Deci, daca se poate citi intregul, apelul:
int x; x=getint(d);
este echivalent cu:
int x; FILE *f;
f=fdopen(d,"r");
fscanf(f,"%d",&x);
(deci functia "getint" va citi caractere cat timp ele se potrivesc cu o
reprezentare externa de intreg zecimal si la sfarsit va returna intregul
respectiv; cand un caracter nu se mai potriveste, indicatorul in fisier este
mutat inapoi cu lseek). In citirea intregului, functia "getint" va ignora
eventualele caractere albe (blank, tab, cap de linie) prealabile. Daca de la
bun inceput intregul nu se poate citi (primul caracter nealb nu poate face
parte dintr-o reprezentare de intreg sau dupa eventualel caractere albe s-a
intalnit sfarsitul fisierului) functia va returna 0 si va seta adecvat errno.
Scrieti un program ilustrativ pentr aceasta functie.
A6. (2 puncte) Scrieti un program care primeste ca argument in linia de
comanda un fisier si inlocuieste in el orice succesiune de caractere albe
(blank, tab, cap de linie) cu un singur blank. Se vor folosi doar functii de
la nivelul inferior de prelucrare a fisierelor, fara lseek si nu se vor folosi
fisiere auxiliare. Indicatie: fisierul va fi accesat prin doi descriptori,
unul in citire, altul in scriere.//DONE
----------
A7. (2 puncte) Scrieti niste programe care arata daca fii obtinuti cu fork
ai unui proces "p" mostenesc redirectarile intrari/iesirii standard care au
loc daca lansam "p" in cadrul unui filtru:
... | p | ...
A8. (1.5 puncte) Scrieti un program care genereaza un fiu cu fork iar acesta
trimite tatalui un numar aleator de semnale SIGUSR1; fiul numara cate a
trimis, tatal numara cate a primit, apoi fiecare afisaza numarul respectiv.
Se va asigura protectia la pierderea unor semnale.
A9. (2 puncte) Scrieti un program cara arata ce se intampla daca mai multe
procese care se ruleaza in paralel in foreground incearca in acelasi timp
sa citeasca de la tastatura un caracter (fiecare il va citi, sau doar unul
aleator il va citi, etc.); procesele respective vor fi fii cu fork ai
programului initial. Nu se vor folosi decat functii de la nivelui inferior
de prelucrare a fisierelor.
A10. (6 puncte) Scrieti un program care sa sorteze prin interclasare un fisier
de caractere in maniera descrisa mai jos.
Sortarea prin interclasare presupune impartirea sirului in doua jumatati,
sortarea fiecarei parti prin aceeasi metoda (deci recursiv), apoi
interclasarea celor doua parti (care sunt acum sortate).
Programul va lucra astfel: se imparte sirul in doua, se genereaza doua
procese fiu (fork) care sorteaza cele doua jumatati in paralel, tatal ii
asteapta sa se termine (wait sau waitpid), apoi interclaseaza jumatatile.
Nu se vor folosi fisiere auxiliare.
A11. (5 puncte) Scrieti un program care genereaza prin backtracking recursiv
permutarile multimii {1,...,n} (n citit de la tastatura), in asa fel incat
de fiecare data cand se completeaza o pozitie, pentru a genera toate
continuarile posibile nu se intra in apel recursiv ci se lanseaza un proces
fiu (cu fork) care genereaza aceste continuari; nu se va astepta terminarea
fiului pentru a incerca o alta valoare pentru pozitia curenta si astfel
vectorii sunt construiti in paralel. In momentul cand un proces gaseste o
permutare o scrie cu printf fara fflush, iar un proces nu se termina decat
dupa ce i s-au terminat totii fii (ii asteapta cu wait) - astfel riscul ca
permutarile sa se amestece pe ecran este redus.
----------
A12. (4 puncte) Scrieti un program care numara aparitiile unui sir de caractere
ca subcuvant in alt sir de caractere (cele doua siruri sunt date ca argumente
in linia de comanda). De fiecare data cand se verifica daca primul sir apare
ca subcuvant incepand de pe o pozitie, verificarea se va face de catre un
proces fiu (obtinut cu fork) iar procesul tata nu asteapta ca acesta sa se
termine pentru a initia o cautare incepand de la o alta pozitie - astfel
verificarile au loc in paralel. Fiecare proces fiu returneaza 0 = nu s-a
verificat (nu apare ca subcuvant de la pozitia respectiva), 1 = s-a verificat.
Dupa initierea tuturor cautarilor, procesul tata asteapta sa i se termine
toti fii si aduna codurile lor de retur - acesta valoarea se afisaza (este
numarul de aparitii ca subcuvant).
A13. (4 puncte) Scriet un program care verifica daca un numar apare sau nu
intr-un vector (numarul se vectorul sunt dati ca argumente in linia de
comanda) printr-o strategie de tip divide et impera: se imparte vectorul in
doua, apoi se initiaza cate un proces fiu care cauta numarul in fiecare
jumatate, in aceeasi maniera; cele doua procese se desfasoara in paralel.
Fiecare subproces returneaza 0 = negasit, 1 = gasit. Fiecare proces nu se
termina pana nu i se termina toti fii si in final returneaza suma valorilor
returnate de ei. Procesul initial trebuie in plus sa afiseze un mesaj de tip
"gasit"/"negasit".
----------
A14. (2 puncte) Scrieti niste programe care arata daca fii obtinuti cu system
ai unui proces "p" mostenesc redirectarile intrari/iesirii standard care au
loc daca lansam "p" in cadrul unui filtru:
... | p | ...
A15.(1.5 puncte) Scrieti niste programe care arata daca fii obtinuti cu system
ai unui proces "p" mostenesc suplimentar eventualele argumente in linia de
comanda cu care a fost lansat "p".
----------
A16. (1 punct) Scrieti un program care afisaza valoarea variabilei de
environment TERM, apoi o asigneaza la valoarea "vt52", apoi genereaza un
proges fiu (cu fork) care afisaza valoarea lui TERM mostenita.
A17. (1 punct) Scrieti un program care sa verifice daca schimbandu-si valoarea
variabilei de environment PWD, functia getcwd returneaza acelasi director
curent.
A18. (2.5 puncte) Scrieti un program care isi concateneaza valoarea fiecarei
variabile de environment de pe pozitie para la sfarsitul valorii variabilei
pe pozitia impara anterioara. Programul isi va afisa environmentul inainte
si dupa aceasta operatie.
A19. (1 punct) Scrieti niste programe care arata daca procesele obtinute cu
o functie din familia exec dintr-un proces "p" mostenesc redirectarile
intrari/iesirii standard care au loc daca lansam "p" in cadrul unui filtru:
... | p | ...
A20. (4 puncte) Scrieti un program "executa" care se lanseaza sub forma:
executa comanda [argumente]
unde "comanda" este specificatorul unui fisier executabil de pe disc iar
"argumente" este un sir de 0 - 3 din urmatoarele constructii (nu conteaza
ordinea):
#0 fisier (avand semnificatia: "< fisier")
#1 fisier (avand semnificatia: "> fisier")
#2 fisier (avand semnificatia: "2> fisier")
(prezenta parantezelor [] arata ca "argumente" poate lipsi) si lanseaza
"comanda" cu redirectarile "argumente". Nu se va folosi system.
A21. (4 puncte) Scrieti un program "filtru" care se lanseaza sub forma:
filtru f1 ... fn
unde f1, ..., fn sunt fisiere executabile de pe disc si lanseaza procesul:
f1 | ... | fn
----------
A22. (4 puncte) Implenetati tipul arbore binar cu varfuri numere intregi alocat
inlantuit (cu pointeri). Scrieti o functie care primeste ca parametru un
arbore (pointer la radacina sa) si afisaza varfurile sale parcurgandu-l pe
nivele. In general algoritmul de parcurgere pe nivele foloseste o coada in
care initial se incarca radacina, apoi intr-un ciclu care tine cat timp coada
e nevida se extrage un varf, se afisaza, apoi se introduc in coada fii lui
(pointeri la radacinile lor). Pe post de coada functia va folosi un fisier
tub fara nume (care va exista doar pe perioada apelului). Scrieti un program
ilustrativ pentru aceasta functie.
A23. (3 puncte) Scrieti un program "nrc" care se lanseaza sub forma:
nrc com
unde "com" este o comanda externa (adica asociata unui fisier executabil de
pe disc) avand eventual si argumente in linia de comanda (deci com este un
sir de cuvinte) si care lanseaza comanda "com", numarand cuvintele scrise
de ea pe standard output. In acest scop procesul "nrc" creaza un tub fara
nume, apoi se bifurca (cu "fork") a.i. intrarea standard a tatalui si iesirea
standard a fiului sa fie in acest tub, apoi fiul se inlocuieste (cu o functie
din familia "exec") cu un proces ce executa "com".
A24. (8 puncte) Scrieti un program "#paralel" care se lanseaza sub forma:
#paralel com1 #, com2 #, ... #, comn #endparalel
(tot ce e dupa "#paralel" sunt argumentele lui), unde com1, ..., comn sunt
comenzi externe (adica asociate unor fisiere executabile de pe disc) avand
eventual si argumente in linia de comanda (deci comi este un sir de cuvinte)
si lanseaza n+2 procese care se desfasoara in paralel:
- cate un proces care executa fiecare dintre comi;
- un proces de intrare care citeste caractere de la intrarea standard si
multiplica fiecare caracter in n copii, pe care le trimite in niste tuburi
conectate fiecare la intrarea standard a uneia din comi (deci fiecare din
comi are intrarea standard redirectata la cate un tub)
- un proces de iesire care citeste caractere dintr-un tub si le scrie la
iesirea standard; la tubul respectiv sunt conectate iesirile standard ale
proceselor comi.
Schema de functionare va fi:
/---> tubi1 ---> com1 ---\
/ \
intrare ........................ ---> tubo ---> iesire
\ /
\---> tubin ---> comn ---/
Tuburile sunt fara nume si exista doar pe perioada executiei acestor procese.
Procesul de intrare are SIGPIPE anihilat, pentru a nu se termina daca comi nu
se termina toate in acelasi timp (si isi inchid tubul de intrare la citire).
Pentru a nu crea confuzii, in scrierea comenzilor comi nu va aparea #.
Aplicati programul "#paralel" pentru a crea generalizari ale comenzilor filtru
in care in loc de un lant com1 | ... | comn avem un graf.
D1. (4 puncte) Program care primeste ca argument in linia de comanda un
director si afisaza arborescenta de directoare si fisiere cu originea
in el (similar comenzii tree /f din DOS).
D2. (4 puncte) Program care primeste ca argument in linia de comanda un
director si calculeaza suma dimensiunilor fisierelor din arborescenta cu
originea in el.
D3. (4 puncte) Program care primeste ca argumente in linia de comanda un
fisier f si un director d si determina daca fisierul f se afla (ca nume)
in arborescenta cu originea in d; in caz afirmativ se va determina numarul
de aparitii.
D4. (8 puncte) Program care primeste ca argumente in linia de comanda doua
directoare d1 si d2 si determina fisierele care apar (ca nume + cale)
intr-o arborescenta si nu apar in cealalta.
D5. (4 puncte) Program care primeste ca argument in linia de comanda un
director si sterge (recursiv) toata arborescenta cu originea in el.
D6. (4 puncte) Program care primeste ca argument in linia de comanda un
director d si sterge toate fisierele terminate in ".out" care apar in
arborescenta cu originea in d.
D7. (8 puncte) Program care primeste ca argumente in linia de comanda doua
directoare d1 si d2 (d1 exista, d2 nu) si copiaza recursiv toata
arborescenta cu originea in d1 intr-o arborescenta cu originea in d2
(intre cele doua arborescente difera doar numele directorului origine).
D8. (2 puncte) Program care tipareste pe stderr toate mesajele de eroare ce
se pot obtine cu functia "perror", precedate de valoarea corespunzatoare a
variabilei "errno". Cu ajutorul lui sa se obtina un fisier cu aceste mesaje.
D9. (4 puncte) Sa se creeze un fisier "myperror.i", care sa contina
definitia unei functii "void myperror(const char *s)", care tipareste
pe stderr stringul "s", apoi ":", apoi mesajul de eroare corespunzator
valorii curente din variabila "errno" dar tradus in romana. In acest scop
se poate folosi fisierul creat la problema D8. Scrieti un program care sa
includa "myperror.i" si sa foloseasca functia "myperror" intr-un context
similar celui in care se foloseste "perror"; in urma rularii acestui
program sa se poata observa modul de functionare al funtiei "myperror".