Tema 1 - Now You See Me

Responsabili:

  • Data publicării: 21.03.2022
  • Deadline HARD: 10.04.2022 23:55:00

Actualizări

  • Adăugare clarificări structură de date generică: 25.03.2022
  • Adăugare schelet README: 24.03.2022

Obiective

  • Aprofundarea cunoștințelor în utilizarea limbajului C.
  • Implementarea și utilizarea structurii de date lista dublu inlantuita .
  • Familiarizarea cu implementarea unei structuri de date generice.

Introducere

“The closer you think you are, the less you'll actually see.”

Faimosul grup de iluzionisti pune la cale un nou show pentru care au nevoie de cei mai experimentați voluntari. Plictisiți de monotonia de la facultate și dornici să experimentați ceva nou, ați luat decizia să mergeți și voi la preselecții.

Pentru a putea lua parte la acest spectacol, veți fi supuși unor teste ce implică trucuri cu cărți. Scopul vostru este să demonstrați că sunteți capabili să impresionați membrii grupului și să vă câștigați locul în show.

Cerință

Veți primi de la unul din membrii grupului mai multe pachete de cărți pe care le veți ține într-o listă dublu înlănțuită. În cadrul fiecărui pachet, cărțile sunt ținute sub forma unei liste dublu înlănțuite.

Fiecare carte are două proprietăți: valoare (în intervalul [1, 14]) și simbol (HEART, CLUB, DIAMOND, SPADE).

Pentru a vă testa abilitățile, membrii grupului vă vor da, pe rând, diverse comenzi pe care va trebui să le executați asupra pachetelor. Aveți grijă însă, trebuie să realizați perfect trucurile pentru a îi convinge pe magicieni că vă meritați locul!

Comenzi posibile (30p)

  • ADD_DECK <număr_cărți>
    • adaugă un nou pachet de <număr_cărți> cărți la finalul listei de pachete.
    • comanda este urmată de cel puțin <număr_cărți> perechi {valoare, simbol}, dintre care se vor adăuga în pachet primele <număr_cărți> perechi valide.
    • în momentul în care pachetul construit ajunge la capacitatea <număr_cărți>, pachetul va fi inserat în lista de pachete.
    • dacă cartea introdusă este una invalidă, se va afișa eroarea INVALID_CARD (vezi secțiunea dedicată erorilor).
    • după adăugarea pachetului în lista de pachete se va afișa mesajul: “The deck was successfully created with <număr_cărți> cards.\n”.
  • DEL_DECK <index_pachet>
    • șterge pachetul <index_pachet> din lista de pachete.
    • după finalizarea comenzii se va afișa mesajul: “The deck <index_pachet> was successfully deleted.\n”.
  • DEL_CARD <index_pachet> <index_carte>
    • șterge cartea <index_carte> din pachetul <index_pachet>
    • dacă în urma comenzii pachetul rămâne fără cărți, acesta este șters din lista de pachete.
    • după finalizarea comenzii se va afișa mesajul: “The card was successfully deleted from deck <index_pachet>.\n”.
  • ADD_CARDS <index_pachet> <număr_cărți>
    • adaugă în pachetul <index_pachet> <număr_cărți> cărți.
    • comanda este urmată de cel puțin <număr_cărți> perechi {valoare, simbol}, dintre care se vor adăuga la finalul pachetului <număr_cărți> perechi valide.
    • după adăugarea celor <număr_cărți> cărți se afișează mesajul: “The cards were successfully added to deck <index_pachet>.\n”.
  • DECK_NUMBER
    • afișează câte pachete de cărți se află în listă
    • după finalizarea comenzii se va afișa mesajul: “The number of decks is <număr_pachete>.\n”.
  • DECK_LEN <index_pachet>
    • afișează lungimea pachetului <index_pachet>
    • după finalizarea comenzii se va afișa mesajul: “The length of deck <index_pachet> is <număr_cărți>.\n”.
  • SHUFFLE_DECK <index_pachet>
    • inversează prima și a doua jumătate a pachetului <index_pachet>.
    • prima jumătate conține primele n/2 cărți, iar a doua jumătate contine n/2 cărți (n par) sau n/2 + 1 carti (n impar), unde n este numărul de cărți din pachet.
    • după finalizarea comenzii se va afișa mesajul: “The deck <index_pachet> was successfully shuffled.\n”.

Exemplu:

Pachet 0: 1, 2, 3, 4, 5
Rezultat: 3, 4, 5, 1, 2

  • MERGE_DECKS <index_pachet_1> <index_pachet_2>
    • combină pachetele <index_pachet_1> și <index_pachet_2> luând câte o carte din fiecare pachet, rând pe rând.
    • ele două pachete combinate vor fi șterse, iar pachetul rezultat va fi adăugat la finalul listei de pachete.
    • după finalizarea comenzii se va afișa mesajul: “The deck <index_pachet_1> and the deck <index_pachet_2> were successfully merged.\n”.

Exemplu:

Pachet 0: 1, 2, 3, 4
Pachet 1: 4, 5, 6, 7, 11, 12, 13
Rezultat: 1, 4, 2, 5, 3, 6, 4, 7, 11, 12, 13

  • SPLIT_DECK <index_pachet> <index_split>
    • împarte pachetul <index_pachet> după indexul <index_split>.
    • primul pachet rezultat va rămâne la <index_pachet>, iar al doilea pachet rezultat se va insera la pozitia <index_pachet> + 1.
    • dacă în urma comenzii rezultă un pachet gol și un pachet ce contine toate cărțile (index_split = 0), se va păstra doar pachetul ce contine cărți.
    • după finalizarea comenzii se va afișa mesajul: “The deck <index_pachet> was successfully split by index <index_split>.\n”.

