RACCOLTA DI ESERCIZI SVOLTI SARA BRUNETTI

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);
}