Corso di Programmazione - Prova Pratica - Terzo Appello - 7 febbraio 2001 - prova 303


L'esame di oggi ha a che fare con un distributore automatico di patatine.

Un valore di tipo Patatina può essere Pai, Fonzies, o Pringles. Il suo costo è desumibile dalla tabella costante COSTO: per esempio, COSTO[Pai] è il costo di un sacchetto di papatine Pai, e nel nostro caso è uguale a 1300.

Per ottenere un pacchetto di patatine dal distributore, uno deve inserire delle monete (da 100, 200, 500 o 1000 lire). Queste sono rappresentate da valori del tipo enumerazione Moneta. Di monete, per avere le patatine, in genere non ne basta una, ed a questo serve il tipo ListaMonete, i cui valori sono liste semplici di elementi di tipo Moneta.

Un distributore di patatine, di tipo Distributore, lo possiamo pensare come un record di tre campi: il campo disponibili è una tabella di interi che, avendo come indice un tipo di patatine (Pai, Fonzies e Pringles, rispettivamente) ci dice quanti pezzi di quel tipo sono disponibili nel distributore stesso; il campo incasso ci dice la somma totale del denaro immesso nel distributore (che verrà incrementato ad ogni erogazione di servizio). Infine, il campo moneteInserite, di tipo ListaMonete, servirà a memorizzare le monete inserite prima che le patatine siano fornite all'utente. Se infatti la lista delle monete inserite non copre il costo delle patatine selezionate, o se quelle selezionate non sono più disponibili, sarà possibile all'utente annullare l'operazione ed avere indietro le monete inserite.

#define NUM_PATATINE 3                  // sono 3 tipi: Pai, Fonzies e Pringles
const int COSTO[] ={1300, 1200,  1700}; // prezzo di Pai, Fonzies e Pringles, rispettivamente
typedef enum Patatina {Pai, Fonzies, Pringles} Patatina;
typedef enum Moneta {cento, duecento, cinquecento, mille} Moneta;


typedef struct ListaMonete{
	Moneta coin;
	struct ListaMonete* prossima;
} ListaMonete;


typedef struct Distributore{
	int disponibili[ NUM_PATATINE ];
	int incasso;
	ListaMonete* moneteInserite;
} Distributore;

Esercizio 1: Implementare le seguenti funzioni:

Distributore* Crea();

La funzione crea crea un nuovo valore di tipo Distributore e ne restituisce l'indirizzo. Gli elementi della tabella disponibili (relativi ai diversi tipi di patatine) vengono tutti inizializzati con il valore 0. Il campo moneteInserite viene inizializzato a NULL, il campo incasso viene inizializzato a 0.

 

int manutenzione(Distributore* d, int num_pezzi);

La funzione rappresenta l'azione svolta dal manutentore della macchina distributrice di patatine, che preleva l'incasso e aggiunge nuovi pacchetti di patatine. La funzione deve restituire il valore del campo incasso sommato al valore complessivo delle monete che sono in moneteInserite. Dovrà inoltre incrementare di num_pezzi unità ciascuno degli elementi della tabella disponibili. Alla fine dell'esecuzione della funzione, il campo incasso dovrà essere resettato (attribuendogli il valore 0), e lo stesso dicasi per il campo moneteInserite (attribuendogli il valore NULL).


Esercizio 2: Implementare la seguente funzione:

int seleziona(Distributore* d, ListaMonete* monete, Patatine patatine);

Questa funzione restituisce 1 se le monete della lista monete (la lista delle monete inserite, passata come parametro attuale) hanno raggiunto o superato il costo di patatine (consultando l'array costante COSTO) e se patatine Ŕ ancora disponibile. In tal caso, il distributore non restituisce il resto: l'incasso del distributore d viene incrementato dell'importo inserito, e viene decrementato il numero di unità di quel tipo di patatine in d.

Qualora invece le monete inserite non coprano il costo delle patatine patatine, la funzione restituisce 0, e nel campo moneteInserite resterÓ una copia della lista monete (gli altri campi resteranno immutati), in attesa della funzione annulla.

Infine, se le monete inserite superano il costo di patatine, ma queste ultime non risultano disponibili, la funzione restituisce -1, e nel campo moneteInserite resterÓ una copia della lista monete (gli altri campi resteranno immutati), in attesa anche in questo caso della funzione annulla.


Esercizio 3: Implementare le seguenti procedure:

ListaMonete* annulla(Distributore* d);

La funzione annulla permette di azzerare l'operazione in corso: le monete vengno restituite in una lista, nello stesso ordine con cui erano state immesse nel distributore d. Alla fine, al campo moneteInserite di d deve essere assegnato il valore NULL.

void stampa(Distributore d);

La procedura stampa deve fornire a video una rappresentazione dello stato dei campi del distributore d passato come parametro attuale.


IMPORTANTE:
La modalità di consegna dell'esame
è analoga a quella delle esercitazioni durante il corso: è sufficiente inviarlo come esercitazione numero 303.

Bisogna inserire esclusivamente la definizione delle funzioni richieste ed eventuali procedure o funzioni ausiliarie, per consentirne la correzione automatica.

Per superare la prova è necessario che almeno uno dei tre esercizi sia corretto (ovvero che la compilazione abbia successo e che l'esecuzione soddisfi la specifica data).