Differences

This shows you the differences between two versions of the page.

Link to this comparison view

programare:laboratoare:lab12 [2025/12/14 02:33]
darius.neatu [Exerciții]
programare:laboratoare:lab12 [2026/01/11 17:19] (current)
teodor.birleanu [PCLP Laborator12: Optimizarea programelor cu operații pe biți]
Line 2: Line 2:
  
 **Responsabili:​** **Responsabili:​**
-  * [[neatudarius@gmail.com|Darius Neațu (2019 - Prezent )]]+  * [[neatudarius@gmail.com|Darius Neațu (2019 - Prezent)]]
   * [[ion_dorinel.filip@cti.pub.ro|Dorinel Filip (2019 - Prezent)]]   * [[ion_dorinel.filip@cti.pub.ro|Dorinel Filip (2019 - Prezent)]]
 +  * [[teodor.matei.birleanu@gmail.com|Bîrleanu Teodor Matei (2025 - prezent)]]
   * [[rares96cheseli@gmail.com|Rareș Cheșeli (2017 - 2018)]] ​   * [[rares96cheseli@gmail.com|Rareș Cheșeli (2017 - 2018)]] ​
  
Line 445: Line 446:
 </​spoiler>​ </​spoiler>​
  
 +==== Exerciții ====
 +Exercițiile pentru laborator se găsesc pe [[https://​acs-pclp.github.io/​laboratoare/​12 | PPCLP Laborator12:​ Optimizarea programelor cu operații pe biți]].
  
-==== Exerciții ​ ==== 
- 
-==Precizari generale== 
-Rezolvați împreună cu asistentul pe tablă, exercițiile 0-4, apoi rezolvați invidual exercițiul 5. 
- 
-== 0: Verificare că un număr e par == 
-Să se verifice folosind operații pe biți că un număr natural n e par. 
-<code C> 
-int is_even(int n); 
-</​code>​ 
- 
-== 1. Calcul putere a lui 2 (0p) == 
-Să se scrie o funcție care să calculeze $2^n$, unde $ n <= 30 $. 
-<code C> 
-int pow2(int n); 
-</​code>​ 
-Răspundeți la întrebarea:​ **are sens** să scriem o funcție? 
- 
-== 2. Negarea biților unui număr n (0p) == 
-Să se scrie o funcție care să nege biții unui număr n (32 biți). 
-<code C> 
-int flip_bits(int n); 
-</​code>​ 
-Răspundeți la întrebarea:​ **are sens** să scriem o funcție? 
- 
-== 3. Afișarea biților unui număr n (0p)== 
-Să se scrie o funcție care să afișeze toți biții unui număr întreg pe 32 biți. 
-<code C> 
-void print_bits(int n); 
-</​code>​ 
- 
- 
-== 4. Verificare că un număr este putere al lui 2 (0p)== 
-Să se scrie o funcție care verifică dacă un număr întreg n pe 32 biți este puterea a lui 2. Funcția va returna 1 dacă n este putere a lui 2, 0 altfel. 
-<code C> 
-int is_power2(int n); 
-</​code>​ 
- 
-<spoiler Hint> 
-Analizați reprezentarea în baza 2 a lui n (ex. n = 16 si n = 5). 
-</​spoiler>​ 
- 
- 
- 
- 
-\\ 
-Implementați invidual următoarea problemă. 
- 
- 
-== 5. bitset (10p )== 
-O mulțime de numere întregi poate fi reprezentată astfel: spunem că un număr **i ** aparține unei mulțimi S dacă bit-ul al i-lea din vectorul S are valoarea 1.  
- 
-Pentru e ficientă,​ vectorul S va conține date de tipul **unsigned char** (reamintim ca **sizeof(unsigned char) == 1 byte** adică **8 biți**). 
- 
-<​note>​ 
-Pentru a folosi cu ușurință același cod facând schimbări minime (de exemplu schimbăm dimensiunea maximă a unei mulțimi), putem să ne definim propriul tip astfel: 
- 
-<code C> 
-#define SET_SIZE 100                   // aceasta este o macrodefiniție (momentan o putem privi ca pe O CONSTANTA CARE ARE VALOAREA 100 
-typedef unsigned char SET[SET_SIZE]; ​  // definesc tipul SET, care este un vector cu maxim 100 de elemente de tip unsigned char 
-</​code>​ 
- 
-Cele două linii de mai sus vor fi puse imediat dupa includerea directivelor header! 
- 
-</​note>​ 
- 
- 
- 
-=== 5.1 === 
-    
-Implementați următoarele funcții. Realizați un program în C prin care să demonstrați că funcțiile implementate funcționează. 
- 
-<​note>​ 
-Există un [[https://​ocw.cs.pub.ro/​courses/​programare/​laboratoare/​lab12-bitset-example | exemplu]] detaliat care vă explică cum functionează aceastea. 
- 
-Treceți la subpunctul următor abia după ce v-ați asigurat că acestea funcționează. 
-</​note>​ 
- 
-      * **adăugarea** unui element în mulțime 
-      <code C>  
-      // insert_in_set(s,​ n) - adauga numarul n in multimea s 
-      void insert_in_set(SET s, unsigned int n); 
-      </​code>​ 
- 
-      * **ștergerea** unui element din mulțime 
-      <code C> 
-      // delete_from_set(s,​ n) - scoate numarul n din multime s 
-      void delete_from_set(SET s, unsigned int n); 
-      </​code>​ 
- 
-      * **verificarea** faptului că un element n **aparține** unei mulțimi 
-      <code C> 
-      // is_in_set(s,​ n) - returneaza 1 daca n este in s, 0 altfel 
-      int is_in_set(SET s, unsigned int n); 
-      </​code>​ 
- 
-      * **ștergerea** tuturor elementelor din mulțime 
-      <code C> 
-      // delete_all_from_set(s) - elimina toate elementele din multime 
-      void delete_all_from_set(SET s); 
-      </​code>​ 
- 
-      * calcularea **cardinalul** unei mulțimi 
-      <code C> 
-      // card_set(s) - returneaza cardinalul multimii s 
-      int card_set(SET s); 
-      </​code>​ 
- 
-      * verificarea faptului că mulțimea este **vidă** 
-      <code C> 
-      // is_empty_set(s) - verifica daca multimea este sau nu goala 
-      // returneaza 1 daca este, 0 daca nu este 
-      int is_empty_set(SET s); 
-      </​code>​ 
- 
-      * o funcție care **să citească de la tastatură** ​ o mulțime 
-      <code C> 
-      // read_set(s) - functia citeste numarul n de elemente care se afla in a 
-      // apoi citeste cele n numere si le insereaza in a 
-      // va returna numarul n citit (numarul de elemente) 
-      int read_set(SET s); 
-      </​code>​ 
- 
-      * o funcție care **să afișeze** pe ecran elementele care se află într-o mulțime 
-      <code C> 
-      // print_set(s) - functia printeaza elementele multimii s 
-      void print_set(SET s); 
-      </​code>​ 
-      ​ 
-Urmăriți acest [[https://​ocw.cs.pub.ro/​courses/​programare/​laboratoare/​lab12-bitset-example | exemplu cu bitset]] ​ pentru a înțelege cum funcționează aceste operații. ​     ​ 
- 
-=== 5.2 === 
-Realizati un program care, utilizând metodele de fite anterior, citește 2 mulțimi A (n și B și a fișează:​ $ A U B, A ∩ B, A - B, B - A $. 
- 
-Pentru a realiza acest lucru, va trebui să implementați următoarele funcții: 
-      * **reuniunea** a două mulțimi (**1p**) 
-      <code C> 
-      // c = a U b 
-      void merge_set(SET a, SET b, SET c); 
-      </​code>​ 
- 
-      * **intersecția** a două mulțimi (**1p**) 
-      <code C> 
-      // c = a n b 
-      void intersect_set(SET a, SET b, SET c); 
-      </​code>​ 
- 
-      * **diferența** a două mulțimi (**1p**) 
-      <code C> 
-      // c = a \ b 
-      void diff_set(SET a, SET b, SET c); 
-      </​code>​ 
- 
-În final va trebui sa creați o funcție ** main ** și să faceți un program care rezolvă cerința folosind funcțiile implementate. 
- 
-==== B1. Optimizations ==== 
-O să învățați pe viitor că nu toate înstrucțiunile sunt la fel din punct de vedere al timpului de execuției. Ca un punct de start, gândiți-vă că dacă ați face pe foaie o adunare sau o înmultire, durează mai mult să înmulțiți decât să adunați. Această dificulate o are și procesorul din laptopul vostru! 
- 
-Pentru a-l ajuta și a face programul mai rapid, putem înlocui operații costisitoare (** * **, ** / **) cu altele mai puțin costistoare (** + **, ** - **). Cele mai rapide instrucțiuni sunt cele care lucrează direct pe biți (deoarece numerele sunt stocate în memorie în binar, deci este modul natural de lucru pentru calculator). 
- 
-Acest exercițiu vă propune să aplicați aceste optimizări pe codul vostru! ​ 
- 
-<spoiler Hint> 
-Pentru a completa acest bonus, **NU** aveți voie să folosiți operatorii ** /, *, % ** ! Încercați să folosiți operații pe biți! ​ 
-</​spoiler>​ 
- 
-==== B2. MSB/LSB ==== 
-Să se scrie o câte o funcție pentru aflarea MSB(Most significant bit), respectiv LSB(Least significant bit), pentru un număr n pe 32 biți. 
-<code C> 
-int get_lsb(int n); 
-int get_msb(int n); 
-</​code>​ 
- 
-<spoiler Hint> 
-Analizați reprezentarea în baza 2 a lui n. 
-</​spoiler>​ 
- 
- 
- 
-==== Probleme de interviu ==== 
-Pentru cei interesați,​ recomandăm rezolvarea și următoarelor probleme, care sunt des întâlnite la interviuri. 
-<note warning> 
-Atenție! Problemele din această categorie au un nivel de dificultate ridicat, peste cel cerut la cursul de PC. 
- 
-Recomandăm totuși rezolvarea acestor probleme pentru cei care doresc să aprofundeze lucrul cu operații pe biți. 
-</​note>​ 
- 
-<spoiler Swap bits> 
-Se dă un număr n natural pe 32 de biți. Se cere să se calculeze numărul obținut prin interschimbarea biților de rang par cu cel de rang impar. 
- 
-Exemplu: n = 2863311530 = > m = 1431655765 
- 
-<​note>​ 
-Hint: Reprezentarea numerelor în baza 2 ([http://​www.binaryhexconverter.com/​decimal-to-binary-converter | convertor]]). 
-</​note>​ 
- 
-</​spoiler>​ 
- 
-<spoiler Element unic din șir> ​ 
-Fie un șir cu ** 2n + 1 ** numere întregi, dintre care n numere apar de câte 2 ori, iar unul singur este unic. 
-Să se gasească elementul unic.  
- 
-Exemplu: 
-        n = 5 și sirul [1, 4, 4, 1, 5] 
-        Numărul unic este 5.  
-<​note> ​       ​ 
-Hint: Încercați să nu folosiți tablouri. 
-</​note>​ 
- 
-Follow-up 1: Șirul are $2*n + (2 * p + 1)$ numere. Se sție că un singur număr apare de un număr impar de ori (2p + 1), iar celelalte apar de un număr par de ori. Cum găsiți numărul care apare de un număr impar de ori? 
- 
-Exemplu: 
-        n = 5 și sirul [1, 1, 4, 4, 4, 4, 5, 5, 5] 
-        Răspunsul este 5. 
-          
-Follow-up 2: Șirul are $2n + 2$ numere, n numere apar de câte 2 ori, iar 2 numere sunt unice. Cum găsiți cele 2 numer unice? 
- 
-Exemplu: 
-        n = 5 și sirul [1, 4, 4, 1, 5, 6] 
-        Numărele unice sunt 5 și 6.  
- 
-TODO: sursă ​       ​ 
-</​spoiler>​ 
- 
-<spoiler Căutare binară pe biți> 
-Realizează o funcție de căutare pe binară, utilizând operații pe biți pentru optimizarea acestei implementări. 
- 
-Follow up: Puteți găsi alt algoritm care să nu se bazeze pe împarțirea vectorului în două și compararea elementului din mijloc cu cel cautat? 
- 
-<​note>​ 
- Hint: 
-[[http://​www.infoarena.ro/​problema/​cautbin | caut bin]] și [[http://​www.infoarena.ro/​multe-smenuri-de-programare-in-cc-si-nu-numai | Multe "​smenuri"​ de programare in C/C++... si nu numai!]] 
-</​note>​ 
- 
-</​spoiler>​ 
- 
- 
- 
-<spoiler Jocul NIM> ​ 
-Se dau n grămezi, fiecare conţinând un anumit număr de pietre. Doi jucători vor începe să ia alternativ din pietre, astfel: la fiecare pas, jucătorul aflat la mutare trebuie să îndepărteze un număr nenul de pietre dintr-o singură grămadă. Câştigătorul este cel care ia ultima piatră. 
-Să se determine dacă jucătorul care ia primele pietre are strategie sigură de câştig. 
- 
-Exemple 
-       n = 4, gramezi = [1 3 5 7], raspuns = NU 
-       n = 3, gramezi = [4 8 17],  raspuns = DA 
- 
-<​note>​ 
-Hint: [[http://​www.infoarena.ro/​problema/​nim | nim]] 
-</​note>​ 
- 
-</​spoiler>​ 
- 
-<spoiler Sushi> 
-Enunt: [[http://​www.infoarena.ro/​problema/​sushi | sushi ]] 
-</​spoiler>​ 
  
programare/laboratoare/lab12.1765672430.txt.gz · Last modified: 2025/12/14 02:33 by darius.neatu
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0