RACCOLTA DI ESERCIZI SVOLTI SARA BRUNETTI Esercizio 1 Realizzare un programma che permetta di eseguire somme, sottrazioni, moltiplicazioni e divisioni tra coppie di frazioni e di visualizzare il risultato in forma ridotta. Una frazione è una coppia di interi n1 (numeratore), d1 (denominatore positivo). Scrivere le seguenti funzioni: void scan_fraction(int *nump, int *denomp); Gestisce l'inserimento di una frazione da tastiera nella forma: intero/intero positivo. Controlla che l'inserimento sia corretto, altrimenti chiede all'utente di reinserire i dati. Ritorna la frazione come coppia di interi. (Perchè i parametri sono puntatori?) char get_operator(void); Gestisce l'inserimento da tastiera dell'operazione aritmetica da effettuare tra le due frazioni inserite. Legge il carattere inserito dall'utente, salta caratteri \n e permette il re-inserimento in caso di errore. void add_fractions(int n1, int d1, int n2, int d2, int *n_ansp, int *d_ansp); Somma frazioni rappresentate da coppie di interi: la frazione somma è data in output attraverso i parametri della funzione. (Perchè?) void multiply_fractions(int n1, int d1, int n2, int d2, int *n_ansp, int *d_ansp); Come sopra ma per il prodotto. int find_gcd (int n1, int n2); Ritorna il massimo comun divisore tra due interi n1, n2. void reduce_fraction(int *nump, int *denomp); Riduce una frazione dividendo il suo numeratore e denominatore per il loro massimo comun divisore. void print_fraction(int num, int denom); Visualizza la frazione come numeratore/denominatore. int main(); gestisce un menù a scelta multipla per la selezione da parte dell'utente di effettuare un' operazione di somma '+', sottrazione '-', moltiplicazione '*' e divisione '/'. Esercizio 2 Modificare l'esercizio 1 definendo una frazione tramite un tipo strutturato fraction con elementi n1 (numeratore), d1 (denominatore). typedef struct{ int n1; int d1; //numeratore }fraction; //denominatore Esercizio 3 Il gioco del TRIS consiste nell'allineare tre pedine dello stesso giocatore sulla stessa riga o colonna o diagonale di una griglia board di dimensione fissa (NxN, con N costante uguale a tre). Realizzare il gioco scrivendo le seguenti funzioni. void init(char board[][N]); inizializza la griglia (ogni elemento è "vuoto", cioe' spazio bianco ) int row_sum(char board[][N], int i, char c); conta gli elementi uguali a c sulla i-esima riga , e ne restitutisce il numero int column_sum(char board[][N], int i, char c); conta gli elementi uguali a c sulla i-esima riga , e ne restitutisce il numero int diagonal_sum(char board[][N],int d,char c); conta gli elementi uguali a c sulla diagonale d, e ne restitutisce il numero. Se d=1, considera la diagonale principale, altrimenti l'antidiagonale. int filled(char board[][N]); controlla se la griglia è piena oppure no, e restituisce 1 nel primo caso, 0 nel secondo caso. int empty_pos(char board[][N], position emptypos[]); se ci sono posizione ancora vuote della griglia ne memorizza gli indici nell'array emptypos e ne ritorna il numero. Nota che position è un tipo strutturato definito come una coppia di indici della griglia. void fill_one(char board[][N], position pos, int *round); effettua la mossa nella posizione specificata da pos. se round è dispari è il turno del giocatore A, altrimenti è il turno di B. Incrementa il turno. void print_board(char board[][N]); visualizza la griglia. main() gestisce l'inizializzazione della griglia; gestisce le mosse: in particolare, per ciascun turno dei due giocatori verifica, prima che venga effettuata la mossa, se la griglia non è completa. In tal caso verifica le posizioni ancora libere, sceglie a caso tra di esse ed effettua la mossa. Dopo aver effettuato la mossa controlla se il giocatore a vinto. In ogni caso visualizza la griglia. Esercizio 4 In un supermercato ogni cliente può utilizzare un lettore di codice a barre dei prodotti che vuole acquistare. Ogni volta che viene letto il codice a barre di un prodotto, un nuovo elemento viene aggiunto alla lista dello scontrino. In caso di errore è possibile rimuovere l'ultimo elemento inserito e al termine degli acquisti viene effettuata la somma dei prezzi di tutti gli articoli. Quindi uno scontrino è rappresentato da una pila. La struttura dati che rappresenta i tipi prodotto e scontrino è così organizzata: typedef struct { unsigned int codice; char descrizione[MAX_STRING]; double prezzo; } prodotto; typedef struct { int size; int TOS; prodotto *buffer; }scontrino; Scrivere le seguenti funzioni: void getsize(int *pt_size); in base alle necessita' del cliente viene impostata una dimensione per lo scontrino: spesa giornaliera (15 oggetti), settimanale (30 oggetti) oppure mensile (50 oggetti). il default è 15. La dimensione è gestita tramite un menù che richiede al cliente di digitare 'g' per giornaliera; 's' per settimanale; 'm' per mensile. void init_scontrino (scontrino *sc); inizializza lo scontrino della dimensione assegnata; boolean aggiungi_prodotto (scontrino *scp, const prodotto prod); aggiunge un prodotto allo scontrino, se possibile TRUE. Se non è possibile ritorna FALSE. boolean elimina_prodotto (scontrino *scp, prodotto * prodp); rimuove dallo scontrino l'ultimo prodotto inserito, e lo restituisce mediante il parametro di uscita prodp. Ritorna TRUE. double totale_spesa (const scontrino sc); ritorna il totale della spesa contenuta nello scontrino sc, pari alla somma di tutti i prezzi dei singoli prodotti presenti nella lista; void stampa_scontrino (const scontrino sc); visualizza lo scontrino sc, omettendo il codice (descrizione ed il prezzo). main() funzione di collaudo. gestisce l'inizializzazione dello scontrino e richiama le funzioni in base alle scelte del cliente (menù cliente). (Opzionale: se la funzione aggiungi_prodotto ha restituito FALSE, chiama la funzione void nuovo_scontrino). Alla fine della spesa, stampa lo scontrino. Opzionale: void nuovo_scontrino(scontrino *scp); crea una dimensione maggiore per lo scontrino. Esercizio 5 Un lettore di codici a barre appartenenti ai Codici di Prodotto Universali (CPU) verifica che il codice a 12 cifre letto sia corretto confrontando il valore dell'ultima cifra del codice (cifra di controllo) con il valore calcolato in base alle 11 cifre precedenti, come spiegato in seguito: 1. calcolare la somma delle cifre nelle posizioni dispari e moltiplicarla per 3. 2. calcolare la somma delle cifre nelle posizioni pari e sommarla al risultato precedente. 3. Se l'ultima cifra del risultato al passo precedente è 0, allora la cifra di controllo è 0; altrimenti sottrarre l'ultima cifra a 10 per ottenere la cifra di controllo. 4. Se la cifra di controllo corrisponde alla cifra finale del CPU a 12 cifre, il codice viene considerato corretto. Esempio: 079400804501 passo1: (0+9+0+8+4+0)*3=63 passo 2: (0+9+0+8+4+0)*3+(7+4+0+0+5)=79 passo3: 10-9 passo4: 1? 1 (corretto) preparare un file di testo codes.txt con i seguenti codici a barre (uno per ciascuna riga): 079400804501 024000162860 011110856807 051000138101 Scrivere le seguenti funzioni: int read_file(FILE *fp, int cod[SIZE]); legge da un file un codice a barre: restituisce :1 per input corretto; 0 per errore; EOF per fine file void load_codes(int all_codes[][],int *rowp); Apre il file codes.txt e legge i dati da salvare in all_codes fino alla fine del file e restituisce come parametro di output il numero di righe utilizzate. Interrompe la lettura se ci sono piu' di MAXSIZE codici nel file o se viene letto un dato non valido. Dopo ogni singola lettura (chiamando read_file) memorizza il codice in una riga della matrice all_codes boolean control_code(int one_code[SIZE]); calcola la cifra di controllo di un codice a barre (one_code) e la confronta con l'ultima cifra del codice a barre. Se le due cifre corrispondono, restituisce TRUE, altrimenti FALSE void print_code_control(int one_code[SIZE],char *result); visualizza il codice a barre con l'esito del controllo (result) : "convalidato" in caso positivo, altrimenti "errore nel codice a barre". int write_file(int one_code[SIZE], FILE * fp, char *result); Memorizza un codice a barre e l'esito del controllo (result) sul file control.txt. main(); funzione di collaudo per il programma. Esercizio 6 Un pacchetto IP (semplificato) contiene le seguenti informazioni: indirizzo IP del mittente source; indirizzo IP del destinatario dest; campo informazione data (stringa di bit). typedef struct{ int first; int second; int third; int fourth; }address; typedef struct{ address source; address dest; char *data; }packet; I pacchetti IP che arrivano in un router vengono accodati in un buffer buffer di dimensione MAXBUF in attesa di essere processati. Quando un pacchetto viene elaborato, esso viene estratto dal buffer e, sulla base dell'indirizzo del destinatario, viene smistato verso l'uscita corrispondente al router successivo. Lo smistamento (semplificato) avviene utilizzando una tabella di inoltro costituita dai seguenti campi: indirizzo di rete network_num, router next_hop. Quindi una tabella di inoltro table sarà realizzata tramite un array di dimensione fissata MAXENTRY di elementi di tipo entry: typedef struct{ address network_num; int next_hop; } entry; Scrivere le seguenti funzioni: void init_packet(packet *p_pac); Inizializza un pacchetto IP, richiedendo all'amministratore di rete l'inserimento dei dati da tastiera. In particolare, inserire i seguenti pacchetti (su una stessa riga riporto indirizzo del mittente, indirizzo del destinatario e dati): P1: 128. 23.15.100 , 187.96.64.64 ,100000111001010000111111 P2: 11.128.15.100 , 132.255.255.64, 0101011111001010100000 P3: 190.16.32.230 , 15.180.16.32 , 1111100101011110000001001 P4: 195.64.12.23 , 26.255.14.192, 0101011100000010111001010 void init_tabel(entry table[]); Inizializza una tabella di inoltro, leggendo la configurazione da un file formattato routing_table.txt . In particolare, il file contiene i seguenti elementi (su una stessa riga riporto network_address, next_hop): 187.96.0.0 , R1 132.255.0.0 R2 15. 0.0.0 R3 int route(packet pac, entry table[], char *router); realizza l'inoltro di un pacchetto come segue: estrae l'indirizzo di rete del destinatario del pacchetto pac e lo cerca tra gli indirizzi di rete nella tabella. Se lo trova restituisce 0 e salva il corrispondente router next_hop nel parametro in uscita; altrimenti restituisce 1 e salva il next_hop di "default" nel parametro in uscita. L'estrazione dell'indirizzo di rete da un indirizzo IP è effettuato dalla funzione network. address network(address ip); restituisce l'indirizzo di rete dell'indirizzo IP ip. Questo è realizzato sulla base del campo first del tipo address come segue: • se 0<first<128, il numero di rete è: first. 0.0.0; • altrimenti se 127<first<192, il numero di rete è: first.second.0.0; • altrimenti se 191<first, il numero di rete è: first.second.third.0; Definire le funzioni per l'accodamento enqueue e per l'estrazione dequeue di un pacchetto dal buffer del router; void print_table(entry table[]); visualizza la tabella di inoltro (nel formato sopra riportato). void print_packet(packet pc); visualizza un pacchetto (nel formato sopra riportato). main(); funzione di collaudo che permette di testare il programma: simula l'accodamento di tre pacchetti P1,P2,P3 nel buffer del router, l'elaborazione di due di essi (P1 e P2) , l'accodamento di un nuovo pacchetto P4 e l'elaborazione di tutti i pacchetti nel buffer. Stampa i pacchetti e la tabella di inoltro. /*Esercizio1: Program to Perform Arithmetic Operations on Common Fractions /* * Adds, subtracts, multiplies and divides common fractions, displaying * results in reduced form. */ #include <stdio.h> #include <stdlib.h> /* provides function abs */ /* Function prototypes */ void scan_fraction(int *nump, int *denomp); char get_operator(void); void add_fractions(int n1, int d1, int n2, int d2, int *n_ansp, int *d_ansp); void multiply_fractions(int n1, int d1, int n2, int d2, int *n_ansp, int *d_ansp); int find_gcd (int n1, int n2); void reduce_fraction(int *nump, int *denomp); void print_fraction(int num, int denom); int main(void) { int n1, d1; /* numerator, denominator of first fraction */ int n2, d2; /* numerator, denominator of second fraction */ char op; /* arithmetic operator + - * or / */ char again; /* y or n depending on user's desire to continue int n_ans, d_ans; /* numerator, denominator of answer */ /* While the user wants to continue, gets and solves arithmetic problems with common fractions */ do { /* Gets a fraction problem scan_fraction(&n1, &d1); op = get_operator(); */ */ scan_fraction(&n2, &d2); /* Computes the result */ switch (op) { case '+': add_fractions(n1, d1, n2, d2, &n_ans, &d_ans); break; case '-': add_fractions(n1, d1, -n2, d2, &n_ans, &d_ans); break; case '*': multiply_fractions(n1, d1, n2, d2, &n_ans, &d_ans); break; case '/': multiply_fractions(n1, d1, d2, n2, &n_ans, &d_ans); } reduce_fraction(&n_ans, &d_ans); /* Displays problem and result */ printf("\n"); print_fraction(n1, d1); printf(" %c ", op); print_fraction(n2, d2); printf(" = "); print_fraction(n_ans, d_ans); /* Asks user about doing another problem */ printf("\nDo another problem? (y/n)> "); scanf(" %c", &again); } while (again == 'y' || again == 'Y'); return (0); } /* * Gets and returns a valid fraction as its result * A valid fraction is of this form: integer/positive integer */ void scan_fraction(int *nump, int *denomp) { char slash; /* character between numerator and denominator */ int status; /* status code returned by scanf indicating number of valid values obtained */ int error; char discard; /* flag indicating presence of an error */ /* unprocessed character from input line */ do { /* No errors detected yet */ error = 0; /* Get a fraction from the user */ printf("Enter a common fraction as two integers separated "); printf("by a slash> "); status = scanf("%d %c%d",nump, &slash, denomp); /* Validate the fraction */ if (status < 3) { error = 1; printf("Invalid-please read directions carefully\n"); } else if (slash != '/') { error = 1; printf("Invalid-separate numerator and denominator"); printf(" by a slash (/)\n"); } else if (*denomp <= 0) { error = 1; printf("Invalid-denominator must be positive\n"); } /* Discard extra input characters */ do { scanf("%c", &discard); } while (discard != '\n'); } while (error); } /* * Gets and returns a valid arithmetic operator. Skips over newline * characters and permits re-entry of operator in case of error. */ char get_operator(void) { char op; printf("Enter an arithmetic operator (+,-,*, or /)\n> "); scanf("%c", &op); while(op != '+' && op != '-' && op != '*' && op != '/'){ if (op != '\n') printf("%c invalid, reenter operator (+,-, *,/)\n> ", op); scanf("%c", &op); } return (op); } /* * Adds fractions represented by pairs of integers. * Pre: n1, d1, n2, d2 are defined; * n_ansp and d_ansp are addresses of type int variables. * Post: sum of n1/d1 and n2/d2 is stored in variables pointed * to by n_ansp and d_ansp. Result is not reduced. */ void add_fractions(int int n1, int n2, int d1, /* input - first fraction d2, /* input - second fraction */ */ int *n_ansp, int *d_ansp) /* output - sum of 2 fractions*/ { int denom, /* common denominator used for sum (may not be least) numer, /* numerator of sum */ sign_factor; /* -1 for a negative, 1 otherwise */ /* Finds a common denominator */ denom = d1 * d2; /* Computes numerator */ numer = n1 * d2 + n2 * d1; /* Adjusts sign (at most, numerator should be negative) if (numer * denom >= 0) sign_factor = 1; else sign_factor = -1; numer = sign_factor * abs(numer); */ */ denom = abs(denom); /* Returns result */ *n_ansp = numer; *d_ansp = denom; } /* * Multiplies fractions represented by pairs of integers. * Pre: n1, d1, n2, d2 are defined; * n_ansp and d_ansp are addresses of type int variables. * Post: product of n1/d1 and n2/d2 is stored in variables pointed * to by n_ansp and d_ansp. Result is not reduced. */ void multiply_fractions(int int n1, int n2, int d1, /* d2, /* int *n_ansp, /* int *d_ansp) /* input - first fraction input - second fraction */ output - */ product of 2 fractions { /* Displays trace message */ printf("\nEntering multiply_fractions with\n"); printf("n1 = %d, d1 = %d, n2 = %d, d2 = %d\n", n1, d1, n2, d2); *n_ansp =n1*n2; *d_ansp =d1*d2; printf("\n Product (to be reduced): %d/%d",*n_ansp,*d_ansp); } /* * Finds greatest common divisor of two integers */ int find_gcd (int n1, int n2) /* input - two integers { int r; if(n2==0) return n1; r=n1%n2; while(r!=0){ n1=n2; n2=r; r=n1%n2; } */ */ */ return n2; } /* * Reduces a fraction by dividing its numerator and denominator by their * greatest common divisor. */ void reduce_fraction(int *nump, /* input/output */ int *denomp) /* numerator and denominator of fraction */ { int gcd; /* greatest common divisor of numerator & denominator */ gcd = find_gcd(*nump, *denomp); *nump = *nump / gcd; *denomp = *denomp / gcd; } /* * Displays pair of integers as a fraction. */ void print_fraction(int num, int denom) { printf("%d/%d", num, denom); } /* input - numerator & denominator */ /*Esercizio 2: Program to Perform Arithmetic Operations on Common Fractions /* * Adds, subtracts, multiplies and divides common fractions, displaying * results in reduced form. */ #include <stdio.h> #include <stdlib.h> /* provides function abs */ typedef struct{ int n1; int d1; //numerator //denominator }fraction; /* Function prototypes */ void scan_fraction(fraction *frac); char get_operator(void); void add_fractions(fraction frac1, fraction frac2, fraction *frac_ansp); void multiply_fractions(fraction frac1, fraction frac2, fraction *frac_ansp); int find_gcd (fraction frac); void reduce_fraction(fraction *fracp); void print_fraction(fraction frac); int main(void) { fraction frac1; fraction frac2; /* numerator, denominator of first fraction /* numerator, denominator of second fraction char op; /* arithmetic operator + - * or / */ char again; /* y or n depending on user's desire to continue fraction frac_ans; /* numerator, denominator of answer */ /* While the user wants to continue, gets and solves arithmetic problems with common fractions */ */ */ */ do { /* Gets a fraction problem */ scan_fraction(&frac1); printf("%d %d", frac1.n1,frac1.d1); op = get_operator(); scan_fraction(&frac2); /* Computes the result */ switch (op) { case '+': add_fractions(frac1, frac2, &frac_ans); break; case '-': add_fractions(frac1, frac2, &frac_ans); break; case '*': multiply_fractions(frac1, frac2, &frac_ans); break; case '/': multiply_fractions(frac1, frac2, &frac_ans); } reduce_fraction(&frac_ans); // Displays problem and result printf("\n"); print_fraction(frac1); printf(" %c ", op); print_fraction(frac2); printf(" = "); print_fraction(frac_ans); // Asks user about doing another problem printf("\nDo another problem? (y/n)> "); scanf(" %c", &again); } while (again == 'y' system("PAUSE"); return (0); } || again == 'Y'); /* * Gets and returns a valid fraction as its result * A valid fraction is of this form: integer/positive integer * Pre : none */ void scan_fraction(fraction *fracp) { char slash; /* character between numerator and denominator */ int status; /* status code returned by scanf indicating number of valid values obtained */ int error; char discard; /* flag indicating presence of an error */ /* unprocessed character from input line */ do { /* No errors detected yet */ error = 0; /* Get a fraction from the user */ printf("Enter a common fraction as two integers separated "); printf("by a slash> "); status = scanf("%d %c%d",&fracp->n1, &slash, &fracp->d1); /* Validate the fraction */ if (status < 3) { error = 1; printf("Invalid-please read directions carefully\n"); } else if (slash != '/') { error = 1; printf("Invalid-separate numerator and denominator"); printf(" by a slash (/)\n"); } else if ( fracp->d1 <= 0) { error = 1; printf("Invalid-denominator must be positive\n"); } /* Discard extra input characters do { scanf("%c", &discard); } while (discard != '\n'); */ } while (error); } /* * Gets and returns a valid arithmetic operator. Skips over newline * characters and permits re-entry of operator in case of error. */ char get_operator(void) { char op; printf("Enter an arithmetic operator (+,-,*, or /)\n> "); scanf("%c", &op); while(op != '+' && op != '-' && op != '*' && op != '/'){ if (op != '\n') printf("%c invalid, reenter operator (+,-, *,/)\n> ", op); scanf("%c", &op); } return (op); } /* * Adds fractions represented by pairs of integers. * Pre: n1, d1, n2, d2 are defined; * n_ansp and d_ansp are addresses of type int variables. * Post: sum of n1/d1 and n2/d2 is stored in variables pointed * to by n_ansp and d_ansp. Result is not reduced. */ void add_fractions(fraction frac1, //input - first fraction fraction frac2, // input - second fraction fraction *frac_ansp) // output - sum of 2 fractions { int denom, numer, // common denominator used for sum (may not be least) // numerator of sum sign_factor; // -1 for a negative, 1 otherwise // Finds a common denominator denom = frac1.d1 * frac2.d1; // Computes numerator numer = frac1.n1 * frac2.d1 + frac2.n1 * frac1.d1; // Adjusts sign (at most, numerator should be negative) if (numer * denom >= 0) sign_factor = 1; else sign_factor = -1; numer = sign_factor * abs(numer); denom = abs(denom); // Returns result frac_ansp->n1 = numer; frac_ansp->d1 = denom; } /* ***** STUB ***** * Multiplies fractions represented by pairs of integers. * Pre: n1, d1, n2, d2 are defined; * n_ansp and d_ansp are addresses of type int variables. * Post: product of n1/d1 and n2/d2 is stored in variables pointed * to by n_ansp and d_ansp. Result is not reduced. */ void multiply_fractions(fraction frac1, // fraction frac2, // input - first fraction fractions fraction *frac_ansp) input - second fraction // output - product of 2 { // Displays trace message printf("\nEntering multiply_fractions with\n"); printf("n1 = %d, d1 = %d, n2 = %d, d2 = %d\n", frac1.n1, frac1.d1, frac2.n1, frac2.d1); // Defines output arguments frac_ansp->n1 = 1; frac_ansp->d1 = 1; } /* ***** STUB ***** * Finds greatest common divisor of two integers */ int find_gcd (fraction frac) // input - two integers { int gcd; // Displays trace message printf("\nEntering find_gcd with n1 = %d, n2 = %d\n", frac.n1, frac.d1); // Asks user for gcd printf("gcd of %d and %d?> ", frac.n1, frac.d1); scanf("%d", &gcd); // Displays exit trace message printf("find_gcd returning %d\n", gcd); return (gcd); } /* * Reduces a fraction by dividing its numerator and denominator by their * greatest common divisor. */ void reduce_fraction(fraction *fracp) // input/output - fraction { int gcd; // greatest common divisor of numerator & denominator gcd = find_gcd(*fracp); fracp->n1 = fracp->n1 / gcd; fracp->d1 = fracp->d1 / gcd; } /* * Displays pair of integers as a fraction. */ void print_fraction(fraction frac) //input - numerator & denominator { printf("%d/%d", frac.n1, frac.d1); } /*Esercizio 3: realizza il gioco del TRIS*/ #include<stdio.h> #include<stdlib.h> #include<time.h> #define N 3 typedef struct{ int r; //indice riga int c; //indice colonna }position; void init(char board[N][N]); int row_sum(char board[][N], int i, char c); int column_sum(char board[][N], int i, char c); int diagonal_sum(char board[][N],int d,char c); int filled(char board[][N]); int void empty_pos(char board[][N], position emptypos[]); fill_one(char board[][N], position pos, int *roundp); void print_board(char board[][N]); void print_emptypos(position emptypos[],int size); main(){ char board[N][N];//griglia di gioco position emptypos[N*N];//array per le posizioni ancora disponibili int size=N*N; int i,j,where;//index for emptypos for the position where to move int win=0; //indicatore di vittoria (se=1) int round,//contatore per il turno di gioco count=0; //contatore char c; //'A' o 'B' int seed; /*inizializza la griglia*/ init(board); /*inizializza emptypos*/ for(i=0;i<N;i++){ for(j=0;j<N;j++){ emptypos[count].r=i; emptypos[count].c=j; count++; } } seed=time(0); srand(seed); where=(int) rand()/RAND_MAX*size; /*prima mossa per il giocatore A*/ round=1; fill_one(board,emptypos[where],&round); print_board(board); while( (size=empty_pos(board,emptypos))!=0){ disponibili //numero di posizioni ancora //print_emptypos(emptypos,size); where=(double) rand()/RAND_MAX*size; posizioni disponibili fill_one(board,emptypos[where],&round); //genera la mossa nella //effettua la mossa /*verifica se il giocatore di turno ha vinto*/ if(round%2) c='A'; else c='B'; if((diagonal_sum(board, 1, c)==3) || (diagonal_sum(board, -1, c)==3)) { win=1; } else{ for(i=0;i<N;i++){ if( (row_sum(board,i,c)==3)||(column_sum(board,i,c)==3) ){ win=1; } } } if(win==1){ printf("\nIl giocatore %c ha vinto\n", c); break; } else{ printf("\nIl giocatore %c non ha vinto, turno successivo\n",c); } print_board(board); } system("PAUSE"); } /*inizializza la griglia (ogni elemento è "vuoto", cioe' spazio bianco )*/ void init(char board[N][N]){ int i,j; for(i=0;i<N;i++){ for(j=0;j<N;j++){ board[i][j]=' '; } } print_board(board); } /*conta gli elementi uguali a c sulla i-esima riga , e ne restitutisce il numero */ int row_sum(char board[][N], int i, char c){ int j,count=0; for(j=0;j<N;j++){ if(board[i][j]=='c') count++; } return count; } /*conta gli elementi uguali a c sulla i-esima colonna , e ne restitutisce il numero */ int column_sum(char board[][N], int i, char c){ int j,count=0; for(j=0;j<N;j++){ if(board[j][i]=='c') count++; } return count; } /*conta gli elementi uguali a c sulla diagonale d, e ne restitutisce il numero. se d=1, considera la diagonale principale, altrimenti l'antidiagonale*/ int diagonal_sum(char board[][N],int d,char c){ int j, count=0; if(d==1){ for(j=0;j<N;j++){ if(board[j][j]=='c') count++; } } else if(d==-1){ for(j=0;j<N;j++){ if(board[j][N-j]=='c') count++; } } } /*controlla se la griglia è piena oppure no, e restituisce 1 nel primo caso, 0 nel secondo caso.*/ int filled(char board[][N]){ int i,j; int ans=1; //griglia completa (se=1) vuota altrimenti for(i=0;i<N;i++){ for(j=0;j<N;j++){ if(board[i][j]==' ') { ans=0; break; } } } return ans; } /*se ci sono posizione ancora vuote della griglia ne memorizza gli indici nell'array emptypos e ne ritorna il numero. */ int empty_pos(char board[][N], position emptypos[]){ int i,j; int count=0; for(i=0;i<N;i++){ for(j=0;j<N;j++){ if(board[i][j]==' ') { emptypos[count].r=i; emptypos[count].c=j; count++; } } } return count; } /*effettua la mossa nella posizione specificata da pos. se round e' dispari e' il turno di A, altrimenti di B*/ void fill_one(char board[][N], position pos, int *roundp){ if(((*roundp)%2)==1) board[pos.r][pos.c]='A'; else board[pos.r][pos.c]='B'; (*roundp)++; } /*stampa la griglia*/ void print_board(char board[][N]){ int i,j; for(i=0;i<N;i++){ printf("\n"); for(j=0;j<N;j++){ printf("%c\t", board[i][j]); } } } /*stampa una listadi posizioni ancora libere*/ void print_emptypos(position emptypos[],int size){ int i; for(i=0;i<size;i++){ printf("(%d,%d)\t", emptypos[i].r,emptypos[i].c); } } /*Esercizio 4: gestione dello scontrino di un cliente del supermercato come una coda*/ #include<stdio.h> #include<stdlib.h> #include<string.h> #define MAX_STRING 15 typedef unsigned short int Boolean; #define TRUE 1 #define FALSE 0 typedef struct { unsigned int codice; char descrizione[MAX_STRING]; double prezzo; } prodotto; typedef struct { int size; int TOS; prodotto *buffer; }scontrino; void getsize(int *pt_size); void init(scontrino *pt_pila, int size); Boolean aggiungi_prodotto(scontrino *pt_pila, prodotto value); Boolean elimina_prodotto(scontrino *pt_pila, prodotto *pt_value); double totale_spesa(const scontrino sc); void stampa_scontrino(const scontrino sc); /*funzione di collaudo per il programma*/ main(){ scontrino s; int size; getsize(&size); init(&s,size); prodotto p; p.codice = 1; p.prezzo = 2.32; strcpy(p.descrizione,"arance"); aggiungi_prodotto(&s,p); p.codice = 2; p.prezzo = 1.60; strcpy(p.descrizione,"acqua"); aggiungi_prodotto(&s,p); p.codice = 3; p.prezzo = 3.28; strcpy(p.descrizione,"prosciutto"); aggiungi_prodotto(&s,p); stampa_scontrino(s); elimina_prodotto(&s,&p); elimina_prodotto(&s,&p); stampa_scontrino(s); system("PAUSE"); } /*in base alle necessita' del cliente viene impostata una dimensione per lo scontrino. se intende fare una spesa giornaliera (15 oggetti), settimanale (30 oggetti) oppure mensile (50 oggetti). il default e' 15*/ void getsize(int *pt_size){ char op; printf("\n Vuoi fare una spesa giornaliera? Premi: g\n"); printf("\n Vuoi fare una spesa settimanale? Premi: s\n"); printf("\n Vuoi fare una spesa mensile? Premi: m\n"); scanf("%c",&op); switch (op) { case 'g': *pt_size=15; break; case 's': *pt_size=30; break; case 'm': *pt_size=50; break; default: *pt_size=15; } } /*inizializza lo scontrino della dimensione assegnata*/ void init(scontrino *pt_pila, int size){ pt_pila->size=size; pt_pila->TOS=0; if((pt_pila->buffer=(prodotto *)malloc(size*sizeof(prodotto)))==0){ printf("\nErrore di allocazione della memoria"); exit(1); } } Boolean aggiungi_prodotto(scontrino *pt_pila, prodotto value){ if(pt_pila->TOS < pt_pila->size){ (pt_pila->buffer)[pt_pila->TOS]=value; (pt_pila->TOS)++; return TRUE; } else return FALSE; } Boolean elimina_prodotto(scontrino *pt_pila, prodotto *pt_value){ if(pt_pila->TOS>0){ (pt_pila->TOS)--; *pt_value=(pt_pila->buffer)[pt_pila->TOS]; return TRUE; } else return FALSE; } /*ritorna il totale della spesa contenuta nello scontrino sc, pari alla somma di tutti i prezzi dei singoli prodotti presenti nella lista*/ double totale_spesa (const scontrino sc){ int i; double total=0; for(i=0;i<sc.TOS;i++){ total+=(sc.buffer)[i].prezzo; } return total; } /*visualizza lo scontrino sc omettendo il codice (descrizione e prezzo)*/ void stampa_scontrino (const scontrino sc){ int i; double total=0; for(i=0;i<sc.TOS;i++){ printf("\n %s\t%lf",(sc.buffer)[i].descrizione ,(sc.buffer) [i].prezzo); } } /*Esercizio 5: realizza un lettore di codici a barre*/ #include<stdio.h> #define SIZE 12 #define MAXSIZE 50 typedef unsigned short int boolean; #define TRUE 1 #define FALSE 0 int read_file(FILE *fp, int cod[SIZE]); void load_codes(int all_codes[][MAXSIZE], int *rowp); boolean control_code(int one_code[SIZE]); void print_code_control(int one_code[SIZE], char *result); void write_file(int one_code[SIZE],FILE *fp, char *result); main(){ int cod[SIZE]; int all_codes[SIZE][MAXSIZE]; //matrice per memorizzare i codici int numrows; //numero di righe della matrice utilizzate int i; boolean result; FILE *output; //file di output load_codes(all_codes, &numrows); output=fopen("control.txt","w"); for(i=0;i<numrows;i++){ result=control_code(all_codes[i]); if (result==TRUE) { print_code_control(all_codes[i], "convalidato"); write_file(all_codes[i],output,"convalidato"); } else{ print_code_control(all_codes[i], "errore nel codice a barre"); write_file(all_codes[i], output,"errore nel codice a barre"); } } fclose(output); system("PAUSE"); } /*legge da un file un codice a barre: restituisce :1 per input corretto; 0 per errore; EOF per fine file*/ int read_file(FILE *fp, int cod[SIZE]){ int i,status; for(i=0;i<SIZE;i++){ status=fscanf(fp, "%d", &cod[i]); if(status!=1 && status!=EOF) status=0; else if(status==EOF) break; } return(status); } /*Apre il file codes.txt e legge i dati da salvare in all_codes fino alla fine del file. Interrompe la lettura se ci sono piu' di MAXSIZE codici nel file o se viene letto un dato non valido. Dopo ogni singola lettura (chiamando read_file) della matrice all_codes*/ memorizza il codice in una riga void load_codes(int all_codes[][MAXSIZE], int *rowp){ FILE *input; int data[SIZE]; int i,j, status; /*acquisisci i dati dal file*/ input=fopen("codes.txt","r"); i=0; do{ if((status=read_file(input,data))==1){ for(j=0;j<SIZE;j++) i++; } }while(status==1 && i<SIZE); fclose(input); all_codes[i][j]=data[j]; /*visualizza un messaggio di errore in caso di uscita prematura*/ if(status==0){ printf("\n ***Errore nel formato***\n"); printf("***Usa solo i primi %d dati\n",i); } else if(status!=EOF){ printf("\n ***il file contiene troppi dati***\n"); printf("***Usa solo i primi %d dati\n",i); } *rowp=i; } /*calcola la cifra di controllo di un codice a barre (one_code) e la confronta con l'ultima cifra del codice a barre. Se le due cifre corrispondono, restituisce TRUE, altrimenti FALSE*/ boolean control_code(int one_code[SIZE]){ int control; //cifra di controllo int i,resto; int evensum=0;//somme parziali delle posizioni pari int oddsum=0;//somme parziali delle posizioni dispari /*calcola i passi 1 e 2*/ for(i=0;i<SIZE-1;i++){ if(i%2==0) evensum+=one_code[i]; //per passo1 else oddsum+=one_code[i];//per passo 2 } evensum=evensum*3; oddsum=evensum+oddsum; printf("\n passo1: %d\n passo 2: %d",evensum,oddsum); resto=oddsum%10; if(resto) control=10-resto; else control=0; printf("\ncontrollo=%d ",control); if(control==one_code[SIZE-1]) return TRUE; else return FALSE; } /*visualizza un codice con il risultato delcontrollo sul file di output*/ void print_code_control(int one_code[SIZE], char *result){ int i=0; printf("\n %d",one_code[i]); for(i=1;i<SIZE;i++){ printf("\t %d",one_code[i]); } printf("\t%s",result); } /*scrive un codice con il risultato delcontrollo sul file di output*/ void write_file(int one_code[SIZE], FILE * fp, char *result){ int j, status; /*scrivi i dati sul file*/ for(j=0;j<SIZE;j++){ if((status=fprintf(fp,"%d\t", one_code[j]))!=2){ printf("Errore di scrittura"); break; } } fprintf(fp,"%s\n",result); }
© Copyright 2024 Paperzz