Termen de predare: 5.12.2019, ora 23:55
Pentru fiecare zi (24 de ore) de întârziere, se vor scădea 10 puncte din nota acordată. Temele trimise după 7 de zile de întârziere vor putea fi notate cu maxim 30 de puncte.
În consecință, deadline-ul hard este 12.12.2019, ora 23:55.
Dacă aveți nelămuriri, puteți să ne contactați pe forumul dedicat temei de casă nr. 2.
La orice întrebare vom răspunde în maximum 24 de ore.
Nu se acceptă întrebări în ultimele 24 de ore înainte de deadline.
Căpitanul Licurici primește postul de redactor al revistei clubului de literatură al UPB datorită experienței acumulate la Grădinița cu program prelungit nr. 42 ca editor de poezii pentru copii. Deși n-au trecut nici 2 luni de când a început lucrul, căpitanul Licurici e copleșit de volumul mare de muncă la care este supus, primind zeci de poezii în fiecare zi.
Acest lucru nu e deloc surprinzător, având în vedere că studenții de la Calculatoare, în special cei care sunt aici deja de 3, 4 sau chiar 5 ani, au realizat că viața lor nu începe cu #include și nu se termina cu return 0 și că pot fi persoane echilibrate care au timp și de alte activități.
Planul sună foarte bine, însă asta nu face viața la Poli mai ușoară, o face doar mai frumoasă. Adevărul e că uneori unii studenți au fost nevoiți să nu doarmă câteva nopți pentru a termina o temă înainte de deadline, așa că și poeziile trimise de ei căpitanului Licurici indică semne de oboseală.
Căpitanul Licurici vă roagă să îi scrieți un program care să îi ușureze munca și să automatizeze acest proces de corectare a poeziilor trimise.
Deoarece nu se pricepe să lucreze cu codul sursă, vă roagă să îi scrieți și o consolă interactivă prin care să poată preciza ce tip de procesare vrea să aplice și să obțină automat output-ul dorit.
Mai multe detalii despre această consolă interactivă odată ce vor fi prezentate toate cerințele aplicației.
Poezia primită s-ar putea să nu respecte norma tradițională de a începe fiecare vers cu majusculă. E posibil ca în mijlocul versului să se fi apăsat shift din greșeală și să apară majuscule în mijlocul cuvintelor. În acest caz, programul scris va trebui să corecteze fiecare vers astfel încât primul cuvânt să înceapă cu majusculă, restul caracterelor alfabetice din vers să fie literă mică.
Exemplu:
trecE lebăDA pe ape
devine:
Trece lebăda pe ape
Din cauza oboselii, studenții au mai ațipit cu capul pe tastatură sprijiniți de cea mai mare tastă - Space. Acest lucru duce la spații prea mari între unele cuvinte, spații ce trebuie eliminate. Căpitanul Licurici vă roagă să identificați poeziile cu o spațiere nefirească și să eliminați acest whitespace redundant, astfel încât dacă între două cuvinte consecutive erau mai multe spații, acum va rămâne unul singur. În unele cazuri, studenții au mai adormit și pe alte taste, așa că pe lângă eliminarea a whitespace redundant se cere și eliminarea tuturor aparițiilor următoarelor caractere non-alfabetice: {‘.’, ‘,’, ‘;’, ‘!’, ‘?’, ‘:’}
Exemplu:
Trece ;;, lebăda pe ....?? ape
devine:
Trece lebăda pe ape
Căpitanul Licurici decide să îi înveselească puțin pe studenți și să le ia gandul de la iminența deadline-urilor, așa că decide să facă poeziile mai haioase. Pentru moment, doar va face schimbări aleatoare din literă mare în literă mica și invers, astfel încât versul “Trece lebăda pe ape” se va transforma în “tReCE LeBădA Pe aPe”. Mai exact fiecare caracter are probabilitate p de a se schimba din majusculă / minusculă în complementara ei. Probabilitatea p va fi un parametru dat funcției.
float sample = rand() % 100 / 99.0;
Nu uitati de: srand(42); la începutul programului!
Tot cu intenția de a mai distra studenții, redactorul vostru preferat vrea să înlocuiască unele cuvinte cu diminutivele lor. Pentru că formarea diminutivelor se bazează pe reguli mai complicate, colegii vostri mai mari au decis să dea o mână de ajutor și să oferă o bibliotecă helper ce implementează funcția de conversie către diminutiv:
void get_friendly_word(const char *word, char **friendly_word);
Această funcție primește ca parametru cuvântul word și returnează în friendly_word diminutivul corespunzător sau NULL în cazul în care nu s-a găsit un diminutiv. Implementarea voastră trebuie sa treacă pe rând prin toate cuvintele din poezie, să apeleze această funcție și dacă rezultatul întors este diferit de NULL să se facă replace cu acesta în locul cuvântului aflat inițial în poezie.
De ex, versul “Trece lebăda pe ape” se va transforma în “Trece lebăduța pe ape” considerând că doar apelul pentru cuvantul “lebăda” a întors un rezultat.
Cu toate încercările de a aduce o urmă de zâmbet, căpitanul Licurici nu e convins că a fost suficient de eficient. Dar ce poate bucura pe cineva mai tare decât un generator automat de rime? Pentru o poezie primită se va încerca formarea de rime fără a schimba semantica.
Pentru catrene, există 3 tipuri tradiționale de rimă:
Presupunem că această funcție primește ca parametru și tipul de rimă pe care dorește să îl obțină.
Pentru tipul de rimă “încrucișată” și următoarea poezie, algoritmul va fi:
A fost odata ca-n basme
A fost ca niciodată,
Din rude mari împăratești,
O prea frumoasă duduie.
Se observă că “basme” nu rimează cu perechea lui - “împărătești”. Se cere de la biblioteca helper lista de sinonime și se primește {“zvonuri”, “povești”} și se alege “povești” pentru că e mai mic lexicografic. Cuvântul “niciodată” nu rimează cu corespondentul lui - “duduie”, însă în lista de sinonime întoarsă de bibliotecă nu s-a găsit nici un sinonim pentru “niciodată”. Astfel, vom încerca să formăm rima din partea cealaltă. Pentru “duduie” primim lista {“puștoaică”, “fată”}. Alegem “fată” pentru că este cuvântul cel mai mic lexicografic care asigură rima.
Rezultatul final obținut în urma înlocuirilor va fi:
A fost odată ca-n povești
A fost ca niciodată,
Din rude mari împarătești,
O prea frumoasă fată.
Se va înlocui “nicicând” cu “niciodată”, dar virgula de la finalul primului vers va fi păstrată. Se obține:
A fost ca niciodată,
O prea frumoasă fată.
Se va implementa un parser al liniei de comandă pentru a putea lucra interactiv cu transformările descrise în cerințele de mai sus și pentru a putea vedea la fiecare pas output-ul rezultat. Programul scris va citi în continuu de la standard input și va putea primi următoarele comenzi, pentru fiecare din ele trebuind sa apeleze funcția de la cerința corespunzătoare.
În cadrul scheletului este oferit și o bibliotecă statică (mai multe detalii în anul 3 SO). Trebuie să adăugați header-ul task_helper.h din folderul util în programul vostru.
/* * Load a file inside a given buffer * @param file - name of the file to be read * @param buffer - initialised vector to hold the content of the file */ void load_file(const char *file, char *buffer); /* * Returns a list of synonym words and its length based on a given word. * @param word - the given word * @param n - the length of the returned list * @param word_list - returns the pointer to a list filled with synonym words having the length n */ void get_synonym(const char *word, int *n, char ***word_list); /* * Receives a word and returns the pointer to a location of memory that holds a friendly word * @param word - the given word * @param friendly_word - returns the pointer to a memory where the word is located */ void get_friendly_word(const char *word, char **friendly_word);
Tema va fi trimisă folosind vmchecker, cursul Programarea Calculatoarelor (CB & CD).
Găsiți poeme pentru temă aici.
Găsiți scheletul temei si makefile-ul aici.
Găsiți arhiva cu checker-ul aici.
Punctajul:
După cum probabil ați observat, task-urile au un total de 150 de puncte, dar motivul pentru acest lucru este ca fiecare test să valoreze 2.5 punct. Dacă soluția voastră trece toate testele veți acumula un total de 1.25 puncte (din nota finală). Celelalte 0.25 puncte se vor acorda pentru coding style si README.
Formatul arhivei va fi următorul:
Lista nu este exhaustivă.