Eat & drink & code

Încă din momentul în care au devenit colegi de apartament, conviețuirea dintre Leonard și Sheldon s-a bazat pe un contract de apartament, întocmit și redactat cu atenție de Sheldon.

În ultimele luni Leonard, datorită unor modificări în cadrul laboratorului din universitate, este nevoit să lucreze un timp semnificativ de acasă. Sheldon, fiind foarte atent la cantitatea de snacks-uri și sucuri pe care le deține din frigiderul comun, a sesizat că Leonard are obiceiul de a consuma și a nu le înlocui.

eat&drink

Cum acest aspect nu este prevăzut în contractul celor doi colegi de apartament, Sheldon petrece câteva nopți pentru a adăuga secțiunea corespunzătoare: un automat de snacks-uri și sucuri programabil, astfel încât Leonard, împreună cu musafirii săi, să achite corespunzător consumul făcut.

Întrucât singurul care are skill-uri de engineering (dintre cercul lor restrâns de prieteni) este Howard,  Leonard a reușit să ajungă la o înțelegere cu acesta.

Cerință

Task-ul vostru este să îl ajutați pe Howard să implementeze acest automat.

Howard a primit de la Sheldon specificațiile cu care automatul trebuie să funcționeze și le-a scris într-un fișier antet (.h), pentru limbajul C.

#ifndef __AUTOMAT_H
#define __AUTOMAT_H
#define MAX_NUMBER_OF_PRODUCTS 100

/**
 * Tipurile de bancnote disponibile.
*/
typedef enum { _1_DOLLAR = 1, _5_DOLLARS = 5, _10_DOLLARS = 10, _50_DOLLARS = 50 } bill_type;

/**
* Setează numărul de bancnote disponibile din tipul dat.
*/
void set_available_bills(bill_type bill, int count);

/**
* Întoarce numărul de bancnote disponibile de un anumit tip.
* (-1, daca tipul respectiv de bancnote nu exista).
*/
int get_available_bills(bill_type bill);

/**
* Setează numărul de produse disponibile. Inițial, acest
* număr trebuie sa fie 0.
*/
void set_number_of_products(int count);

/**
* Întoarce numărul total de produse disponibile.
* Este vorba de numărul total de produse, indiferent de cantitate.
*/
int get_number_of_products();

/**
* Întoarce costul unui anumit produs, dat prin codul său.
* Fiecare produs este identificat printr-un cod unic.
*/
int get_product_cost(int code);

/**
* Setează costul unui produs.
*/
void set_product_cost(int code, int cost);

/**
* Setează cantitatea disponibilă a unui anumit produs.
*/
void set_product_quantity(int code, int quantity);

/**
* Întoarce cantitatea disponibilă a unui anumit produs.
*/
int get_product_quantity(int code);

/**
* Cere un produs.
*
* Următoarele coduri de eroare trebuie întoarse, în diferite situații:
* 	-1 -- a fost cerut un produs care nu există (cod invalid)
* 	-2 -- produsul nu mai este disponibil (cantitate = 0)
* 	-3 -- insuficienți bani introduși pentru a cumpară produsul.
* 	-4 -- imposibil de returnat rest cu bancnotele disponibile.
* 
* Dacă nu se întoarce un cod de eroare, request_product va întoarce
* suma totală pe care ar putea să o ofere drept rest, în cazul în care
* request_change este apelată imediat dupa aceea. Intern, bancnotele
* disponibile nu vor fi modificate până la apelul request_change.
*/
int request_product(int code);

/**
* Cere restul.
*
* Notă: acest automat este special, în sensul ca un client poate sa
* nu ceară întotdeauna rest, sau să uite!
*
* Daca funcția este apelată după request_product (*doar dacă* cumpărătorul
* dorește să facă asta) i se va întoarce restul disponibil.
*
* Daca request_product nu a fost apelat și au fost bani introduși,
* această funcție va întoarce aceeași sumă, în orice bancnote
* disponibile.
*
* Dacă force_request_product este apelată, cumpărătorul nu dorește
* rest, și această functie nu ar trebui apelată.
*/
int request_change();

/**
* Cere un produs, chiar dacă nu exista rest disponibil.
* Codurile întoarse sunt aceleași ca și la request_product,
* cu excepția erorii în privința restului.
*/
int force_request_product(int code);
/**
* Insereaza o bancnota.
* (-1, daca bancnota nu a putut fi identificata).
*/
int insert_bill(bill_type bill);

/**
* Resetează automatul (reset ar trebui să reseteze întreaga stare,
* număr de produs, cantități, costuri, etc).
*/
void reset();

#endif /* __AUTOMAT_H */

Implementare

Veți implementa funcționalitățile descrise în fișierul antet de mai sus, într-un fișier sursă denumit automat.c.

Pe lângă automat.h și automat.c, creați și un fișier main.c, cu o funcție main() care va simula practic comportamentul unui automat.

 Autori: Victor Cărbune, Laura Vasilescu

Data: 21.11.2011