Pachet 0: 1, 2, 3, 4
Pachet 1: 7, 8, 9
Pachet 2: 12, 13, 14
SPLIT_DECK 0 2
Rezultate: 
	Pachet 1a: 1, 2
	Pachet 1b: 3, 4
	Pachet 2: 7, 8, 9
	Pachet 3: 12, 13, 14

  • REVERSE_DECK <index_pachet>
    • inversează ordinea cărților din pachetul <index_pachet>.
    • după finalizarea comenzii se va afișa mesajul: “The deck <index_pachet> was successfully reversed.\n”.
  • SHOW_DECK <index_pachet>
    • afișează cărțile din pachetul <index_pachet>.
    • structura: <index_pachet> - {valoare1, simbol1}, {valoare2, simbol2}, etc..
    • mesajul afișat pe ecran va fi de forma:
      • Deck <index_pachet>:\n
        \t<valoare_carte1> <simbol_carte1>\n
        \t<valoare_carte2> <simbol_carte2>\n
        \t<valoare_carte3> <simbol_carte3>\n
        …
  • SHOW_ALL
    • afișează toate cărțile din toate pachetele.
    • mesajul afișat pe ecran va fi de forma:
      • Deck <index_pachet1>:\n
        \t<valoare_carte1> <simbol_carte1>\n
        \t<valoare_carte2> <simbol_carte2>\n
        \t<valoare_carte3> <simbol_carte3>\n
        …
        Deck <index_pachet2>:\n
        \t<valoare_carte1> <simbol_carte1>\n
        \t<valoare_carte2> <simbol_carte2>\n
        \t<valoare_carte3> <simbol_carte3>\n
        …
        Deck <index_pachet3>:\n
        \t<valoare_carte1> <simbol_carte1>\n
        \t<valoare_carte2> <simbol_carte2>\n
        \t<valoare_carte3> <simbol_carte3>\n
        …
  • EXIT
    • comanda exit va opri execuția programului.

Tratarea erorilor (50p)

La primirea comenzilor de la tastatură pot apărea unele erori:

  • DECK_INDEX_OUT_OF_BOUNDS
    • această eroare apare atunci când indexul pachetului din comandă nu există.
    • mesajul afișat: “The provided index is out of bounds for the deck list.\n”.
  • CARD_INDEX_OUT_OF_BOUNDS
    • această eroare apare atunci când indexul cărții din comandă nu există.
    • mesajul afișat: “The provided index is out of bounds for deck <index_pachet>.\n”.
  • INVALID_CARD
    • această eroare apare dacă se încearcă introducerea unei cărți care nu are valoarea în intervalul [1, 14] sau simbolul in lista [“HEART”, “SPADE”, “CLUB”, “DIAMOND”].
    • mesajul afișat: “The provided card is not a valid one.\n”.
  • INVALID_COMMAND
    • această eroare apare atunci când este introdusă o comandă inexistentă sau atunci când numărul de parametri este incorect.
    • mesajul afișat: “Invalid command. Please try again.\n”.

Erorile de index aduc după sine suspendarea execuției restului comenzii!

Bonus (10p)

  • SORT_DECK <index_pachet>
    • sortează pachetul <index_pachet> după valoarea cărților de joc.
    • dacă au aceeași valoare, prioritatea simbolurilor va fi: {HEART, SPADE, DIAMOND, CLUB} (inima rosie va avea cea mai mare prioritate, iar trefla cea mai mica).
    • după finalizarea comenzii se va afișa mesajul: “The deck <index_pachet> was successfully sorted.\n”.

README (20p)

  • Fișierul de README va avea numele README sau README.md și va fi pus în rădăcina arhivei. În acest fișier veți detalia implementarea voastră, ce vi s-a părut interesant și care a fost cea mai dificilă parte a temei.
  • Găsiți aici un model de README pe care vă rugăm să îl respectați pe cât posibil.

Coding Style (10p)

Mențiuni

  • Indexarea se face de la 0 pentru orice tip de listă.
  • Alocarea memoriei se va realiza dinamic. Alocarea statică a bufferelor a căror dimensiune nu se cunoaște la compile-time, atrage dupa ea depunctări.
  • Se cere ca structura de date folosită să fie generică. Pentru implementare lipsită de genericitate, se vor pierde 20p din totalul temei.

  • O structură de date generică are rolul de a nu duplica (pe cât posibil) cod permițând adăugarea în cadrul ei a oricărui tip de date. (hint: void*)
  • Exemplu: Vedeți în cadrul scheletului de lab unde a trebuit să implementați exact această situație. (hint: data_size)

  • Nu este indicată utilizarea variabilelor globale. Utilizarea acestora aduce pierderea a 20p din totalul temei.
  • Eliberarea memoriei se va verifica folosind utilitarul Valgrind. O temă ce conține memory leaks va atrage după sine punctaj de 0p pe testul respectiv.

Checker

Teste: 2022-tema1-check.zip.

Temele vor fi trimise pe vmchecker. Atenție! Temele trebuie trimise în secțiunea Structuri de Date (CA).

Arhiva trebuie să conțină:

  • sursele .c și .h
  • fișier Makefile cu două reguli:
    • regula build: în urma căreia se generează un executabil numit tema1
    • regula clean care şterge executabilul si fișierele obiect
  • Compilarea trebuie sa se realizeze cu flagurile -Wall -Wextra -std=c99
  • fișier README care să conțină detalii despre implementarea temei
sd-ca/2021/teme/tema1-2022.txt · Last modified: 2022/10/03 15:10 (external edit)
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