Appello 12.09.2007-1- punti 15 (4+6+5) a) ctunes è un programma per la gestione di archivi musicali; serve per raccogliere informazioni riguardanti tutti i file musicali presenti su un computer e per creare playlist in base alle preferenze degli utenti. Di ogni brano musicale si vogliono memorizzare titolo, album, artista, durata, genere e tipo di file. Titolo, album e artista sono stringhe di massimo 255 caratteri. La durata è espressa in millisecondi. I generi musicali sono solo rock, classical e jazz. Il tipo di file può essere uno tra mp3, aac, wma, wav. - Definire i tipi di dato TipoGenere e TipoFile. - Definire il tipo di dato TipoBrano, utilizzando anche i due tipi definiti sopra. #define STR_LEN 256 #define MAX_BRANI 100 typedef enum {rock, classical, jazz TipoGenere; typedef enum {mp3, aac, wma, wav TipoFile; typedef struct { char titolo[str_len]; char album[str_len]; char artista[str_len]; TipoGenere genere; TipoFile file; long int durata; TipoBrano; b) Siano date le seguenti variabili globali: - TipoBrano archivio[100]; //lista dei brani - int nbrani = 0; //numero di brani presenti in archivio Si implementi la funzione creaplaylist, il cui prototipo è il seguente: int creaplaylist(tipobrano[] playlist, int n, TipoGenere g, TipoFile t); La funzione inserisce nell array playlist i primi n brani di genere g e tipo t trovati in archivio. In caso non ci siano sufficienti brani di genere dato, la playlist viene riempita con brani di altro genere. Invece, se non esistono abbastanza brani di tipo t, la procedura termina. Il valore intero restituito dalla funzione equivale al numero di brani effettivamente inseriti in playlist (quindi di solito vale n, se ci sono almeno n file del tipo voluto in archivio). Si supponga che playlist sia un array già inizializzato con almeno n celle e che n < nbrani (quindi, in altri termini, queste condizioni non devono essere controllate).
int creaplaylist(tipobrano playlist[], int n, TipoGenere g, TipoFile t) { int i = 0; /*indice della playlist (incrementato ogni volta che aggiungiamo un brano)*/ int j = 0; /*indice di scorrimento nell'archivio (incrementato ogni volta che analizziamo un brano)*/ TipoBrano brano; //brano sotto osservazione //cerchiamo brani di genere e tipofile dato: while (i < n && j < nbrani) { brano = archivio[j]; if (brano.genere == g && brano.file == t) { //abbiamo un brano playlist[i++] = brano; //che ci piace! j++; //analizziamo il prossimo if (i < n) { //siamo usciti dal ciclo ma non abbiamo riempito la //playlist: non ci sono abbastanza brani di genere g //e tipo t in archivio j = 0; while (i < n && j < nbrani) { brano = archivio[j]; //cerchiamo brani di tipo t ma di genere diverso da g //(altrimenti, inseriremmo due volte gli stessi brani if (brano.genere!= g && brano.file == t) { //abbiamo un brano che ci //piace "abbastanza" playlist[i++] = brano; j++; /* Siamo usciti dal ciclo: o abbiamo inserito n brani, o abbiam analizzato due volte tutto l'archivio. In entrambi i casi, abbiamo finite. */ return i; c) Si implementi la procedura di prototipo void inseriscibrano(tipobrano b); La procedura inserisce il brano b nell archivio (si noti che il brano è già stato creato all esterno della procedura), solo dopo aver controllato che non ne sia presente una sua copia. Due brani sono uguali se tutti i loro campi corrispondenti sono uguali. Per il confronto tra stringhe (titolo, album, artista) si utilizzi la funzione di libreria strcmp(char s1[ ], char s2[ ]), che restituisce 0 se due stringhe sono uguali tra loro. Si faccia attenzione a non eccedere la capacità massima dell archivio.
void inseriscibrano (TipoBrano b) { int i; TipoBrano b1; if (nbrani >= MAX_BRANI) return; for (i = 0; i < nbrani; i++) { b1 = archivio[i]; if (b.genere == b1.genere && b.file == b1.file) /* && tutti gli altri campi */ return; //se arriviamo qui abbiamo spazio e non ci sono duplicati archivio[nbrani] = b; nbrani++; Effettuare il tracing delle variabili per il seguente programma C. Indicare il contenuto delle variabili al termine dell esecuzione del programma #include <stdio.h> int main(){ int x, y, i; x=1; y=3; printf("i x y\n"); for(i=3;i<7;i++){ if (i%2==0) x=x+ ++y +i; if (i%3==0) y=x-1; else y=y-1; printf("%d %d %d\n", i, x,y); Output delle printf: i x y 3 1 0 4 6 0 5 6-1
6 12 11 Appello 28.06.2010-3- punti 3 Si deve realizzare un programma che consenta di giocare al gioco del 15. Il gioco è un rompicapo classico inventato da Samuel Loyd nel 1878. Il gioco consiste di una tabellina di forma quadrata divisa in quattro righe e quattro colonne (quindi 16 posizioni), su cui sono posizionate 15 tessere quadrate, numerate progressivamente a partire da 1. Le tessere possono scorrere in orizzontale o verticale, ma il loro spostamento è ovviamente limitato dall'esistenza di un singolo spazio vuoto. Lo scopo del gioco è riordinare le tessere dopo averle "mescolate" in modo casuale (la posizione da raggiungere è quella con il numero 1 in alto a sinistra e gli altri numeri a seguire da sinistra a destra e dall'alto in basso, fino al 15 seguito dalla casella vuota). La figura sottostante riporta il gioco del quindici risolto. Definire le strutture dati necessarie per scrivere il programma. #define Size 4 typedef int gioco15[size][size]; gioco15 f; -4- punti 2 In base alle strutture dati definite al punto precedente si definisca il prototipo di una funzione int gioco15risolto(...) che deve fornire 1 se il gioco del 15 è stato risolto e 0 altrimenti. int gioco15risolto(gioco15 g);
-5- punti 4 Si fornisca l implementazione della funzione definita al punto precedente. int gioco15risolto(gioco15 g){ int cont=1; for( int i=0; i<size; i++) for(int j=0; j<size; j++) if(g[i][j]==cont) cont++; else { if (cont==16) return 1 //sono arrivato sulla cella //vuota else return 0; // esiste un element fuori sequenza