Programmazione ed
Esercitazioni di Programmazione


Esame pratico di programmazione del 19/06/2008 - Soluzioni

Le soluzioni qui proposte sono solo indicative, vi sono molti modi per poter svolgere lo stesso esercizio!

Sono proposte alcune soluzioni alle tipologie di esercizi assegnati nell'esame pratico del corso di programmazione del 19/06/2008.

Esercizio 1 (Tema 147)

/* Stato *inizializza();
La funzione inizializza restituisce l'indirizzo di una nuova variabile dinamica di tipo Stato che rappresenta la situazione iniziale ad inizio giornata: la lista delle persone in attesa è ancora vuota, tutti e tre gli sportelli sono ancora liberi, e per ognuno dei tre sportelli, la lista delle persone già servite è ancora vuota. */

Stato *inizializza() {
	int i = 0;
	Stato *stato = (Stato *)malloc(sizeof(Stato));
	stato->lista = NULL;
	
	/* Attenzione: non è necessario fare una malloc per gli sportelli. 
	Nella struttura non sono dichiarati come puntatori. */
	for(i = 0; i < 3; i++) {
		(stato->sportello[i]).servito = NULL;
		(stato->sportello[i]).lista = NULL;
	}
	
	return stato;
}


Esercizio 1 (Tema 148)

/* int contaliTutti(Stato stato);
La funzione contaliTutti restituice il numero complessivo sia delle persone che sono ancora in coda in attesa di essere servite che di quelle che sono già state servite dai tre sportelli (ovvero che sono nelle rispettive liste). */

int contaliTutti(Stato stato) {
	int count = 0;
	int i = 0;
	ListaPersone *l = stato.lista;
	
	while(l != NULL) {
		count++;
		l = l->next;
	}
	for(i = 0; i < 3; i++) {
		l = (stato.sportello[i]).lista;
		while(l != NULL) {
			count++;
			l = l->next;
		}
	}
	return count;
}


Esercizio 2 (Tema 147)

/* void avantiIlProssimo(Stato *stato);
La procedura avantiIlProssimo verifica se uno degli sportelli è libero (altrimenti non fa nulla!), ed in tal caso toglie dalla lista delle persone in attesa il primo arrivato (se la lista delle persone in attesa è vuota non fa nulla), e ne assegna l'indirizzo al campo servito di quello, tra gli sportelli liberi, che finora ha lavorato di meno (ovvero la cui lista di persone già servite è più piccola). In caso di "parità" tra sportelli, la persona sarà servita da sportello[i] con indice i più basso. */

void avantiIlProssimo(Stato *stato) {
	int i = 0;
	int i_min = -1;
	ListaPersone *tmp;
	
	int count[3] = {0,0,0};
	
	if((*stato).lista == NULL) return;
	
	for(i = 0; i < 3; i++) {
		if(((*stato).sportello[i]).servito == NULL) {
			ListaPersone *l = ((*stato).sportello[i]).lista;
			while(l != NULL) {
				count[i]++;
				l = l->next;
			}
			if(i_min == -1 || count[i] < count[i_min]) i_min = i;
		}
	}
	switch(i_min) {
		case -1:
			return;
		default:
			(stato->sportello[i_min]).servito = (Persona *)malloc(sizeof(Persona));
			for(i = 0; i < 16; i++)
				((stato->sportello[i_min])->servito)[i] = (stato->lista)->persona[i];
			tmp = (*stato).lista;
			(*stato).lista = ((*stato).lista)->next;	
			free(tmp);
			break;
	}
	
	return;
}


Esercizio 2 (Tema 148)

/* int libero(Stato stato);
La funzione libero verifica se uno degli sportelli è libero (altrimenti restituisce -1), ed in tal caso restituisce l'indice di quello, tra gli sportelli liberi, che finora ha lavorato di meno (ovvero la cui lista di persone già servite è più piccola). In caso di "parità di lavoro fatto" tra sportelli, restituisce l'indice più basso. */

int libero(Stato stato) {
	int i;
	int i_min = -1;
	int count[3] = {0,0,0};
	
	for(i = 0; i < 3; i++) {
		if((stato.sportello[i]).servito == NULL) {
			ListaPersone *l = (stato.sportello[i]).lista;
			while(l != NULL) {
				count[i]++;
				l = l->next;
			}
			if(i_min == -1 || count[i] < count[i_min]) i_min = i;
		}
	}
	return i_min;
}


Esercizio 3 (Tema 147)

/* void fattoAncheQuesto(Stato *stato, int num_sportello);
La procedura fattoAncheQuesto deve aggiornare lo stato dopo che la persona che è allo sportello di indice num_sportello è stata servita: al campo servito di tale sportello viene assegnato il valore NULL, e la persona che era allo sportello viene inserita in cima alla lista delle persone già servite associata allo sportello stesso. */

void fattoAncheQuesto(Stato *stato, int num_sportello) {
	ListaPersone *t;
	int i;
	
	if((stato->sportello[num_sportello]).servito == NULL) {
		return;
	}
	t = (ListaPersone *)malloc(sizeof(ListaPersone));

	for(i = 0; i < 16; i++)
		t->persona[i] = (*(stato->sportello[num_sportello]).servito)[i];

	(stato->sportello[num_sportello]).servito = NULL;

	t->next = (stato->sportello[num_sportello]).lista;

	(stato->sportello[num_sportello]).lista = t;
	
	(stato->sportello[num_sportello]).servito = NULL;
	
	return;	
}


Esercizio 3 (Tema 148)

/* void nuovoArrivato(Stato *stato, char codiceFiscale[16]);
La procedura nuovoArrivato deve aggiornare lo stato dopo che una nuova persona, identificata dal codiceFiscale è arrivata all'ufficio delle imposte, mettendola in fondo alla lista delle persone in attesa. */

void nuovoArrivato(Stato *stato, char codiceFiscale[16]) {
	ListaPersone *l = stato->lista;
	int i;
	
	if(l == NULL) {
		stato->lista = (ListaPersone *)malloc(sizeof(ListaPersone));
		stato->lista->next = NULL;
		for(i = 0; i < 16; i++)
			stato->lista->persona[i] = codiceFiscale[i];
		return;
	}
	
	while(l->next != NULL)
		l = l->next;
	
	l->next = (ListaPersone *)malloc(sizeof(ListaPersone));
	l->next->next = NULL;
	
	for(i = 0; i < 16; i++)
		l->next->persona[i] = codiceFiscale[i];
	
	return;
}