Esercizio 1
#include <stdio.h> #include <assert.h> #include <string.h> #define LEN 1000 // Confronta le due stringhe s,t, e trova il primo carattere k // tale che s[k] != t[k] se esiste. Restituisce -1 se s == t. int compare(char *s, char *t) { int k = 0; while (s[k] != '\0' && t[k] != '\0' && s[k] == t[k]) k++; if (s[k] != t[k]) return k; else return -1; } // Stampa un intorno di (al +) 5 caratteri delle stringhe s e t intorno a k. // Si usa una stringa temporanea buf, dove si copia il segmento s[start..end] // ed il segmento t[start..end]. con start <= k <= end // Bisogna assicurarsi che start >= 0 e end < strlen(s) e end < strlen(t) void output(char *s, char *t, int linea, int k) { char buf[100]; int start = k; for (int i=0; i<5 && start > 0; i++) start--; int end = k; for (int i=0; i<5 && t[end]!='\0' && s[end]!='\0'; i++) end++; strncpy(buf,s+start,end-start+1); buf[end-start+1] = '\0'; printf("%3d > %s\n",linea,buf); strncpy(buf,t+start,end-start+1); buf[end-start+1] = '\0'; printf("%3d < %s\n",linea,buf); for (int i=0; i<k-start+1; i++) buf[i] = ' '; buf[k-start+1] = '\0'; printf(" %s!\n",buf); } /* Apriamo i file in argv, in lettura, poi leggiamo riga per riga da entrambi i file, fino a quando non arriviamo alla fine di uno dei due. Confrontiamo le due stringhe e stampiamo eventualmente se sono diverse, con le funzioni sopra. */ int main(int argc, char *argv[]) { if (argc < 3) { printf("confronta <file1> <file2>\n"); return 1; } FILE *file1 = fopen(argv[1],"r"); FILE *file2 = fopen(argv[2],"r"); if (file1 == NULL || file2 == NULL) return 1; char alpha[LEN]; char beta[LEN]; int linea = 1; while (!feof(file1) || !feof(file2)) { fgets(alpha,LEN,file1); fgets(beta,LEN,file2); int k = compare(alpha,beta); if (k >= 0) output(alpha,beta,linea,k); linea++; } fclose(file1); fclose(file2); return 0; }
Esercizio 2
#include <stdio.h> #include <stdbool.h> #include <math.h> #include <stdlib.h> #include <time.h> #define N 200 #define MORTA 0 #define VIVA 1 // Prima di queste funzioni si consiglia di studiare la main. // copiam -> a = b tra matrici n x m void copiam(int a[N][N], int b[N][N], int n, int m) { for (int i=0; i<n; i++) for (int j=0; j<m; j++) a[i][j] = b[i][j]; } // uguali -> a == b tra matrici n x m bool uguali(int a[N][N], int b[N][N], int n, int m) { for (int i=0; i<n; i++) for (int j=0; j<m; j++) if (a[i][j] != b[i][j]) return false; return true; } // conto il numero di vicini della cellula (i,j) vive. // ci si muove in a[][] come se fosse un toro, quindi le // operazioni sugli indici di riga,colonna, sono fatte modulo n,m. // Il ciclo k in -1,0,1 e l in -1,0,1 consente di visitare tutti // i vicini di una cella int contavicini_vivi(int a[N][N], int i, int j, int n, int m) { int count = 0; for (int l=-1; l <= 1; l++) for (int k=-1; k <= 1; k++) { if (l == 0 && k == 0) continue; if (a[(i+l+n) % n][(j+k+m) % m] == VIVA) count++; } return count; } // Inizializza la matrice a in modo che a[i][j] == VIVO con probabilità p. // Se si vuole simulare una variabile di Bernulli (VIVO,MORTO) con // P(VIVO) = p, P(MORTO) = 1-p, allora basta generare un punto x uniforme in [0,1] // e porre a[i][j] = VIVO se x < p. Perche X unif. in [0,1] => P(X < p) = p void inizializza(int a[N][N], double p, int n, int m) { for (int i=0; i<n; i++) for (int j=0; j<m; j++) { double k = (double)rand() / RAND_MAX; // k in [0,1] a[i][j] = (k < p) ? VIVA : MORTA; } } void printmatrix(int a[N][N], int n, int m) { for (int i=0; i<n; i++) { for (int j=0; j<m; j++) if (a[i][j] == VIVA) printf("*"); else printf(" "); printf("\n"); } printf("\n"); } int main(int argc, char *argv[]) { srand(time(NULL)); if (argc < 4) { printf("errore\n"); return 1; } // leggo gli argomenti dalla linea di comando int n = atoi(argv[1]); int m = atoi(argv[2]); double p = atof(argv[3]); printf("Simulo LIFE di dimensione %dx%d (p = %f)\n",n,m,p); /* Rappresentiamo lo stato del sistema con due matrici di interi. M0 e' lo stato corrente, per passare da tempo t a t+1, dobbiamo cambiare i valori della matrice M0. Non possiamo farlo in loco perche se cambiamo i valori intorno ad una cellula, allora l'evoluzione non dipenderebbe solo dai valori del tempo corrente. Usiamo quindi due matrici, aggiorniamo M1, e poi, copiamo il contenuto di M1 su M0 */ int M0[N][N], M1[N][N]; inizializza(M0, p, n, m); int tempo = 0; printf("--------- T = %d ------------\n",tempo++); printmatrix(M0,n,m); getchar(); // usiamo una getchar per fare una pausa, ricordarsi di premere invio. while (1) { // Applichiamo le regole per passare dallo stato t in M0 // allo stato t+1 in M1. for (int i=0; i<n; i++) for (int j=0; j<m; j++) { int k = contavicini_vivi(M0, i, j, n, m); if (M0[i][j] == VIVA) { if (k == 2 || k == 3) M1[i][j] = VIVA; else M1[i][j] = MORTA; } else if (k == 3) M1[i][j] = VIVA; else M1[i][j] = MORTA; } if (uguali(M0,M1,n,m)) break; system("CLS"); printf("--------- T = %d ------------\n",tempo++); printmatrix(M1,n,m); getchar(); copiam(M0,M1,n,m); } }
Esercizio 3