Soluzioni 26/07/2012

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