Programmazione ed
Esercitazioni di Programmazione


Esame pratico di programmazione del 15/01/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 15/01/2008.

Vengono fornite le soluzioni solo per alcuni esercizi, per gli altri la struttura delle funzioni rimane uguale, cambiano i tipi di dato e i nomi delle strutture dati utilizzate.

Esercizio 1 (Tema 140)

/* int produci(Dispensa* d);
La procedura produci restituisce il numero massimo di confezioni di frittelle che si possono produrre con le quantità presenti nella dispensa *d. All'uscita della funzione, i valori dei campi di *d dovranno ovviamente essere decrementati in ragione degli ingredienti effettivamente consumati. */

int produci(Dispensa *d) {
	int min;
	/* Questo controllo è molto importante. Tutte le istruzioni successive 
	darebbero errore se il puntatore fosse a NULL!!! */
	if(d == NULL)
		return 0;
		
	min = d->farina;
	if(min > (d->uova / 3)) min = d->uova / 3;
	if(min > (d->olio / 2)) min = d->olio / 2;
	if(min > (d->zucchero / 3)) min = d->zucchero / 3;
	
	d->farina -= min;
	d->uova -= (min * 3);
	d->olio -= (min * 2);
	d->zucchero -= (min * 3);
	
	return min;
}


Esercizio 2 (Tema 140)

/* ListaPacchi aggiungiPacco(ListaPacchi l, char* cliente, int numero_confezioni);
La procedura aggiungiPacco aggiunge in coda alla lista l un nuovo pacco, destinato al cliente di nome cliente, e contenente numero_confezioni confezioni di frittelle. */

ListaPacchi aggiungiPacco(ListaPacchi l, char* cliente, int numero_confezioni) {
	ListaPacchi new = (ListaPacchi)malloc(sizeof(Pacco));
	ListaPacchi aux;
	
	strcpy(new->nome_cliente, cliente);
	new->n_confezioni = numero_confezioni;
	new->next = NULL;
	
	/* Se il puntatore alla lista è NULL, la lista non esiste, 
	e bisogna creare la testa. Sarebbe inutile altrimenti che la procedura 
	restituisse un valore di tipo ListaPacchi */
	if(l == NULL) {
		return new;
	}
	aux = l;
	/* Arrivo all'ultimo elemento della lista e ci collego il nuovo elemento creato */
	while(aux->next != NULL)
		aux = aux->next;
	
	aux->next = new;
	
	/* Restituisco la testa della lista */
	return l;
}


Esercizio 3 (Tema 140)

/* void ritiraPacco(ListaPacchi* l, char* cliente); La procedura ritiraPacco deve eliminare dalla lista l tutti i pacchi corripondenti al cliente di nome cliente presenti nella lista. */

void ritiraPacco(ListaPacchi *l, char *cliente) {
	ListaPacchi aux = (*l);
	ListaPacchi temp = (*l);
	ListaPacchi pred = NULL;
	
	/* Se la lista è vuota, non ho niente da fare. */
	if((*l) == NULL)
		return;

	/* Scorro tutta la lista, con un puntatore ausiliario per non perdere 
	il riferimento alla testa */
	while(aux != NULL) {
		/* Se il cliente attuale è uno di quelli da eliminare */
		if(strcmp(aux->nome_cliente, cliente) == 0) {
			/* Salvo l'elemento di cui fare la free */
			temp = aux;
			/* Se non avevo un elemento precedente, sono sul primo 
			elemento della lista, oppure ho eliminato tutti
			gli elementi della lista dal primo fino a quello attuale */
			if(pred == NULL) {
				/* Passo al successivo elemento la testa della lista */
				(*l) = (*l)->next;
			}
			else {
			/* Se non sono nella testa della lista, assegno all'elemento 
			precedente quello attuale, il prossimo (scollego l'attuale dalla lista) */
				pred->next = aux->next;
			}
		}
		else {
			/* Se l'elemento attuale non è da eliminare, 
			sarà quello a cui collegare i prossimi in caso di
			eliminazione, e non c'è alcun elemento di cui fare la free */
			temp = NULL;
			pred = aux;
		}
		
		/* Passo all'elemento successivo ed eseguo l'eventuale free di temp */
		aux = aux->next;
		/* Effettuo la free in questo punto perché nell'istruzione 
		precedente devo accedere ad aux, che può corrispondere
		alla stessa locazione di temp. */
		free(temp);
	}
}


Esercizio 3 (Tema 142)

/* void spostaPacco(ListaPacchi* l);
La procedura spostaPacco deve spostare il pacco in testa alla lista alla fine della lista stessa. */

void spostaPacco(ListaPacchi *l) {
	ListaPacchi aux = (*l);
	
	/* Se la lista è vuota o contiene un solo pacco non faccio niente */
	if((*l) == NULL || (*l)->next == NULL) {
		return;
	}
	
	/* Scorro fino all'ultimo pacco */
	while(aux->next != NULL) {
		aux = aux->next;
	}
	
	/* Collego la coda della lista con la testa */
	aux->next = (*l);
	/* Sposto la testa al pacco successivo */
	(*l) = (*l)->next;
	/* Chiudo la lista */
	aux->next->next = NULL;
	return;
}


Esercizio 3 (Tema 143)

/* void spostaPacco(ListaPacchi* l);
La procedura spostaPacco deve spostare il pacco in fondo alla lista all'inizio della lista stessa. */

void spostaPacco(ListaPacchi *l) {
	ListaPacchi aux = (*l);
	ListaPacchi prev;
	
	/* Se la lista è vuota o contiene un solo pacco non faccio niente */
	if((*l) == NULL || (*l)->next == NULL) {
		return;
	}
	
	/* Scorro fino all'ultimo pacco salvando il pacco precedente all'attuale */
	while(aux->next != NULL) {
		prev = aux;
		aux = aux->next;
	}
	
	/* Termino la lista al penultimo elemento */
	prev->next = NULL;
	/* Collego l'ultimo elemento in testa alla lista */
	aux->next = (*l);
	/* Setto l'ultimo elemento come nuova testa */
	(*l) = aux;
	return;
}