1
0

feat: Initial commit

This commit is contained in:
2024-03-22 17:37:24 +01:00
parent 4288bd63a1
commit 6732a7a166
120 changed files with 9620 additions and 0 deletions

2
.gitignore vendored
View File

@@ -52,3 +52,5 @@ Module.symvers
Mkfile.old
dkms.conf
# GDB history
.gdb_history

View File

@@ -0,0 +1,94 @@
// Laboratorio 1 - Esercizio 1
// Matteo Schiff - s295565
#include <stdbool.h>
#include <ctype.h>
#include <stdio.h>
char *cercaRegexp(char *src, char *regexp);
// NOTE: regexp has to be incremented after calling this function
bool checkChar(char src, char **regexp)
{
switch (**regexp)
{
case '.':
return true;
case '[':
(*regexp)++;
int negate = **regexp == '^';
if (negate)
(*regexp)++;
do
{
if (src == **regexp) {
while (**regexp != ']')
(*regexp)++;
return !negate;
}
(*regexp)++;
} while (**regexp != ']');
return negate;
case '\\':
(*regexp)++;
if (**regexp == 'a') {
return islower(src);
} else if (**regexp == 'A') {
return isupper(src);
}
return false; // NOTE: regex is not valid
default:
return src == **regexp;
}
}
bool matchSubstring(char *src, char *regexp)
{
char *cur_s = src;
char *cur_meta = regexp;
while (*cur_meta != 0)
{
// match failed if regex check is false or if we reached the end
// of the string without reaching the end of the regex
if (*cur_s == 0 || !checkChar(*cur_s, &cur_meta))
return false;
cur_s++;
cur_meta++;
}
return true;
}
char *searchRegexp(char *src, char *regexp)
{
char *cur_s = src;
while (*cur_s != 0)
{
if (matchSubstring(cur_s, regexp))
return cur_s;
cur_s++;
}
return 0;
}
int main(int argc, char ** argv) {
if (argc != 3) {
puts("USAGE: ./esercizio1 string regexp");
return 1;
}
char * substr = searchRegexp(argv[1], argv[2]);
if (!substr) {
puts("No matches");
} else {
puts(substr);
}
return 0;
}

View File

@@ -0,0 +1,7 @@
6
GTT004 Marmolada Sebastopoli 2018/11/10 00:01:02 00:12:00 3
GTT003 Einaudi Cso_Trapani 2018/09/10 14:11:23 14:38:23 2
GTT002 Politecnico XVIII_Dicembre 2018/10/10 10:01:23 10:12:08 4
GTT002 Politecnico Piazza_Statuto 2018/11/10 23:11:59 23:20:07 0
GTT001 Braccini Porta_Nuova 2018/12/10 19:50:00 20:06:00 1
GTT001 Braccini Porta_Nuova 2018/10/10 18:50:00 19:07:25 1

View File

@@ -0,0 +1,249 @@
// Laboratorio 1 - Esercizio 2
// Matteo Schiff - s295565
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX_LEN 30
#define MAX_ROWS 1000
const int MAXL = 50;
typedef struct Time {
unsigned int hours;
unsigned int minutes;
unsigned int seconds;
} time;
typedef struct Date {
unsigned int year;
unsigned int month;
unsigned int day;
} date;
typedef struct Corsa {
char codice_tratta[MAX_LEN];
char partenza[MAX_LEN];
char destinazione[MAX_LEN];
date data;
time ora_partenza;
time ora_arrivo;
unsigned int ritardo;
} corsa;
typedef enum {
r_date, r_partenza, r_capolinea, r_ritardo, r_ritardo_tot, r_fine
} t_comandi;
char* toLower(char* s);
t_comandi leggiComando();
int confrontaDate(date a, date b);
void stampaCorsa(corsa corsa);
void data(char * argomenti, corsa corse[MAX_ROWS], int N);
void partenza(char * argomenti, corsa corse[MAX_ROWS], int N);
void capolinea(char * argomenti, corsa corse[MAX_ROWS], int N);
void ritardo(char * argomenti, corsa corse[MAX_ROWS], int N);
void ritardoTot(char * argomenti, corsa corse[MAX_ROWS], int N);
void menuParola (corsa corse[MAX_ROWS], int N);
int loadFile(corsa corse[MAX_ROWS], int * N, char * filename);
// Trasforma in lowercase tutti i caratteri di una stringa
char* toLower(char* s) {
for(char *p=s; *p; p++) *p=tolower(*p);
return s;
}
t_comandi leggiComando() {
t_comandi c;
char cmd[MAXL];
char tabella[7][12] = {
"date", "partenza", "capolinea", "ritardo", "ritardo_tot", "fine"
};
printf("comando (date/partenza/capolinea");
printf("/ritardo/ritardo_tot/fine): ");
scanf("%s",cmd); toLower(cmd);
c=r_date;
while(c<7 && strcmp(cmd,tabella[c])!=0)
c++;
return (c);
}
// restituisce true se la prima data è successiva o coincidente alla seconda
int confrontaDate(date a, date b) {
if (a.year > b.year)
return true;
else if (a.year < b.year)
return false;
if (a.month > b.month)
return true;
else if (a.month < b.month)
return false;
if (a.day >= b.day)
return true;
return false;
}
void stampaCorsa(corsa corsa) {
printf(" - %s %s %s, data: %4u/%02u/%02u, ora di partenza: %02u:%02u:%02u, ora di arrivo: %02u:%02u:%02u, ritardo %d minuto\n",
corsa.codice_tratta, corsa.partenza, corsa.destinazione,
corsa.data.year, corsa.data.month, corsa.data.day,
corsa.ora_partenza.hours, corsa.ora_partenza.minutes, corsa.ora_partenza.seconds,
corsa.ora_arrivo.hours, corsa.ora_arrivo.minutes, corsa.ora_arrivo.seconds,
corsa.ritardo);
}
void data(char * argomenti, corsa corse[MAX_ROWS], int N) {
date data_inizio, data_fine;
if (sscanf(argomenti, " %4u/%2u/%2u %4u/%2u/%2u", &data_inizio.year, &data_inizio.month, &data_inizio.day, &data_fine.year, &data_fine.month, &data_fine.day) != 6) {
puts("Date non valide. La sintassi è 'date <data inizio> <data fine>'");
return;
}
puts("Elenco corse con partenza compresa nell'intervallo specificato:\n");
for (int i = 0; i < N; i++) {
if (confrontaDate(corse[i].data, data_inizio) && confrontaDate(data_fine, corse[i].data)) {
stampaCorsa(corse[i]);
}
}
}
void partenza(char * argomenti, corsa corse[MAX_ROWS], int N) {
char partenza[30];
if (sscanf(argomenti, " %30s", partenza) != 1) {
puts("Partenza non valida. La sintassi è 'partenza <partenza>'");
return;
}
printf("Elenco corse con partenza da %s:\n", partenza);
for (int i = 0; i < N; i++) {
if (strcmp(partenza, corse[i].partenza) == 0) {
stampaCorsa(corse[i]);
}
}
}
void capolinea(char * argomenti, corsa corse[MAX_ROWS], int N) {
char capolinea[30];
if (sscanf(argomenti, " %30s", capolinea) != 1) {
puts("Capolinea non valido. La sintassi è 'capolinea <capolinea>'");
return;
}
printf("Elenco corse con capolinea da %s:\n", capolinea);
for (int i = 0; i < N; i++) {
if (strcmp(capolinea, corse[i].destinazione) == 0) {
stampaCorsa(corse[i]);
}
}
}
void ritardo(char * argomenti, corsa corse[MAX_ROWS], int N) {
date data_inizio, data_fine;
if (sscanf(argomenti, " %4u/%2u/%2u %4u/%2u/%2u", &data_inizio.year, &data_inizio.month, &data_inizio.day, &data_fine.year, &data_fine.month, &data_fine.day) != 6) {
puts("Date non valide. La sintassi è 'date <data inizio> <data fine>'");
return;
}
puts("Eleco corse con ritardo nell'intervallo di date specificato:\n");
for (int i = 0; i < N; i++) {
if (confrontaDate(corse[i].data, data_inizio) && confrontaDate(data_fine, corse[i].data) && corse[i].ritardo > 0) {
stampaCorsa(corse[i]);
}
}
}
void ritardoTot(char * argomenti, corsa corse[MAX_ROWS], int N) {
char codice_tratta[30];
if (sscanf(argomenti, " %30s", codice_tratta) != 1) {
puts("Codice di tratta non valido. La sintassi è 'ritardo_tot <codice tratta>'");
return;
}
unsigned int sum = 0;
for (int i = 0; i < N; i++) {
if (strcmp(codice_tratta, corse[i].codice_tratta) == 0) {
sum += corse[i].ritardo;
}
}
printf("Il ritardo complessivo accumulato sulla tratta %s è pari a %u minuti.\n", codice_tratta, sum);
}
void menuParola (corsa corse[MAX_ROWS], int N) {
t_comandi comando;
char argomenti[MAXL];
int i, continua=1;
while (continua) {
comando = leggiComando();
fgets(argomenti,MAXL,stdin); /* resto della riga */
switch (comando) {
case r_date: data(argomenti, corse, N); break;
case r_partenza: partenza(argomenti, corse, N); break;
case r_capolinea: capolinea(argomenti, corse, N); break;
case r_ritardo: ritardo(argomenti, corse, N); break;
case r_ritardo_tot: ritardoTot(argomenti, corse, N); break;
case r_fine: continua = 0; break;
default:
puts("Comando non valido\n");
}
}
}
int loadFile(corsa corse[MAX_ROWS], int * N, char * filename) {
FILE *fp_read;
unsigned int lines, i;
if ((fp_read = fopen(filename, "r")) == NULL)
{
puts("Impossibile aprire il file");
return 1;
}
fscanf(fp_read, "%u\n", &lines);
if (lines > MAX_ROWS) {
fclose(fp_read);
return 1;
}
for (i = 0; i < lines; i++) {
int num_read = fscanf(fp_read, "%30s %30s %30s %4u/%2u/%2u %2u:%2u:%2u %2u:%2u:%2u %u\n", corse[i].codice_tratta, corse[i].partenza, corse[i].destinazione, &corse[i].data.year, &corse[i].data.month, &corse[i].data.day, &corse[i].ora_partenza.hours, &corse[i].ora_partenza.minutes, &corse[i].ora_partenza.seconds, &corse[i].ora_arrivo.hours, &corse[i].ora_arrivo.minutes, &corse[i].ora_arrivo.seconds, &corse[i].ritardo);
if (num_read != 13) {
// la stringa è mal formattata
printf("File non formattato correttamente. Errore a linea %d\n", i+1);
fclose(fp_read);
return 1;
}
}
fclose(fp_read);
*N = i;
return 0;
}
int main() {
int N;
corsa corse[MAX_ROWS];
if (loadFile(corse, &N, "./corse.txt")) {
return 1;
}
if (corse == NULL) {
return 1;
}
menuParola(corse, N);
return 0;
}

View File

@@ -0,0 +1,7 @@
6
GTT004 Marmolada Sebastopoli 2018/11/10 00:01:02 00:12:00 3
GTT003 Einaudi Cso_Trapani 2018/09/10 14:11:23 14:38:23 2
GTT002 Politecnico XVIII_Dicembre 2018/10/10 10:01:23 10:12:08 4
GTT002 Politecnico Piazza_Statuto 2018/11/10 23:11:59 23:20:07 0
GTT001 Braccini Porta_Nuova 2018/12/10 19:50:00 20:06:00 1
GTT001 Braccini Porta_Nuova 2018/10/10 18:50:00 19:07:25 1

View File

@@ -0,0 +1,451 @@
// Laboratorio 1 - Esercizio 3
// Matteo Schiff - s295565
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX_LEN 30
#define MAX_ROWS 1000
const int MAXL = 50;
typedef struct Time
{
unsigned int hours;
unsigned int minutes;
unsigned int seconds;
} time;
typedef struct Date
{
unsigned int year;
unsigned int month;
unsigned int day;
} date;
typedef struct Corsa
{
char codice_tratta[MAX_LEN];
char partenza[MAX_LEN];
char destinazione[MAX_LEN];
date data;
time ora_partenza;
time ora_arrivo;
unsigned int ritardo;
} corsa;
typedef enum
{
k_codice_tratta,
k_partenza,
k_destinazione,
k_data
} corsa_keys;
typedef enum
{
r_stampa,
r_ordina_data,
r_ordina_codice,
r_ordina_partenza,
r_ordina_destinazione,
r_ricerca_partenza,
r_fine
} t_comandi;
char *toLower(char *s);
t_comandi leggiComando();
int confronta_data_ora(corsa *a, corsa *b);
void stampa_corsa(corsa corsa);
void stampa_corse(char *argomenti, corsa *corse[MAX_ROWS], int N);
void ordina_data(char *argomenti, corsa * corse[MAX_ROWS], int N);
void ordina_codice(char *argomenti, corsa * corse[MAX_ROWS], int N);
void ordina_partenza(char *argomenti, corsa * corse[MAX_ROWS], int N);
void ordina_arrivo(char *argomenti, corsa * corse[MAX_ROWS], int N);
void ricerca(char *argomenti, corsa * corse[MAX_ROWS], int N);
void menuParola(corsa * corse[MAX_ROWS], int N);
int loadFile(corsa corse[MAX_ROWS], int *N, char *filename);
// Trasforma in lowercase tutti i caratteri di una stringa
char *toLower(char *s)
{
for (char *p = s; *p; p++)
*p = tolower(*p);
return s;
}
t_comandi leggiComando()
{
t_comandi c;
char cmd[MAXL];
char tabella[8][20] = {
"stampa", "ordina_data", "ordina_codice", "ordina_partenza", "ordina_destinazione", "ricerca", "fine"};
printf("comando (stampa/ordina_data/ordina_codice");
printf("/ordina_partenza/ordina_destinazione/ricerca/fine): ");
scanf("%s", cmd);
toLower(cmd);
c = r_stampa;
while (c < 8 && strcmp(cmd, tabella[c]) != 0)
c++;
return (c);
}
corsa_keys interpreta_tratta(char *tratta)
{
corsa_keys c;
char cmd[MAXL];
char tabella[8][20] = {
"codice\n", "partenza\n", "destinazione\n", "data\n"};
c = k_codice_tratta;
while (c < 8 && strcmp(tratta, tabella[c]) != 0)
c++;
return (c);
}
// restituisce true se la prima data è successiva o coincidente alla seconda
int confronta_data_ora(corsa *a, corsa *b)
{
if (a->data.year > b->data.year)
return true;
else if (a->data.year < b->data.year)
return false;
if (a->data.month > b->data.month)
return true;
else if (a->data.month < b->data.month)
return false;
if (a->data.day > b->data.day)
return true;
else if (a->data.day < b->data.day)
return false;
if (a->ora_partenza.hours > b->ora_partenza.hours)
return true;
else if (a->ora_partenza.hours < b->ora_partenza.hours)
return false;
if (a->ora_partenza.minutes > b->ora_partenza.minutes)
return true;
else if (a->ora_partenza.minutes < b->ora_partenza.minutes)
return false;
if (a->ora_partenza.seconds >= b->ora_partenza.seconds)
return true;
return false;
}
int confronta_codice(corsa *a, corsa *b)
{
return strcmp(a->codice_tratta, b->codice_tratta);
}
int confronta_partenza(corsa *a, corsa *b)
{
return strcmp(a->partenza, b->partenza) >= 0;
}
int confronta_arrivo(corsa *a, corsa *b)
{
return strcmp(a->destinazione, b->destinazione) >= 0;
}
int confronta_chiave(corsa *a, corsa *b, corsa_keys chiave)
{
switch (chiave)
{
case k_codice_tratta:
return confronta_codice(a, b);
case k_destinazione:
return confronta_arrivo(a, b);
case k_partenza:
return confronta_partenza(a, b);
case k_data:
return confronta_data_ora(a, b);
}
}
int min(int x, int y)
{
return (x < y) ? x : y;
}
void merge(corsa *A[MAX_ROWS], int low, int mid, int high, corsa_keys chiave)
{
int i, j, k;
// Merge the temp arrays
corsa * temp[MAX_ROWS];
i = low;
j = mid+1;
k = 0;
while (i <= mid && j <= high)
{
if (!confronta_chiave(A[i], A[j], chiave))
{
temp[k] = A[i];
i++;
}
else
{
temp[k] = A[j];
j++;
}
k++;
}
// Copy the remaining elements of L[]
while (i <= mid)
{
temp[k] = A[i];
i++;
k++;
}
// Copy the remaining elements of R[]
while (j <= high)
{
temp[k] = A[j];
j++;
k++;
}
for (i = 0; i <= high - low; i++) {
A[i+low] = temp[i];
}
}
void mergesort_by_key(corsa *A[MAX_ROWS], int low, int high, corsa_keys key)
{
if (low >= high)
return;
// Finding mid element
int mid = low + (high - low) / 2;
// Recursively sorting both the halves
mergesort_by_key(A, low, mid, key);
mergesort_by_key(A, mid + 1, high, key);
// Merge the array
merge(A, low, mid, high, key);
}
void stampa_corsa(corsa corsa)
{
printf(" - %s %s %s, data: %4u/%02u/%02u, ora di partenza: %02u:%02u:%02u, ora di arrivo: %02u:%02u:%02u, ritardo %d minuto\n",
corsa.codice_tratta, corsa.partenza, corsa.destinazione,
corsa.data.year, corsa.data.month, corsa.data.day,
corsa.ora_partenza.hours, corsa.ora_partenza.minutes, corsa.ora_partenza.seconds,
corsa.ora_arrivo.hours, corsa.ora_arrivo.minutes, corsa.ora_arrivo.seconds,
corsa.ritardo);
}
void stampa_corse(char *argomenti, corsa * corse[MAX_ROWS], int N)
{
puts("Elenco delle corse:");
for (int i = 0; i < N; i++)
{
stampa_corsa(*(corse[i]));
}
}
void ordina_data(char *argomenti, corsa * corse[MAX_ROWS], int N)
{
puts("Ordino le corse per data\n");
mergesort_by_key(corse, 0, N - 1, k_data);
}
void ordina_codice(char *argomenti, corsa * corse[MAX_ROWS], int N)
{
puts("Ordino le corse per codice tratta\n");
mergesort_by_key(corse, 0, N - 1, k_codice_tratta);
}
void ordina_partenza(char *argomenti, corsa * corse[MAX_ROWS], int N)
{
puts("Ordino le corse per partenza\n");
mergesort_by_key(corse, 0, N - 1, k_partenza);
}
void ordina_arrivo(char *argomenti, corsa * corse[MAX_ROWS], int N)
{
puts("Ordino le corse per destinazione\n");
mergesort_by_key(corse, 0, N - 1, k_destinazione);
}
void ricerca_dicotomica(corsa *corse[MAX_ROWS], char *partenza, int partenza_len, int N)
{
int s = 0, e = N - 1, i = (e + s) / 2, res = strncmp(partenza, corse[i]->partenza, partenza_len);
while (res != 0)
{
if (e-s <= 0) { //nothing found
puts("Nessun risultato");
return;
}
if (res > 0)
{
s = i+1;
}
else
{
e = i-1;
}
i = (e + s) / 2;
res = strncmp(partenza, corse[i]->partenza, partenza_len);
}
s = i;
e = i;
while (s > 0 && !strncmp(partenza, corse[s - 1]->partenza, partenza_len))
s--;
while (e < (N - 1) && !strncmp(partenza, corse[e + 1]->partenza, partenza_len))
e++;
for (i = s; i <= e; i++)
{
stampa_corsa(*(corse[i]));
}
}
void ricerca_lineare(corsa *corse[MAX_ROWS], char *partenza, int partenza_len, int N)
{
for (int i = 0; i < N; i++) {
if (!strncmp(partenza, corse[i]->partenza, partenza_len))
stampa_corsa(*(corse[i]));
}
}
void ricerca_partenza(char *argomenti, corsa * corse[MAX_ROWS], int N)
{
char partenza[30], tipo[30], partenza_len;
if (sscanf(argomenti, " %30s %30s", tipo, partenza) != 2)
{
puts("Partenza non valida. La sintassi è 'partenza [dicotomica/lineare] <partenza>'");
return;
}
partenza_len = strlen(partenza);
puts("Risultati della ricerca per stazione di partenza:");
if (!strcmp(tipo, "dicotomica"))
{
ricerca_dicotomica(corse, partenza, partenza_len, N);
}
else
{
ricerca_lineare(corse, partenza, partenza_len, N);
}
}
void menuParola(corsa * corse[MAX_ROWS], int N)
{
t_comandi comando;
char argomenti[MAXL];
int i, continua = 1;
while (continua)
{
comando = leggiComando();
fgets(argomenti, MAXL, stdin); /* resto della riga */
switch (comando)
{
case r_stampa:
stampa_corse(argomenti, corse, N);
break;
case r_ordina_data:
ordina_data(argomenti, corse, N);
break;
case r_ordina_codice:
ordina_codice(argomenti, corse, N);
break;
case r_ordina_destinazione:
ordina_arrivo(argomenti, corse, N);
break;
case r_ordina_partenza:
ordina_partenza(argomenti, corse, N);
break;
case r_ricerca_partenza:
ricerca_partenza(argomenti, corse, N);
break;
case r_fine:
continua = 0;
break;
default:
puts("Comando non valido\n");
}
}
}
void fillArray(corsa corse[MAX_ROWS], corsa *corse_ptr[MAX_ROWS], int N)
{
for (int i = 0; i < N; i++)
{
corse_ptr[i] = &corse[i];
}
}
int loadFile(corsa corse[MAX_ROWS], int *N, char *filename)
{
FILE *fp_read;
unsigned int lines, i;
if ((fp_read = fopen(filename, "r")) == NULL)
{
puts("Impossibile aprire il file");
return 1;
}
fscanf(fp_read, "%u\n", &lines);
if (lines > MAX_ROWS)
{
fclose(fp_read);
return 1;
}
for (i = 0; i < lines; i++)
{
int num_read = fscanf(fp_read, "%30s %30s %30s %4u/%2u/%2u %2u:%2u:%2u %2u:%2u:%2u %u\n", corse[i].codice_tratta, corse[i].partenza, corse[i].destinazione, &corse[i].data.year, &corse[i].data.month, &corse[i].data.day, &corse[i].ora_partenza.hours, &corse[i].ora_partenza.minutes, &corse[i].ora_partenza.seconds, &corse[i].ora_arrivo.hours, &corse[i].ora_arrivo.minutes, &corse[i].ora_arrivo.seconds, &corse[i].ritardo);
if (num_read != 13)
{
// la stringa è mal formattata
printf("File non formattato correttamente. Errore a linea %d\n", i + 1);
fclose(fp_read);
return 1;
}
}
fclose(fp_read);
*N = i;
return 0;
}
int main()
{
int N;
corsa corse[MAX_ROWS];
corsa * corse_ptr[MAX_ROWS];
if (loadFile(corse, &N, "./corse.txt"))
{
return 1;
}
if (corse == NULL)
{
return 1;
}
fillArray(corse, corse_ptr, N);
menuParola(corse_ptr, N);
return 0;
}

View File

@@ -0,0 +1,7 @@
6
GTT004 Marmolada Sebastopoli 2018/11/10 00:01:02 00:12:00 3
GTT003 Einaudi Cso_Trapani 2018/09/10 14:11:23 14:38:23 2
GTT002 Politecnico XVIII_Dicembre 2018/10/10 10:01:23 10:12:08 4
GTT002 Politecnico Piazza_Statuto 2018/11/10 23:11:59 23:20:07 0
GTT001 Braccini Porta_Nuova 2018/12/10 19:50:00 20:06:00 1
GTT001 Braccini Porta_Nuova 2018/10/10 18:50:00 19:07:25 1

View File

@@ -0,0 +1,476 @@
// Laboratorio 1 - Esercizio 4
// Matteo Schiff - s295565
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX_LEN 30
#define MAX_ROWS 1000
const int MAXL = 50;
typedef struct Time
{
unsigned int hours;
unsigned int minutes;
unsigned int seconds;
} time;
typedef struct Date
{
unsigned int year;
unsigned int month;
unsigned int day;
} date;
typedef struct Corsa
{
char codice_tratta[MAX_LEN];
char partenza[MAX_LEN];
char destinazione[MAX_LEN];
date data;
time ora_partenza;
time ora_arrivo;
unsigned int ritardo;
} corsa;
typedef struct Raccolta
{
corsa *corse_data[MAX_ROWS];
corsa *corse_codice[MAX_ROWS];
corsa *corse_partenza[MAX_ROWS];
corsa *corse_arrivo[MAX_ROWS];
} raccolta;
typedef enum
{
k_codice_tratta,
k_partenza,
k_destinazione,
k_data
} corsa_keys;
typedef enum
{
r_stampa,
r_ordina_data,
r_ordina_codice,
r_ordina_partenza,
r_ordina_destinazione,
r_ricerca_partenza,
r_fine
} t_comandi;
// Trasforma in lowercase tutti i caratteri di una stringa
char *toLower(char *s)
{
for (char *p = s; *p; p++)
*p = tolower(*p);
return s;
}
t_comandi leggiComando()
{
t_comandi c;
char cmd[MAXL];
char tabella[8][20] = {
"stampa", "ordina_data", "ordina_codice", "ordina_partenza", "ordina_destinazione", "ricerca", "fine"};
printf("comando (stampa/ordina_data/ordina_codice");
printf("/ordina_partenza/ordina_destinazione/ricerca/fine): ");
scanf("%s", cmd);
toLower(cmd);
c = r_stampa;
while (c < 8 && strcmp(cmd, tabella[c]) != 0)
c++;
return (c);
}
corsa_keys interpreta_tratta(char *tratta)
{
corsa_keys c;
char cmd[MAXL];
char tabella[8][20] = {
"codice\n", "partenza\n", "destinazione\n", "data\n"};
c = k_codice_tratta;
while (c < 8 && strcmp(tratta, tabella[c]) != 0)
c++;
return (c);
}
// restituisce true se la prima data è successiva o coincidente alla seconda
int confronta_data_ora(corsa *a, corsa *b)
{
if (a->data.year > b->data.year)
return true;
else if (a->data.year < b->data.year)
return false;
if (a->data.month > b->data.month)
return true;
else if (a->data.month < b->data.month)
return false;
if (a->data.day > b->data.day)
return true;
else if (a->data.day < b->data.day)
return false;
if (a->ora_partenza.hours > b->ora_partenza.hours)
return true;
else if (a->ora_partenza.hours < b->ora_partenza.hours)
return false;
if (a->ora_partenza.minutes > b->ora_partenza.minutes)
return true;
else if (a->ora_partenza.minutes < b->ora_partenza.minutes)
return false;
if (a->ora_partenza.seconds >= b->ora_partenza.seconds)
return true;
return false;
}
int confronta_codice(corsa *a, corsa *b)
{
return strcmp(a->codice_tratta, b->codice_tratta);
}
int confronta_partenza(corsa *a, corsa *b)
{
return strcmp(a->partenza, b->partenza) >= 0;
}
int confronta_arrivo(corsa *a, corsa *b)
{
return strcmp(a->destinazione, b->destinazione) >= 0;
}
int confronta_chiave(corsa *a, corsa *b, corsa_keys chiave)
{
switch (chiave)
{
case k_codice_tratta:
return confronta_codice(a, b);
case k_destinazione:
return confronta_arrivo(a, b);
case k_partenza:
return confronta_partenza(a, b);
case k_data:
return confronta_data_ora(a, b);
}
}
int min(int x, int y)
{
return (x < y) ? x : y;
}
void merge(corsa *A[MAX_ROWS], int low, int mid, int high, corsa_keys chiave)
{
int i, j, k;
corsa * temp[MAX_ROWS];
// Merge the temp arrays
i = low;
j = mid+1;
k = 0;
while (i <= mid && j <= high)
{
if (!confronta_chiave(A[i], A[j], chiave))
{
temp[k] = A[i];
i++;
}
else
{
temp[k] = A[j];
j++;
}
k++;
}
// Copy the remaining elements of L[]
while (i <= mid)
{
temp[k] = A[i];
i++;
k++;
}
// Copy the remaining elements of R[]
while (j <= high)
{
temp[k] = A[j];
j++;
k++;
}
for (i = 0; i <= high - low; i++) {
A[i+low] = temp[i];
}
}
void mergesort_by_key(corsa *A[MAX_ROWS], int low, int high, corsa_keys key)
{
if (low >= high)
return;
// Finding mid element
int mid = low + (high - low) / 2;
// Recursively sorting both the halves
mergesort_by_key(A, low, mid, key);
mergesort_by_key(A, mid + 1, high, key);
// Merge the array
merge(A, low, mid, high, key);
}
void stampa_corsa(corsa corsa)
{
printf(" - %s %s %s, data: %4u/%02u/%02u, ora di partenza: %02u:%02u:%02u, ora di arrivo: %02u:%02u:%02u, ritardo %d minuto\n",
corsa.codice_tratta, corsa.partenza, corsa.destinazione,
corsa.data.year, corsa.data.month, corsa.data.day,
corsa.ora_partenza.hours, corsa.ora_partenza.minutes, corsa.ora_partenza.seconds,
corsa.ora_arrivo.hours, corsa.ora_arrivo.minutes, corsa.ora_arrivo.seconds,
corsa.ritardo);
}
void stampa_corse_vettore(corsa **corse, int N)
{
for (int i = 0; i < N; i++)
{
stampa_corsa(*(corse[i]));
}
}
void stampa_corse_scelta(char *argomenti, raccolta *rac, int N)
{
argomenti++; // salta lo spazio
switch (interpreta_tratta(argomenti))
{
case k_codice_tratta:
puts("Corse ordinate per codice:");
stampa_corse_vettore(rac->corse_codice, N);
break;
case k_data:
puts("Corse ordinate per data:");
stampa_corse_vettore(rac->corse_data, N);
break;
case k_destinazione:
puts("Corse ordinate per destinazione:");
stampa_corse_vettore(rac->corse_arrivo, N);
break;
case k_partenza:
puts("Corse ordinate per partenza:");
stampa_corse_vettore(rac->corse_partenza, N);
break;
default:
puts("Errore. La sintassi è 'stampa [codice/partenza/destinazione/data]'");
break;
}
}
void ordina_data(char *argomenti, raccolta *rac, int N)
{
puts("Ordino le corse per data\n");
mergesort_by_key(rac->corse_data, 0, N - 1, k_data);
}
void ordina_codice(char *argomenti, raccolta *rac, int N)
{
puts("Ordino le corse per codice tratta\n");
mergesort_by_key(rac->corse_codice, 0, N - 1, k_codice_tratta);
}
void ordina_partenza(char *argomenti, raccolta *rac, int N)
{
puts("Ordino le corse per partenza\n");
mergesort_by_key(rac->corse_partenza, 0, N - 1, k_partenza);
}
void ordina_arrivo(char *argomenti, raccolta *rac, int N)
{
puts("Ordino le corse per destinazione\n");
mergesort_by_key(rac->corse_arrivo, 0, N - 1, k_destinazione);
}
void ricerca_dicotomica(corsa *corse[MAX_ROWS], char *partenza, int partenza_len, int N)
{
int s = 0, e = N - 1, i = (e + s) / 2, res = strncmp(partenza, corse[i]->partenza, partenza_len);
while (res != 0)
{
if (e-s <= 0) { //nothing found
puts("Nessun risultato");
return;
}
if (res > 0)
{
s = i+1;
}
else
{
e = i-1;
}
i = (e + s) / 2;
res = strncmp(partenza, corse[i]->partenza, partenza_len);
}
s = i;
e = i;
while (s > 0 && !strncmp(partenza, corse[s - 1]->partenza, partenza_len))
s--;
while (e < (N - 1) && !strncmp(partenza, corse[e + 1]->partenza, partenza_len))
e++;
for (i = s; i <= e; i++)
{
stampa_corsa(*(corse[i]));
}
}
void ricerca_lineare(corsa *corse[MAX_ROWS], char *partenza, int partenza_len, int N)
{
for (int i = 0; i < N; i++) {
if (!strncmp(partenza, corse[i]->partenza, partenza_len))
stampa_corsa(*(corse[i]));
}
}
void ricerca_partenza(char *argomenti, raccolta *rac, int N)
{
char partenza[30], tipo[30], partenza_len;
if (sscanf(argomenti, " %30s %30s", tipo, partenza) != 2)
{
puts("Partenza non valida. La sintassi è 'partenza [dicotomica/lineare] <partenza>'");
return;
}
partenza_len = strlen(partenza);
puts("Risultati della ricerca per stazione di partenza:");
if (!strcmp(tipo, "dicotomica"))
{
ricerca_dicotomica(rac->corse_partenza, partenza, partenza_len, N);
}
else
{
ricerca_lineare(rac->corse_partenza, partenza, partenza_len, N);
}
}
void menuParola(raccolta *rac, int N)
{
t_comandi comando;
char argomenti[MAXL];
int i, continua = 1;
while (continua)
{
comando = leggiComando();
fgets(argomenti, MAXL, stdin); /* resto della riga */
switch (comando)
{
case r_stampa:
stampa_corse_scelta(argomenti, rac, N);
break;
case r_ordina_data:
ordina_data(argomenti, rac, N);
break;
case r_ordina_codice:
ordina_codice(argomenti, rac, N);
break;
case r_ordina_destinazione:
ordina_arrivo(argomenti, rac, N);
break;
case r_ordina_partenza:
ordina_partenza(argomenti, rac, N);
break;
case r_ricerca_partenza:
ricerca_partenza(argomenti, rac, N);
break;
case r_fine:
continua = 0;
break;
default:
puts("Comando non valido\n");
}
}
}
void fillArray(corsa corse[MAX_ROWS], corsa *corse_ptr[MAX_ROWS], int N)
{
for (int i = 0; i < N; i++)
{
corse_ptr[i] = &corse[i];
}
}
int loadFile(corsa corse[MAX_ROWS], int *N, char *filename)
{
FILE *fp_read;
unsigned int lines, i;
if ((fp_read = fopen(filename, "r")) == NULL)
{
puts("Impossibile aprire il file");
return 1;
}
fscanf(fp_read, "%u\n", &lines);
if (lines > MAX_ROWS)
{
fclose(fp_read);
return 1;
}
for (i = 0; i < lines; i++)
{
int num_read = fscanf(fp_read, "%30s %30s %30s %4u/%2u/%2u %2u:%2u:%2u %2u:%2u:%2u %u\n", corse[i].codice_tratta, corse[i].partenza, corse[i].destinazione, &corse[i].data.year, &corse[i].data.month, &corse[i].data.day, &corse[i].ora_partenza.hours, &corse[i].ora_partenza.minutes, &corse[i].ora_partenza.seconds, &corse[i].ora_arrivo.hours, &corse[i].ora_arrivo.minutes, &corse[i].ora_arrivo.seconds, &corse[i].ritardo);
if (num_read != 13)
{
// la stringa è mal formattata
printf("File non formattato correttamente. Errore a linea %d\n", i + 1);
fclose(fp_read);
return 1;
}
}
fclose(fp_read);
*N = i;
return 0;
}
int main()
{
int N;
corsa corse[MAX_ROWS];
raccolta rac;
if (loadFile(corse, &N, "./corse.txt"))
{
return 1;
}
if (corse == NULL)
{
return 1;
}
fillArray(corse, rac.corse_data, N);
fillArray(corse, rac.corse_codice, N);
fillArray(corse, rac.corse_partenza, N);
fillArray(corse, rac.corse_arrivo, N);
menuParola(&rac, N);
return 0;
}

View File

@@ -0,0 +1,45 @@
// Laboratorio 2 - Esercizio 1
// Matteo Schiff - s295565
#include <stdio.h>
#include <stdlib.h>
int gcd(int a, int b) {
if (b > a) { // inverti in modo che a > b
int c = a;
a = b;
b = c;
}
if (a == b)
return a;
if (b == 1)
return 1;
if (b % 2 == 0) {
if (a % 2 == 0) {
return 2*gcd(a/2,b/2);
} else {
return gcd(a, b/2);
}
} else if (a % 2 == 0) {
// il caso `a` pari, `b` dispari
// non è presente nel testo
return gcd(a/2,b);
}
return gcd((a-b)/2, b);
}
int main(int argc, char ** argv) {
int a, b;
if (argc != 3)
return 1;
a = atoi(argv[1]);
b = atoi(argv[2]);
printf("gcd: %i\n", gcd(a, b));
}

View File

@@ -0,0 +1,89 @@
// Laboratorio 2 - Esercizio 2
// Matteo Schiff - s295565
#include <stdio.h>
#include <stdlib.h>
int ** matrmalloc(int * nc, int * nr) {
FILE *fp_read;
if ((fp_read = fopen("mat.txt", "r")) == NULL)
{
puts("Impossibile aprire il file");
return NULL;
}
fscanf(fp_read, "%u %u\n", nr, nc);
int ** mat = malloc(*nr * sizeof(int *));
for (int i = 0; i < *nr; i++) {
int * row = malloc(*nc * sizeof(int));
for (int j = 0; j < *nc; j++) {
fscanf(fp_read, "%d ", &row[j]);
}
mat[i] = row;
}
fclose(fp_read);
return mat;
}
void matrfree(int **mat, int nr) {
for (int i = 0; i < nr; i++) {
free(mat[i]);
}
free(mat);
}
void separa(int **mat, int nr, int nc, int ** bianchi, int ** neri, int * nbianchi, int * nneri) {
int a = nc % 2;
int x = nc / 2;
int b = nr % 2;
int y = nr / 2;
*nneri = (x + a) * y + x * (y + b);
*nbianchi = x * y + (x+a) * (y + b);
*bianchi = malloc(*nbianchi * sizeof(int));
*neri = malloc(*nneri * sizeof(int));
int conta_bianchi = 0, conta_neri = 0;
for (int i = 0; i < nr; i++) {
for (int j = 0; j < nc; j++) {
if ((i+j) % 2 == 0) {
(*bianchi)[conta_bianchi++] = mat[i][j];
} else {
(*neri)[conta_neri++] = mat[i][j];
}
}
}
}
int main(int argc, char ** argv) {
int nc, nr;
int ** mat = matrmalloc(&nc, &nr);
if (mat == NULL) {
return 1;
}
int *bianchi, *neri, n_bianchi, n_neri;
separa(mat, nr, nc, &bianchi, &neri, &n_bianchi, &n_neri);
puts("Numeri su caselle bianche:");
for (int i = 0; i < n_bianchi; i++)
printf("%u\n", bianchi[i]);
puts("Numeri su caselle nere:");
for (int i = 0; i < n_neri; i++)
printf("%u\n", neri[i]);
matrfree(mat, nr);
free(bianchi);
free(neri);
return 0;
}

View File

@@ -0,0 +1,4 @@
3 3
1 2 3
4 5 6
7 8 9

View File

@@ -0,0 +1,8 @@
6
GTT004 Marmolada Sebastopoli 2018/11/10 00:01:02 00:12:00 3
GTT003 Einaudi Cso_Trapani 2018/09/10 14:11:23 14:38:23 2
GTT002 Politecnico XVIII_Dicembre 2018/10/10 10:01:23 10:12:08 4
GTT002 Politecnico Piazza_Statuto 2018/11/10 23:11:59 23:20:07 0
GTT001 Braccini Porta_Nuova 2018/12/10 19:50:00 20:06:00 1
GTT001 Braccini Porta_Nuova 2018/10/10 18:50:00 19:07:25 1

View File

@@ -0,0 +1,8 @@
6
GTT004 SantOttavio Sebastopoli 2018/11/10 00:01:02 00:12:00 3
GTT003 Vinzaglio Cso_Trapani 2018/09/10 14:11:23 14:38:23 2
GTT002 Politecnico XVIII_Dicembre 2018/10/10 10:01:23 10:12:08 4
GTT002 Politecnico Piazza_Statuto 2018/11/10 23:11:59 23:20:07 0
GTT001 XVIII_Dicembre Porta_Nuova 2018/12/10 19:50:00 20:06:00 1
GTT001 Braccini Porta_Nuova 2018/10/10 18:50:00 19:07:25 1

View File

@@ -0,0 +1,496 @@
// Laboratorio 2 - Esercizio 3
// Matteo Schiff - s295565
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
#include <ctype.h>
#define MAX_LEN 30
const int MAXL = 50;
typedef struct Time
{
unsigned int hours;
unsigned int minutes;
unsigned int seconds;
} time;
typedef struct Date
{
unsigned int year;
unsigned int month;
unsigned int day;
} date;
typedef struct Corsa
{
char codice_tratta[MAX_LEN];
char partenza[MAX_LEN];
char destinazione[MAX_LEN];
date data;
time ora_partenza;
time ora_arrivo;
unsigned int ritardo;
} corsa;
typedef struct Raccolta
{
int N;
corsa **corse_data;
corsa **corse_codice;
corsa **corse_partenza;
corsa **corse_arrivo;
corsa **temp;
} raccolta;
typedef enum
{
k_codice_tratta,
k_partenza,
k_destinazione,
k_data
} corsa_keys;
typedef enum
{
r_stampa,
r_ordina_data,
r_ordina_codice,
r_ordina_partenza,
r_ordina_destinazione,
r_ricerca_partenza,
r_carica,
r_fine
} t_comandi;
// Trasforma in lowercase tutti i caratteri di una stringa
char *toLower(char *s)
{
for (char *p = s; *p; p++)
*p = tolower(*p);
return s;
}
t_comandi leggiComando()
{
t_comandi c;
char cmd[MAXL];
char tabella[9][20] = {
"stampa", "ordina_data", "ordina_codice", "ordina_partenza", "ordina_destinazione", "ricerca", "carica", "fine"};
printf("comando (stampa/ordina_data/ordina_codice");
printf("/ordina_partenza/ordina_destinazione/ricerca/carica/fine): ");
scanf("%s", cmd);
toLower(cmd);
c = r_stampa;
while (c < 9 && strcmp(cmd, tabella[c]) != 0)
c++;
return (c);
}
corsa_keys interpreta_tratta(char *tratta)
{
corsa_keys c;
char cmd[MAXL];
char tabella[8][20] = {
"codice\n", "partenza\n", "destinazione\n", "data\n"};
c = k_codice_tratta;
while (c < 8 && strcmp(tratta, tabella[c]) != 0)
c++;
return (c);
}
// restituisce true se la prima data è successiva o coincidente alla seconda
int confronta_data_ora(corsa *a, corsa *b)
{
if (a->data.year > b->data.year)
return true;
else if (a->data.year < b->data.year)
return false;
if (a->data.month > b->data.month)
return true;
else if (a->data.month < b->data.month)
return false;
if (a->data.day > b->data.day)
return true;
else if (a->data.day < b->data.day)
return false;
if (a->ora_partenza.hours > b->ora_partenza.hours)
return true;
else if (a->ora_partenza.hours < b->ora_partenza.hours)
return false;
if (a->ora_partenza.minutes > b->ora_partenza.minutes)
return true;
else if (a->ora_partenza.minutes < b->ora_partenza.minutes)
return false;
if (a->ora_partenza.seconds >= b->ora_partenza.seconds)
return true;
return false;
}
int confronta_codice(corsa *a, corsa *b)
{
return strcmp(a->codice_tratta, b->codice_tratta);
}
int confronta_partenza(corsa *a, corsa *b)
{
return strcmp(a->partenza, b->partenza) >= 0;
}
int confronta_arrivo(corsa *a, corsa *b)
{
return strcmp(a->destinazione, b->destinazione) >= 0;
}
int confronta_chiave(corsa *a, corsa *b, corsa_keys chiave)
{
switch (chiave)
{
case k_codice_tratta:
return confronta_codice(a, b);
case k_destinazione:
return confronta_arrivo(a, b);
case k_partenza:
return confronta_partenza(a, b);
case k_data:
return confronta_data_ora(a, b);
}
}
int freeVettori(raccolta * rac) {
for (int i = 0; i < rac->N; i++)
{
free(rac->corse_codice[i]);
}
free(rac->corse_data);
free(rac->corse_partenza);
free(rac->corse_arrivo);
free(rac->corse_codice);
free(rac->temp);
}
int loadFile(raccolta * rac, char *filename, int callFree)
{
FILE *fp_read;
unsigned int i;
if ((fp_read = fopen(filename, "r")) == NULL)
{
puts("Impossibile aprire il file");
return 1;
}
if (callFree) {
// chiamo free solo dopo aver controllato che il file esista
// se il file non esiste rimangono caricati i dati precedenti
freeVettori(rac);
}
fscanf(fp_read, "%u\n", &(rac->N));
rac->corse_data = malloc(rac->N * sizeof(corsa *));
rac->corse_partenza = malloc(rac->N * sizeof(corsa *));
rac->corse_arrivo = malloc(rac->N * sizeof(corsa *));
rac->corse_codice = malloc(rac->N * sizeof(corsa *));
rac->temp = malloc(rac->N * sizeof(corsa *));
for (i = 0; i < rac->N; i++)
{
corsa * nuova = malloc(sizeof(corsa));
int num_read = fscanf(fp_read, "%30s %30s %30s %4u/%2u/%2u %2u:%2u:%2u %2u:%2u:%2u %u\n", nuova->codice_tratta, nuova->partenza, nuova->destinazione, &(nuova->data.year), &(nuova->data.month), &(nuova->data.day), &(nuova->ora_partenza.hours), &(nuova->ora_partenza.minutes), &(nuova->ora_partenza.seconds), &(nuova->ora_arrivo.hours), &(nuova->ora_arrivo.minutes), &(nuova->ora_arrivo.seconds), &(nuova->ritardo));
if (num_read != 13)
{
// la stringa è mal formattata
printf("File non formattato correttamente. Errore a linea %d\n", i + 1);
fclose(fp_read);
return 1;
}
rac->corse_data[i] = nuova;
rac->corse_partenza[i] = nuova;
rac->corse_arrivo[i] = nuova;
rac->corse_codice[i] = nuova;
}
fclose(fp_read);
return 0;
}
int min(int x, int y)
{
return (x < y) ? x : y;
}
void merge(corsa **A, corsa ** temp, int low, int mid, int high, corsa_keys chiave)
{
int i, j, k;
// Merge the temp arrays
i = low;
j = mid+1;
k = 0;
while (i <= mid && j <= high)
{
if (!confronta_chiave(A[i], A[j], chiave))
{
temp[k] = A[i];
i++;
}
else
{
temp[k] = A[j];
j++;
}
k++;
}
// Copy the remaining elements of L[]
while (i <= mid)
{
temp[k] = A[i];
i++;
k++;
}
// Copy the remaining elements of R[]
while (j <= high)
{
temp[k] = A[j];
j++;
k++;
}
for (i = 0; i <= high - low; i++) {
A[i+low] = temp[i];
}
}
void mergesort_by_key(corsa **A, corsa ** temp, int low, int high, corsa_keys key)
{
if (low >= high)
return;
// Finding mid element
int mid = low + (high - low) / 2;
// Recursively sorting both the halves
mergesort_by_key(A, temp, low, mid, key);
mergesort_by_key(A, temp, mid + 1, high, key);
// Merge the array
merge(A, temp, low, mid, high, key);
}
void stampa_corsa(corsa corsa)
{
printf(" - %s %s %s, data: %4u/%02u/%02u, ora di partenza: %02u:%02u:%02u, ora di arrivo: %02u:%02u:%02u, ritardo %d minuto\n",
corsa.codice_tratta, corsa.partenza, corsa.destinazione,
corsa.data.year, corsa.data.month, corsa.data.day,
corsa.ora_partenza.hours, corsa.ora_partenza.minutes, corsa.ora_partenza.seconds,
corsa.ora_arrivo.hours, corsa.ora_arrivo.minutes, corsa.ora_arrivo.seconds,
corsa.ritardo);
}
void stampa_corse_vettore(corsa **corse, int N)
{
for (int i = 0; i < N; i++)
{
stampa_corsa(*(corse[i]));
}
}
void stampa_corse_scelta(char *argomenti, raccolta * rac)
{
argomenti++; // salta lo spazio
switch (interpreta_tratta(argomenti))
{
case k_codice_tratta:
puts("Corse ordinate per codice:");
stampa_corse_vettore(rac->corse_codice, rac->N);
break;
case k_data:
puts("Corse ordinate per data:");
stampa_corse_vettore(rac->corse_data, rac->N);
break;
case k_destinazione:
puts("Corse ordinate per destinazione:");
stampa_corse_vettore(rac->corse_arrivo, rac->N);
break;
case k_partenza:
puts("Corse ordinate per partenza:");
stampa_corse_vettore(rac->corse_partenza, rac->N);
break;
default:
puts("Errore. La sintassi è 'stampa [codice/partenza/destinazione/data]'");
break;
}
}
void ordina_data(char *argomenti, raccolta * rac)
{
puts("Ordino le corse per data\n");
mergesort_by_key(rac->corse_data, rac->temp, 0, rac->N - 1, k_data);
}
void ordina_codice(char *argomenti, raccolta * rac)
{
puts("Ordino le corse per codice tratta\n");
mergesort_by_key(rac->corse_codice, rac->temp, 0, rac->N - 1, k_codice_tratta);
}
void ordina_partenza(char *argomenti, raccolta * rac)
{
puts("Ordino le corse per partenza\n");
mergesort_by_key(rac->corse_partenza, rac->temp, 0, rac->N - 1, k_partenza);
}
void ordina_arrivo(char *argomenti, raccolta * rac)
{
puts("Ordino le corse per destinazione\n");
mergesort_by_key(rac->corse_arrivo, rac->temp, 0, rac->N - 1, k_destinazione);
}
void ricerca_dicotomica(corsa **corse, char *partenza, int partenza_len, int N)
{
int s = 0, e = N - 1, i = (e + s) / 2, res = strncmp(partenza, corse[i]->partenza, partenza_len);
while (res != 0)
{
if (e-s <= 0) { //nothing found
puts("Nessun risultato");
return;
}
if (res > 0)
{
s = i+1;
}
else
{
e = i-1;
}
i = (e + s) / 2;
res = strncmp(partenza, corse[i]->partenza, partenza_len);
}
s = i;
e = i;
while (s > 0 && !strncmp(partenza, corse[s - 1]->partenza, partenza_len))
s--;
while (e < (N - 1) && !strncmp(partenza, corse[e + 1]->partenza, partenza_len))
e++;
for (i = s; i <= e; i++)
{
stampa_corsa(*(corse[i]));
}
}
void ricerca_lineare(corsa **corse, char *partenza, int partenza_len, int N)
{
for (int i = 0; i < N; i++) {
if (!strncmp(partenza, corse[i]->partenza, partenza_len))
stampa_corsa(*(corse[i]));
}
}
void ricerca_partenza(char *argomenti, raccolta * rac)
{
char partenza[30], tipo[30], partenza_len;
if (sscanf(argomenti, " %30s %30s", tipo, partenza) != 2)
{
puts("Partenza non valida. La sintassi è 'partenza [dicotomica/lineare] <partenza>'");
return;
}
partenza_len = strlen(partenza);
puts("Risultati della ricerca per stazione di partenza:");
if (!strcmp(tipo, "dicotomica"))
{
ricerca_dicotomica(rac->corse_partenza, partenza, partenza_len, rac->N);
}
else
{
ricerca_lineare(rac->corse_partenza, partenza, partenza_len, rac->N);
}
}
void carica_file(char *argomenti, raccolta * rac)
{
char filename[30], partenza_len;
if (sscanf(argomenti, " %30s", filename) != 1)
{
puts("Sintassi non valida. La sintassi è 'carica <nome file>'");
return;
}
puts("Carico il nuovo file...");
loadFile(rac, filename, true);
}
void menuParola(raccolta * rac)
{
t_comandi comando;
char argomenti[MAXL];
int i, continua = 1;
while (continua)
{
comando = leggiComando();
fgets(argomenti, MAXL, stdin); /* resto della riga */
switch (comando)
{
case r_stampa:
stampa_corse_scelta(argomenti, rac);
break;
case r_ordina_data:
ordina_data(argomenti, rac);
break;
case r_ordina_codice:
ordina_codice(argomenti, rac);
break;
case r_ordina_destinazione:
ordina_arrivo(argomenti, rac);
break;
case r_ordina_partenza:
ordina_partenza(argomenti, rac);
break;
case r_ricerca_partenza:
ricerca_partenza(argomenti, rac);
break;
case r_carica:
carica_file(argomenti, rac);
break;
case r_fine:
continua = 0;
break;
default:
puts("Comando non valido\n");
}
}
}
int main()
{
raccolta rac;
if (loadFile(&rac, "./corse.txt", false))
{
return 1;
}
menuParola(&rac);
freeVettori(&rac);
return 0;
}

View File

@@ -0,0 +1,56 @@
// Laboratorio 3 - Esercizio 1
// Matteo Schiff - s295565
#include <stdio.h>
#include <stdlib.h>
int majority(int * a, int N) {
if (N == 1) {
return a[0];
}
int m = N/2;
int x = majority(a, m);
int y = majority(a+m, m);
if (x == y)
return x;
if (x != -1) {
int c = 0;
for (int i = 0; i < N; i++) {
if (a[i] == x)
c++;
}
if (c > (N/2))
return x;
}
if (y != -1) {
int c = 0;
for (int i = 0; i < N; i++) {
if (a[i] == y)
c++;
}
if (c > (N/2))
return y;
}
return -1;
}
int main(int argc, char ** argv) {
int N = argc - 1;
if (argc < 2)
return 1;
int * vec = malloc(N * sizeof(int));
for (int i = 0; i < N; i++) {
vec[i] = atoi(argv[i+1]);
}
printf("major: %d\n", majority(vec, N));
}

View File

@@ -0,0 +1,26 @@
5
5
DivideAndConquer
MementoMori
LegacyOfHate_Pt.III
GhostLoveScore
TheHowling
3
BirdSetFree
ThePrayer
SomeoneLikeYou
4
Yellow
Wonderwall
MessageInABottle
FreeBird
5
GliAngeli
HoMessoVia
GliAnni
ReginaDiCuori
Pescatore
3
ISeeFire
ChasingCars
HowToSaveALife

View File

@@ -0,0 +1,87 @@
// Laboratorio 3 - Esercizio 2
// Matteo Schiff - s295565
#include <stdio.h>
#include <stdlib.h>
#define MAX_LEN 255
typedef struct Lista
{
unsigned int N;
char *canzoni;
} lista;
lista *leggi_brani(int *N, int **playlist)
{
FILE *fp_read;
if ((fp_read = fopen("brani.txt", "r")) == NULL)
{
puts("Impossibile aprire il file");
return NULL;
}
fscanf(fp_read, "%u \n", N);
lista *raccolta = malloc(*N * sizeof(lista));
*playlist = malloc(*N * sizeof(int));
for (int i = 0; i < *N; i++)
{
fscanf(fp_read, "%u \n", &(raccolta[i].N));
raccolta[i].canzoni = malloc(raccolta[i].N * MAX_LEN * sizeof(char));
for (int j = 0; j < raccolta[i].N; j++)
{
fscanf(fp_read, "%s ", raccolta[i].canzoni + j * MAX_LEN);
}
}
fclose(fp_read);
return raccolta;
}
void free_brani(lista *mat, int N, int *playlist)
{
for (int i = 0; i < N; i++)
{
free(mat[i].canzoni);
}
free(mat);
free(playlist);
}
void stampa_playlist(lista *mat, int *playlist, int N, int depth)
{
if (N == depth)
{
puts("\nPlaylist:");
for (int i = 0; i < N; i++)
{
printf(" - %s\n", (mat[i].canzoni + playlist[i] * MAX_LEN));
}
return;
}
for (int i = 0; i < mat[depth].N; i++)
{
playlist[depth] = i;
stampa_playlist(mat, playlist, N, depth + 1);
}
}
int main(int argc, char **argv)
{
int N;
int *playlist;
lista *mat = leggi_brani(&N, &playlist);
if (mat == NULL)
{
return 1;
}
stampa_playlist(mat, playlist, N, 0);
free_brani(mat, N, playlist);
return 0;
}

View File

@@ -0,0 +1,5 @@
4 4
0 1
0 2
1 2
1 3

View File

@@ -0,0 +1,77 @@
// Laboratorio 4 - Esercizio 1
// Matteo Schiff - s295565
#include <stdio.h>
#include <stdlib.h>
#define FILENAME "grafo.txt"
int checkVertexCover(int *soluzione, int N, int **archi, int E) {
for (int i = 0; i < E; i++) {
if (soluzione[archi[i][0]] == 0 && soluzione[archi[i][1]] == 0)
return 0;
}
return 1;
}
void vertexCoverR(int pos, int **archi, int E, int *soluzione, int N) {
if (pos >= N) {
if (checkVertexCover(soluzione, N, archi, E)) {
printf("(");
for (int i = 0; i < N; i++) {
if (soluzione[i] == 1) {
printf("%d,", i);
}
}
printf("\b)\n");
}
return;
}
soluzione[pos] = 0;
vertexCoverR(pos+1, archi, E, soluzione, N);
soluzione[pos] = 1;
vertexCoverR(pos+1, archi, E, soluzione, N);
}
void vertexCovers(int **archi, int N, int E) {
int *soluzione = (int *) malloc(N * sizeof(int));
vertexCoverR(0, archi, E, soluzione, N);
free(soluzione);
}
void leggiGrafo(int ***archi, int *N, int *E) {
FILE *fp;
if ((fp = fopen(FILENAME, "r")) == NULL) {
printf("Impossibile aprire il file di input %s", FILENAME);
exit(1);
}
fscanf(fp, "%d %d", N, E);
*archi = (int **) malloc(*E * sizeof(int *));
if (*archi == NULL) {
printf("Impossibile allocare memoria");
exit(2);
}
for (int i = 0; i < *E; i++) {
(*archi)[i] = (int *) malloc(2 * sizeof(int));
if ((*archi)[i] == NULL) {
printf("Impossibile allocare memoria");
exit(2);
}
fscanf(fp, "%d %d", &(*archi)[i][0], &(*archi)[i][1]);
}
fclose(fp);
}
int main(int argc, char ** argv)
{
int **archi, N, E;
leggiGrafo(&archi, &N, &E);
vertexCovers(archi, N, E);
free(archi);
return 0;
}

View File

@@ -0,0 +1,3 @@
A0001 Mario Rossi 01/02/1990 ViaMarcoPolo Torino 10129
A0002 Lucia Verdi 07/11/1989 ViaTorino Milano 20123
A0003 Antonio Neri 19/04/1999 GalleriaTermini Roma 00185

View File

@@ -0,0 +1,2 @@
A0004 Anna Gialli 04/09/1995 FratelliAlinari Firenze 50123
A0005 Marco Bianchi 03/07/1993 PiazzaMazzini Napoli 80135

View File

@@ -0,0 +1,192 @@
// Laboratorio 4 - Esercizio 2 - item.c
// Matteo Schiff - s295565
#ifndef ITEM_C_DEFINED
#define ITEM_C_DEFINED
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include "item.h"
int DateGreater(Date a, Date b) {
if (a.year > b.year)
return true;
else if (a.year < b.year)
return false;
if (a.month > b.month)
return true;
else if (a.month < b.month)
return false;
if (a.day >= b.day)
return true;
return false;
}
Link newNode(Item val, Link next) {
Link t = (Link) malloc(sizeof(Node));
if (t == NULL) {
printf("Impossibile allocare memoria");
exit(2);
}
t->val = val;
t->next = next;
return t;
}
void freeNode(Link node) {
free(node->val);
free(node);
}
Item ItemFromString(char *str) {
Item item;
if ((item = (Item) malloc(sizeof(struct item_s))) == NULL) {
printf("Impossibile allocare memoria");
exit(2);
}
if (sscanf(str, " %5s %50s %50s %d/%d/%d %50s %50s %d",
item->code,
item->name,
item->surname,
&item->date.day,
&item->date.month,
&item->date.year,
item->address,
item->city,
&item->cap
) != 9) {
free(item);
return NULL;
}
return item;
}
Item ItemRead(FILE * fp) {
Item item;
if ((item = (Item) malloc(sizeof(struct item_s))) == NULL) {
printf("Impossibile allocare memoria");
exit(2);
}
if (fscanf(fp, " %5s %50s %50s %d/%d/%d %50s %50s %d",
item->code,
item->name,
item->surname,
&item->date.day,
&item->date.month,
&item->date.year,
item->address,
item->city,
&item->cap
) != 9) {
free(item);
return NULL;
}
return item;
}
Key ItemKey(Item val) {
return val->code;
}
int ItemEq(Key x, Key y) {
return strcmp(x, y) == 0;
}
void ItemPrint(FILE *fp, Item x) {
fprintf(fp, "%s %s %s %02d/%02d/%04d %s %s %05d\n",
x->code,
x->name,
x->surname,
x->date.day,
x->date.month,
x->date.year,
x->address,
x->city,
x->cap
);
}
Link insertOrderedByDate(Item val, Link head) {
Link x, p;
if (head == NULL || DateGreater(val->date, head->val->date))
return newNode(val, head);
for (p = head, x = head->next; x != NULL && DateGreater(x->val->date, val->date); p = x, x = x->next);
p->next = newNode(val, x);
return head;
}
Item getItemByCode(Link head, Key key) {
for (Link t = head; t != NULL; t = t->next) {
if (ItemEq(ItemKey(t->val), key))
return t->val;
}
return NULL;
}
void printList(FILE *fp, Link head) {
for (Link t = head; t != NULL; t = t->next) {
ItemPrint(fp, t->val);
}
}
Item extractCode(Link *headp, Key key) {
Link *t, r;
Item element = NULL;
for (t = headp; *t != NULL; t = &((*t)->next)) {
if (ItemEq(ItemKey((*t)->val), key)) {
element = (*t)->val;
// Salvo `r` per poi chiamare free
r = *t;
// rimuovo il nodo dalla lista
*t = (*t)->next;
// Faccio free solo del nodo (non dell'item)
free(r);
break;
}
}
return element;
}
Item extractDates(Link *headp, Date first, Date last) {
Link *t, r;
Item element = NULL;
for (t = headp; *t != NULL; t = &((*t)->next)) {
if (DateGreater((*t)->val->date, first) && DateGreater(last, (*t)->val->date)) {
element = (*t)->val;
r = *t;
*t = (*t)->next;
free(r);
break;
}
}
return element;
}
void freeList(Link head) {
Link p, x;
for (p = head, x = head->next; x != NULL; p = x, x = x->next){
freeNode(p);
}
}
#endif

View File

@@ -0,0 +1,55 @@
// Laboratorio 4 - Esercizio 2 - item.h
// Matteo Schiff - s295565
#ifndef ITEM_H_DEFINED
#define ITEM_H_DEFINED
#define CODE_LEN 5
#define STR_LEN 50
typedef struct date_s {
int day;
int month;
int year;
} Date;
typedef struct item_s {
char code[CODE_LEN+1];
char name[STR_LEN+1];
char surname[STR_LEN+1];
Date date;
char address[STR_LEN+1];
char city[STR_LEN+1];
int cap;
} *Item;
typedef struct node_s *Link;
typedef struct node_s {
Item val;
Link next;
} Node;
typedef char* Key;
// Date
int DateGreater(Date a, Date b);
// Item
Item ItemFromString(char *str);
Item ItemRead(FILE * fp);
Key ItemKey(Item item);
int ItemEq(Key x, Key y);
void ItemPrint(FILE *fp, Item x);
// List
Link insertOrderedByDate(Item val, Link head);
Item getItemByCode(Link head, Key key);
void printList(FILE *fp, Link head);
Item extractCode(Link *headp, Key key);
Item extractDates(Link *headp, Date first, Date last);
void freeList(Link head);
#endif

View File

@@ -0,0 +1,220 @@
// Laboratorio 4 - Esercizio 2 - main.c
// Matteo Schiff - s295565
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stdlib.h>
#include <ctype.h>
#include "item.h"
#define MAX_LEN 30
const int MAXL = 100;
typedef enum
{
k_codice_tratta,
k_partenza,
k_destinazione,
k_data
} corsa_keys;
typedef enum
{
r_leggi_file,
r_leggi_tastiera,
r_ricerca_codice,
r_cancella_codice,
r_cancella_date,
r_stampa,
r_fine
} t_comandi;
// Trasforma in lowercase tutti i caratteri di una stringa
char *toLower(char *s)
{
for (char *p = s; *p; p++)
*p = tolower(*p);
return s;
}
t_comandi leggiComando()
{
t_comandi c;
char cmd[MAXL];
char tabella[7][20] = {
"leggi_file", "leggi_tastiera", "ricerca_codice", "cancella_codice", "cancella_date", "stampa", "fine"};
printf("comando (leggi_file/leggi_tastiera/ricerca_codice");
printf("/cancella_codice/cancella_date/stampa/fine): ");
scanf("%s", cmd);
toLower(cmd);
c = r_leggi_file;
while (c < 8 && strcmp(cmd, tabella[c]) != 0)
c++;
return (c);
}
void carica_file(char *argomenti, Link * head)
{
char filename[MAX_LEN+1];
FILE *fp_read;
if (sscanf(argomenti, " %30s", filename) != 1)
{
puts("Sintassi non valida. La sintassi è 'carica <nome file>'");
return;
}
puts("Carico il nuovo file...");
if ((fp_read = fopen(filename, "r")) == NULL)
{
puts("Impossibile aprire il file");
return;
}
while(!feof(fp_read)) {
Item nuovo = ItemRead(fp_read);
// skip invalid entries
if (nuovo != NULL)
*head = insertOrderedByDate(nuovo, *head);
}
fclose(fp_read);
}
void carica_tastiera(char *argomenti, Link * head)
{
Item new = ItemFromString(argomenti);
if (new == NULL) {
puts("Anagrafica non valida");
return;
}
*head = insertOrderedByDate(new, *head);
}
void ricerca_codice(char *argomenti, Link * head)
{
char codice[CODE_LEN+1];
if (sscanf(argomenti, " %5s", codice) != 1)
{
puts("Sintassi non valida. La sintassi è 'ricerca_codice <codice>'");
return;
}
Item found = getItemByCode(*head, codice);
if (found == NULL) {
puts("Non è stato trovato nessun elemento");
return;
}
ItemPrint(stdout, found);
}
void cancella_codice(char *argomenti, Link * head)
{
char codice[CODE_LEN+1];
if (sscanf(argomenti, " %5s", codice) != 1)
{
puts("Sintassi non valida. La sintassi è 'cancella_codice <codice>'");
return;
}
Item found = extractCode(head, codice);
if (found == NULL) {
puts("Non è stato trovato nessun elemento");
return;
}
ItemPrint(stdout, found);
free(found);
}
void cancella_date(char *argomenti, Link * head)
{
Date start, end;
if (sscanf(argomenti, " %d/%d/%d %d/%d/%d", &(start.day), &(start.month), &(start.year), &(end.day), &(end.month), &(end.year)) != 6)
{
puts("Sintassi non valida. La sintassi è 'cancella_date <data inizio> <data fine>'");
return;
}
Item found;
while (found = extractDates(head, start, end), found != NULL) {
ItemPrint(stdout, found);
free(found);
}
}
void stampa_file(char *argomenti, Link * head)
{
FILE *fp_write;
char filename[MAX_LEN+1];
if (sscanf(argomenti, " %30s", filename) != 1)
{
puts("Sintassi non valida. La sintassi è 'stampa <nome file>'");
return;
}
if ((fp_write = fopen(filename, "w")) == NULL)
{
puts("Impossibile aprire il file");
return;
}
printList(fp_write, *head);
fclose(fp_write);
}
void menuParola(Link * head)
{
t_comandi comando;
char argomenti[MAXL];
int i, continua = 1;
while (continua)
{
comando = leggiComando();
fgets(argomenti, MAXL, stdin); /* resto della riga */
switch (comando)
{
case r_leggi_file:
carica_file(argomenti, head);
break;
case r_leggi_tastiera:
carica_tastiera(argomenti, head);
break;
case r_ricerca_codice:
ricerca_codice(argomenti, head);
break;
case r_cancella_codice:
cancella_codice(argomenti, head);
break;
case r_cancella_date:
cancella_date(argomenti, head);
break;
case r_stampa:
stampa_file(argomenti, head);
break;
case r_fine:
continua = 0;
break;
default:
puts("Comando non valido\n");
}
}
}
int main()
{
Link head = NULL;
menuParola(&head);
freeList(head);
return 0;
}

View File

@@ -0,0 +1,2 @@
A0004 Anna Gialli 04/09/1995 FratelliAlinari Firenze 50123
A0002 Lucia Verdi 07/11/1989 ViaTorino Milano 20123

View File

@@ -0,0 +1,17 @@
15
5 7 4 10
6 8 10 1
3 1 6 10
4 4 2 1
7 2 4 10
8 8 4 6
6 1 4 4
8 3 6 4
7 7 4 2
1 3 7 1
10 10 9 10
8 8 8 6
9 6 10 5
6 10 9 5
9 6 9 9

View File

@@ -0,0 +1,45 @@
TEST #1
zaffiro = 5, rubino = 7, topazio = 4, smeraldo = 10, TOT = 26
Collana massima di lunghezza 24
TEST #2
zaffiro = 6, rubino = 8, topazio = 10, smeraldo = 1, TOT = 25
Collana massima di lunghezza 24
TEST #3
zaffiro = 3, rubino = 1, topazio = 6, smeraldo = 10, TOT = 20
Collana massima di lunghezza 16
TEST #4
zaffiro = 4, rubino = 4, topazio = 2, smeraldo = 1, TOT = 11
Collana massima di lunghezza 10
TEST #5
zaffiro = 7, rubino = 2, topazio = 4, smeraldo = 10, TOT = 23
Collana massima di lunghezza 22
TEST #6
zaffiro = 8, rubino = 8, topazio = 4, smeraldo = 6, TOT = 26
Collana massima di lunghezza 23
TEST #7
zaffiro = 6, rubino = 1, topazio = 4, smeraldo = 4, TOT = 15
Collana massima di lunghezza 13
TEST #8
zaffiro = 8, rubino = 3, topazio = 6, smeraldo = 4, TOT = 21
Collana massima di lunghezza 19
TEST #9
zaffiro = 7, rubino = 7, topazio = 4, smeraldo = 2, TOT = 20
Collana massima di lunghezza 18
TEST #10
zaffiro = 1, rubino = 3, topazio = 7, smeraldo = 1, TOT = 12
Collana massima di lunghezza 9
TEST #11
zaffiro = 10, rubino = 10, topazio = 9, smeraldo = 10, TOT = 39
Collana massima di lunghezza 39
TEST #12
zaffiro = 8, rubino = 8, topazio = 8, smeraldo = 6, TOT = 30
Collana massima di lunghezza 30
TEST #13
zaffiro = 9, rubino = 6, topazio = 10, smeraldo = 5, TOT = 30
Collana massima di lunghezza 27
TEST #14
zaffiro = 6, rubino = 10, topazio = 9, smeraldo = 5, TOT = 30
Collana massima di lunghezza 30
TEST #15
zaffiro = 9, rubino = 6, topazio = 9, smeraldo = 9, TOT = 33
Collana massima di lunghezza 31

View File

@@ -0,0 +1,16 @@
15
19 6 8 5
19 14 5 11
14 14 5 8
12 16 5 14
12 17 20 20
13 11 14 18
7 14 12 10
13 20 12 17
17 18 6 9
5 5 15 19
18 12 20 17
13 6 19 6
17 20 15 19
12 18 17 8
7 20 12 7

View File

@@ -0,0 +1,45 @@
TEST #1
zaffiro = 19, rubino = 6, topazio = 8, smeraldo = 5, TOT = 38
Collana massima di lunghezza 37
TEST #2
zaffiro = 19, rubino = 14, topazio = 5, smeraldo = 11, TOT = 49
Collana massima di lunghezza 41
TEST #3
zaffiro = 14, rubino = 14, topazio = 5, smeraldo = 8, TOT = 41
Collana massima di lunghezza 33
TEST #4
zaffiro = 12, rubino = 16, topazio = 5, smeraldo = 14, TOT = 47
Collana massima di lunghezza 37
TEST #5
zaffiro = 12, rubino = 17, topazio = 20, smeraldo = 20, TOT = 69
Collana massima di lunghezza 67
TEST #6
zaffiro = 13, rubino = 11, topazio = 14, smeraldo = 18, TOT = 56
Collana massima di lunghezza 54
TEST #7
zaffiro = 7, rubino = 14, topazio = 12, smeraldo = 10, TOT = 43
Collana massima di lunghezza 42
TEST #8
zaffiro = 13, rubino = 20, topazio = 12, smeraldo = 17, TOT = 62
Collana massima di lunghezza 55
TEST #9
zaffiro = 17, rubino = 18, topazio = 6, smeraldo = 9, TOT = 50
Collana massima di lunghezza 39
TEST #10
zaffiro = 5, rubino = 5, topazio = 15, smeraldo = 19, TOT = 44
Collana massima di lunghezza 35
TEST #11
zaffiro = 18, rubino = 12, topazio = 20, smeraldo = 17, TOT = 67
Collana massima di lunghezza 60
TEST #12
zaffiro = 13, rubino = 6, topazio = 19, smeraldo = 6, TOT = 44
Collana massima di lunghezza 32
TEST #13
zaffiro = 17, rubino = 20, topazio = 15, smeraldo = 19, TOT = 71
Collana massima di lunghezza 67
TEST #14
zaffiro = 12, rubino = 18, topazio = 17, smeraldo = 8, TOT = 55
Collana massima di lunghezza 55
TEST #15
zaffiro = 7, rubino = 20, topazio = 12, smeraldo = 7, TOT = 46
Collana massima di lunghezza 39

View File

@@ -0,0 +1,107 @@
// Laboratorio 4 - Esercizio 3 - main.c
// Matteo Schiff - s295565
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
enum Pietra{zaffiro, rubino, topazio, smeraldo};
// Esploro il set di collane valide in modo ordinato, quando arrivo alla fine della collana ne controllo
// la lunghezza e aggiorno se necessario la soluzione
void esploraSoluzioni(int z, int r, int t, int s, int len, int * tmp, int * max, int * sol) {
int added = false;
if (z > 0 && (len == 0 || (tmp[len - 1] == zaffiro || tmp[len - 1] == topazio))) {
tmp[len] = zaffiro;
esploraSoluzioni(z-1,r,t,s,len +1,tmp,max,sol);
added = true;
}
if (s > 0 && (len == 0 || (tmp[len - 1] == smeraldo || tmp[len - 1] == rubino))) {
tmp[len] = smeraldo;
esploraSoluzioni(z,r,t,s-1,len +1,tmp,max,sol);
added = true;
}
if (r > 0 && (len == 0 || (tmp[len - 1] == zaffiro || tmp[len - 1] == topazio))) {
tmp[len] = rubino;
esploraSoluzioni(z,r-1,t,s,len +1,tmp,max,sol);
added = true;
}
if (t > 0 && (len == 0 || (tmp[len - 1] == smeraldo || tmp[len - 1] == rubino))) {
tmp[len] = topazio;
esploraSoluzioni(z,r,t-1,s,len +1,tmp,max,sol);
added = true;
}
// se non è possibile più aggiungere pietre, ho raggiunto la lunghezza massima ottenibile dal ramo
if (!added) {
if (len > *max) {
*max = len;
for (int i = 0; i < len; i++) {
sol[i] = tmp[i];
}
}
}
}
void solveCase(int z, int r, int t, int s) {
int maxL = z+r+t+s;
int max = 0;
// vettore su cui la funzione costruisce le collane
int * tmp = malloc(maxL * sizeof(int));
// vettore utilizzato per memorizzare la soluzione
int * sol = malloc(maxL * sizeof(int));
printf("zaffiri = %d, rubini = %d, topazi = %d, smeraldi = %d; numero pietre = %d\n", z,r,t,s,maxL);
esploraSoluzioni(z,r,t,s,0,tmp,&max,sol);
printf("Collana massima di lunghezza %d\n", max);
for(int i = 0; i < max; i++) {
switch (sol[i])
{
case zaffiro:
printf("z ");
break;
case rubino:
printf("r ");
break;
case smeraldo:
printf("s ");
break;
case topazio:
printf("t ");
break;
default:
break;
}
}
putc('\n', stdout);
fflush(stdout);
free(tmp);
free(sol);
}
int main() {
int z, r, t, s, N = 0;
FILE *fp;
if ((fp = fopen("easy_test_set.txt", "r")) == NULL)
{
puts("Impossibile aprire il file");
return 1;
}
fscanf(fp, "%d", &N);
for (int i = 0; i < N; i++) {
fscanf(fp, " %d %d %d %d", &z, &r, &t, &s);
printf("Test case %d\n", i+1);
solveCase(z,r,t,s);
}
fclose(fp);
}

View File

@@ -0,0 +1,7 @@
6
2 1 2 2
3 2 3 3
6 2 2 3
6 4 4 3
4 3 7 4
6 5 9 7

View File

@@ -0,0 +1,3 @@
1
2 1 2 2

View File

@@ -0,0 +1,122 @@
// Laboratorio 4 - Esercizio 4 - item.c
// Matteo Schiff - s295565
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
enum Pietra{zaffiro, rubino, topazio, smeraldo};
// Ho messo queste variabili globali per diminuire il numero di parametri
// di `esploraSoluzioni` per migliorarne la leggibilità
// Questi numeri sono costanti per ogni set
int vz, vr, vt, vs, max_rip;
void esploraSoluzioni(int z, int r, int t, int s, int nz, int ns, int cur_rip, int len, int val, int * tmp, int * max, int*maxlen, int * sol) {
int added = false;
if (z > 0 && (nz +1) <= ns) {
tmp[len] = zaffiro;
if (len == 0 || tmp[len - 1] == topazio) {
esploraSoluzioni(z-1,r,t,s,nz+1,ns,1,len +1,val+vz,tmp,max,maxlen,sol);
added = true;
}
if (len != 0 && tmp[len - 1] == zaffiro && cur_rip < max_rip) {
esploraSoluzioni(z-1,r,t,s,nz+1,ns,cur_rip+1,len +1,val+vz,tmp,max,maxlen,sol);
added = true;
}
}
if (s > 0) {
tmp[len] = smeraldo;
if (len == 0 || tmp[len - 1] == rubino) {
esploraSoluzioni(z,r,t,s-1,nz,ns+1,1,len +1,val+vs,tmp,max,maxlen,sol);
added = true;
}
if (len != 0 && tmp[len - 1] == smeraldo && cur_rip < max_rip) {
esploraSoluzioni(z,r,t,s-1,nz,ns+1,cur_rip+1,len +1,val+vs,tmp,max,maxlen,sol);
added = true;
}
}
if (r > 0 && (len == 0 || (tmp[len - 1] == zaffiro || tmp[len - 1] == topazio))) {
tmp[len] = rubino;
esploraSoluzioni(z,r-1,t,s,nz,ns,1,len +1,val+vr,tmp,max,maxlen,sol);
added = true;
}
if (t > 0 && (len == 0 || (tmp[len - 1] == smeraldo || tmp[len - 1] == rubino))) {
tmp[len] = topazio;
esploraSoluzioni(z,r,t-1,s,nz,ns,1,len +1,val+vt,tmp,max,maxlen,sol);
added = true;
}
// se non è possibile più aggiungere pietre, ho raggiunto la lunghezza massima ottenibile dal ramo
if (!added) {
if (val >= *max) {
*max = val;
*maxlen = len;
for (int i = 0; i < len; i++) {
sol[i] = tmp[i];
}
}
}
}
void solveCase(int z, int r, int t, int s) {
int maxL = z+r+t+s;
int max = 0;
int maxlen = 0;
int * tmp = malloc(maxL * sizeof(int));
int * sol = malloc(maxL * sizeof(int));
printf("zaffiri = %d (valore: %d), rubini = %d (valore: %d), topazi = %d (valore: %d), smeraldi = %d (valore: %d); numero pietre = %d {max_rip = %d}\n", z, vz,r,vr,t,vt,s,vs,maxL, max_rip);
esploraSoluzioni(z,r,t,s,0,0,0,0,0,tmp,&max,&maxlen,sol);
printf("Collana con valore massimo %d, lunghezza %d\n", max, maxlen);
for(int i = 0; i < maxlen; i++) {
switch (sol[i])
{
case zaffiro:
printf("z ");
break;
case rubino:
printf("r ");
break;
case smeraldo:
printf("s ");
break;
case topazio:
printf("t ");
break;
default:
break;
}
}
putc('\n', stdout);
fflush(stdout);
free(tmp);
free(sol);
}
int main() {
int z, r, t, s, N = 0;
FILE *fp;
if ((fp = fopen("test_set.txt", "r")) == NULL)
{
puts("Impossibile aprire il file");
return 1;
}
fscanf(fp, "%d", &N);
for (int i = 0; i < N; i++) {
fscanf(fp, " %d %d %d %d %d %d %d %d %d", &z, &r, &t, &s, &vz, &vr, &vt, &vs, &max_rip);
printf("Test case %d\n", i+1);
solveCase(z,r,t,s);
}
fclose(fp);
}

View File

@@ -0,0 +1,21 @@
20
8 1 10 5 6 6 20 8 3
6 5 7 2 2 15 2 21 5
10 7 8 10 17 16 18 17 3
7 1 9 2 10 13 16 20 5
6 6 8 10 8 25 20 10 7
5 6 1 5 21 7 13 1 9
9 5 3 8 7 3 10 8 6
7 8 6 8 5 5 12 15 5
4 8 8 6 1 19 13 19 1
9 3 9 9 17 11 3 5 7
1 1 5 10 15 12 14 15 6
2 9 3 5 19 14 6 19 3
4 5 2 7 21 10 16 5 10
5 6 9 6 20 14 3 17 4
9 8 9 2 17 5 21 11 9
7 1 3 6 25 19 3 20 8
6 2 5 4 19 22 3 11 8
9 3 5 3 3 1 2 24 9
5 10 7 9 19 1 6 5 1
4 8 2 10 13 1 8 23 3

View File

@@ -0,0 +1,80 @@
TEST #1
zaffiro = 8 [6], rubino = 1 [6], topazio = 10 [20], smeraldo = 5 [8], TOT = 24 {max_rip = 3}
Soluzione ottima di valore 116 usando 13 gemma/e
Composizione collana: sstzzrssstzzz
TEST #2
zaffiro = 6 [2], rubino = 5 [15], topazio = 7 [2], smeraldo = 2 [21], TOT = 20 {max_rip = 5}
Soluzione ottima di valore 133 usando 15 gemma/e
Composizione collana: trtrtrtrtrsstzz
TEST #3
zaffiro = 10 [17], rubino = 7 [16], topazio = 8 [18], smeraldo = 10 [17], TOT = 35 {max_rip = 3}
Soluzione ottima di valore 596 usando 35 gemma/e
Composizione collana: trtrtrtrstzrssstzzzrssstzzzrssstzzz
TEST #4
zaffiro = 7 [10], rubino = 1 [13], topazio = 9 [16], smeraldo = 2 [20], TOT = 19 {max_rip = 5}
Soluzione ottima di valore 105 usando 7 gemma/e
Composizione collana: trsstzz
TEST #5
zaffiro = 6 [8], rubino = 6 [25], topazio = 8 [20], smeraldo = 10 [10], TOT = 30 {max_rip = 7}
Soluzione ottima di valore 438 usando 29 gemma/e
Composizione collana: trtrtrtrtrssstzzzrssssssstzzz
TEST #6
zaffiro = 5 [21], rubino = 6 [7], topazio = 1 [13], smeraldo = 5 [1], TOT = 17 {max_rip = 9}
Soluzione ottima di valore 137 usando 13 gemma/e
Composizione collana: rssssstzzzzzr
TEST #7
zaffiro = 9 [7], rubino = 5 [3], topazio = 3 [10], smeraldo = 8 [8], TOT = 25 {max_rip = 6}
Soluzione ottima di valore 162 usando 23 gemma/e
Composizione collana: rtrsstzzrsssssstzzzzzzr
TEST #8
zaffiro = 7 [5], rubino = 8 [5], topazio = 6 [12], smeraldo = 8 [15], TOT = 29 {max_rip = 5}
Soluzione ottima di valore 262 usando 28 gemma/e
Composizione collana: rtrtrtrtrsstzzrssssstzzzzzrs
TEST #9
zaffiro = 4 [1], rubino = 8 [19], topazio = 8 [13], smeraldo = 6 [19], TOT = 26 {max_rip = 1}
Soluzione ottima di valore 374 usando 26 gemma/e
Composizione collana: rtrtrstzrstzrstzrstzrstrst
TEST #10
zaffiro = 9 [17], rubino = 3 [11], topazio = 9 [3], smeraldo = 9 [5], TOT = 30 {max_rip = 7}
Soluzione ottima di valore 243 usando 25 gemma/e
Composizione collana: trtrsstzzrssssssstzzzzzzz
TEST #11
zaffiro = 1 [15], rubino = 1 [12], topazio = 5 [14], smeraldo = 10 [15], TOT = 17 {max_rip = 6}
Soluzione ottima di valore 205 usando 14 gemma/e
Composizione collana: sssstzrsssssst
TEST #12
zaffiro = 2 [19], rubino = 9 [14], topazio = 3 [6], smeraldo = 5 [19], TOT = 19 {max_rip = 3}
Soluzione ottima di valore 207 usando 14 gemma/e
Composizione collana: rtrtrsstzzrsss
TEST #13
zaffiro = 4 [21], rubino = 5 [10], topazio = 2 [16], smeraldo = 7 [5], TOT = 18 {max_rip = 10}
Soluzione ottima di valore 181 usando 16 gemma/e
Composizione collana: rtrsssstzzzzrsss
TEST #14
zaffiro = 5 [20], rubino = 6 [14], topazio = 9 [3], smeraldo = 6 [17], TOT = 26 {max_rip = 4}
Soluzione ottima di valore 307 usando 24 gemma/e
Composizione collana: trtrtrtrtrsstzzrsssstzzz
TEST #15
zaffiro = 9 [17], rubino = 8 [5], topazio = 9 [21], smeraldo = 2 [11], TOT = 28 {max_rip = 9}
Soluzione ottima di valore 285 usando 21 gemma/e
Composizione collana: trtrtrtrtrtrtrtrsstzz
TEST #16
zaffiro = 7 [25], rubino = 1 [19], topazio = 3 [3], smeraldo = 6 [20], TOT = 17 {max_rip = 8}
Soluzione ottima di valore 295 usando 15 gemma/e
Composizione collana: trsssssstzzzzzz
TEST #17
zaffiro = 6 [19], rubino = 2 [22], topazio = 5 [3], smeraldo = 4 [11], TOT = 17 {max_rip = 8}
Soluzione ottima di valore 173 usando 13 gemma/e
Composizione collana: trtrsssstzzzz
TEST #18
zaffiro = 9 [3], rubino = 3 [1], topazio = 5 [2], smeraldo = 3 [24], TOT = 20 {max_rip = 9}
Soluzione ottima di valore 92 usando 13 gemma/e
Composizione collana: trtrtrssstzzz
TEST #19
zaffiro = 5 [19], rubino = 10 [1], topazio = 7 [6], smeraldo = 9 [5], TOT = 31 {max_rip = 1}
Soluzione ottima di valore 185 usando 28 gemma/e
Composizione collana: rstzrstzrstzrstzrstzrstrstrs
TEST #20
zaffiro = 4 [13], rubino = 8 [1], topazio = 2 [8], smeraldo = 10 [23], TOT = 24 {max_rip = 3}
Soluzione ottima di valore 278 usando 18 gemma/e
Composizione collana: rssstzzzrssstzrsss

View File

@@ -0,0 +1,7 @@
6
1 2
2 4
2 5
3 5
5 7
6 8

View File

@@ -0,0 +1,9 @@
8
0 6
1 4
3 5
3 8
4 7
5 9
6 10
8 11

View File

@@ -0,0 +1,103 @@
// Laboratorio 5 - Esercizio 1
// Matteo Schiff - s295565
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int start, end;
} att;
void readFile(att **val, int *N, char *filename) {
FILE *fp;
if ((fp = fopen(filename, "r")) == NULL) {
printf("Impossibile aprire il file di input %s", filename);
exit(1);
}
fscanf(fp, "%d", N);
*val = (att *) malloc(*N * sizeof(att));
for (int i = 0; i < *N; i++) {
fscanf(fp, "%d %d", &(*val)[i].start, &(*val)[i].end);
}
fclose(fp);
}
int controllaCompatibile(att *val, int N, int pos, int *selezioni) {
int compatibile = 1;
att last = val[pos];
for (int i = 0; i < N && compatibile; i++) {
if (i != pos && selezioni[i] == 1) {
if (val[i].start < last.end && last.start < val[i].end)
compatibile = 0;
}
}
return compatibile;
}
void stampaSoluzione(int *soluzione, att *val, int N) {
for (int i = 0; i < N; i++) {
if (soluzione[i] == 1) {
printf("(%d, %d) ", val[i].start, val[i].end);
}
}
printf("\n");
}
void attSelR(int N, att *val, int pos, int *selezioni, int *soluzione, int durata, int *durata_soluzione) {
// Terminazione
if (pos >= N) {
if (durata > *durata_soluzione) {
*durata_soluzione = durata;
// copio nuova soluzione
for (int i = 0; i < N; i++) {
soluzione[i] = selezioni[i];
}
}
return;
}
// inserisco un attività solo se è compatibile con il resto della soluzione
if (controllaCompatibile(val, N, pos, selezioni)) {
selezioni[pos] = 1;
int d = val[pos].end - val[pos].start;
attSelR(N, val, pos+1, selezioni,soluzione, durata+d, durata_soluzione);
}
// continuo ad esplorare senza prendere l'attività
selezioni[pos] = 0;
attSelR(N, val, pos+1, selezioni,soluzione, durata, durata_soluzione);
return;
}
void attSel(int N, att *v) {
int durata_soluzione = 0;
int *selezioni = (int *) calloc(N, sizeof(int));
int *soluzione = (int *) calloc(N, sizeof(int));
attSelR(N, v, 0, selezioni, soluzione, 0, &durata_soluzione);
printf("Migliore soluzione:\n");
stampaSoluzione(soluzione, v, N);
printf("Durata della migliore soluzione: %d\n", durata_soluzione);
free(selezioni);
free(soluzione);
}
int main(int argc, char const *argv[])
{
att *val;
int N;
readFile(&val, &N, "att.txt");
attSel(N, val);
free(val);
return 0;
}

View File

@@ -0,0 +1,4 @@
3 3
0/0 -1/-1 2/0
3/1 -1/-1 -1/-1
-1/-1 6/0 -1/-1

View File

@@ -0,0 +1,245 @@
// Laboratorio 5 - Esercizio 2
// Matteo Schiff - s295565
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct tile_s {
char c_o, c_v; // colore orizzontale e verticale
int p_o, p_v; // punti orizzontali e verticali
} tile;
typedef struct cell_s {
int id, rot; // id tile e rotazione
} cell;
void readTiles(tile **tiles, int *N, char *filename) {
FILE *fp;
if ((fp = fopen(filename, "r")) == NULL) {
printf("Errore nell'apertura del file %s",filename);
exit(1);
}
fscanf(fp, "%d", N);
*tiles = (tile *) malloc(*N * sizeof(tile));
for (int i = 0; i < *N; i++) {
fscanf(fp, " %c %d %c %d", &((*tiles)[i].c_o), &((*tiles)[i].p_o), &((*tiles)[i].c_v), &((*tiles)[i].p_v));
}
fclose(fp);
}
void readBoard(cell ***board, int *R, int *C, char *filename) {
FILE *fp;
if ((fp = fopen(filename, "r")) == NULL) {
printf("Errore nell'apertura del file %s",filename);
exit(1);
}
fscanf(fp, "%d %d", R, C);
*board = (cell **) malloc(*R * sizeof(cell *));
for (int i = 0; i < *R; i++) {
(*board)[i] = (cell *) malloc(*C * sizeof(cell));
for (int j = 0; j < *C; j++) {
fscanf(fp, " %d/%d", &(*board)[i][j].id, &(*board)[i][j].rot);
}
}
fclose(fp);
}
// funzione helper per ottenere il colore di un tile conoscendone la posizione
// se `vert` è true restituisce il colore sulla verticale
char getTileColor(tile *tiles, cell **board, int x, int y, bool vert) {
cell c = board[x][y];
if (c.rot ^ vert)
return tiles[c.id].c_v;
return tiles[c.id].c_o;
}
// funzione helper per ottenere il punteggio di un tile conoscendone la posizione
// se `vert` è true restituisce il punteggio sulla verticale
char getTilePoints(tile *tiles, cell **board, int x, int y, bool vert) {
cell c = board[x][y];
if (c.rot ^ vert)
return tiles[c.id].p_v;
return tiles[c.id].p_o;
}
int calcolaPunteggio(int R, int C, tile *tiles, cell **board) {
int points = 0;
for (int i = 0; i < R; i++) {
char color = getTileColor(tiles, board, i, 0, false);
int temp_points = getTilePoints(tiles, board, i, 0, false);
bool ok = true;
for (int j = 1; ok && j < C; j++) {
if (color != getTileColor(tiles, board, i, j, false))
ok = false;
temp_points += getTilePoints(tiles, board, i, j, false);
}
// Aggiungo i punti solo se la riga è dello stesso colore
if (ok) {
points += temp_points;
}
}
for (int i = 0; i < C; i++) {
char color = getTileColor(tiles, board, 0, i, true);
int temp_points = getTilePoints(tiles, board, 0, i, true);
bool ok = true;
for (int j = 1; ok && j < R; j++) {
if (color != getTileColor(tiles, board, j, i, true))
ok = false;
temp_points += getTilePoints(tiles, board, j, i, true);
}
// Aggiungo i punti solo se la colonna è dello stesso colore
if (ok) {
points += temp_points;
}
}
return points;
}
void cercaMassimoR(int R, int C, int N, tile *tiles, bool * taken, cell **board, int depth, int * max, cell **sol) {
// Terminazione
if (depth == R*C) {
int punteggio = calcolaPunteggio(R, C, tiles, board);
if (punteggio > *max) {
*max = punteggio;
// Copio soluzione
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
sol[i][j] = board[i][j];
}
}
}
return;
}
int r = depth / C;
int c = depth % C;
// Provo ad aggiungere un tile solo se nella casella non è già presente un altro tile
if (board[r][c].id == -1 && board[r][c].rot == -1) {
for (int i = 0; i < N; i++) {
if (!taken[i]) {
taken[i] = true;
board[r][c].id = i;
// Aggiungo in un verso
board[r][c].rot = 0;
cercaMassimoR(R, C, N, tiles, taken, board, depth + 1, max, sol);
// Aggiungo nell'altro verso
board[r][c].rot = 1;
cercaMassimoR(R, C, N, tiles, taken, board, depth + 1, max, sol);
taken[i] = false;
}
}
// Pulisco la casella, in modo che nella esplorazione successiva
// la funzione inserisca un altra tessera
board[r][c].id = -1;
board[r][c].rot = -1;
} else {
cercaMassimoR(R, C, N, tiles, taken, board, depth + 1, max, sol);
}
}
cell ** cercaMassimo(int R, int C, int N, tile *tiles, cell **board) {
int max = 0;
bool *taken = (bool *) malloc(N * sizeof(bool));
// Rimuovo dalla lista delle tessere disponibili quelle che sono già presenti sulla board
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
if (board[i][j].id != -1)
taken[board[i][j].id] = true;
}
}
cell **solution = (cell **) malloc(R * sizeof(cell *));
for (int i = 0; i < R; i++) {
solution[i] = (cell *) malloc(C * sizeof(cell));
}
cercaMassimoR(R,C,N,tiles,taken,board,0,&max,solution);
free(taken);
return solution;
}
void freeSolution(cell **solution, int R) {
for (int i = 0; i < R; i++) {
free(solution[i]);
}
free(solution);
}
// Disegna la board
void printBoard(int R, int C, cell **board, tile * tiles) {
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
tile t = tiles[board[i][j].id];
if (board[i][j].rot) {
printf(" %c ", t.c_o);
} else {
printf(" %c ", t.c_v);
}
}
putchar('\n');
for (int j = 0; j < C; j++) {
tile t = tiles[board[i][j].id];
if (board[i][j].rot) {
printf("%c %d ", t.c_v, t.p_v);
} else {
printf("%c %d ", t.c_o, t.p_o);
}
}
putchar('\n');
for (int j = 0; j < C; j++) {
tile t = tiles[board[i][j].id];
if (board[i][j].rot) {
printf(" %d ", t.p_o);
} else {
printf(" %d ", t.p_v);
}
}
putchar('\n');
putchar('\n');
}
}
int main(int argc, char const *argv[])
{
tile *tiles;
cell **board;
int N, R, C;
readTiles(&tiles, &N, "tiles.txt");
readBoard(&board, &R, &C, "board.txt");
cell **solution = cercaMassimo(R,C,N,tiles,board);
printBoard(R, C, solution, tiles);
freeSolution(solution, R);
free(tiles);
free(board);
return 0;
}

View File

@@ -0,0 +1,10 @@
9
A 3 B 2
A 2 V 1
A 2 V 2
B 1 N 2
A 3 G 3
V 1 G 2
R 1 G 6
V 1 B 1
V 11 B 3

View File

@@ -0,0 +1,17 @@
15
5 7 4 10
6 8 10 1
3 1 6 10
4 4 2 1
7 2 4 10
8 8 4 6
6 1 4 4
8 3 6 4
7 7 4 2
1 3 7 1
10 10 9 10
8 8 8 6
9 6 10 5
6 10 9 5
9 6 9 9

View File

@@ -0,0 +1,45 @@
TEST #1
zaffiro = 5, rubino = 7, topazio = 4, smeraldo = 10, TOT = 26
Collana massima di lunghezza 24
TEST #2
zaffiro = 6, rubino = 8, topazio = 10, smeraldo = 1, TOT = 25
Collana massima di lunghezza 24
TEST #3
zaffiro = 3, rubino = 1, topazio = 6, smeraldo = 10, TOT = 20
Collana massima di lunghezza 16
TEST #4
zaffiro = 4, rubino = 4, topazio = 2, smeraldo = 1, TOT = 11
Collana massima di lunghezza 10
TEST #5
zaffiro = 7, rubino = 2, topazio = 4, smeraldo = 10, TOT = 23
Collana massima di lunghezza 22
TEST #6
zaffiro = 8, rubino = 8, topazio = 4, smeraldo = 6, TOT = 26
Collana massima di lunghezza 23
TEST #7
zaffiro = 6, rubino = 1, topazio = 4, smeraldo = 4, TOT = 15
Collana massima di lunghezza 13
TEST #8
zaffiro = 8, rubino = 3, topazio = 6, smeraldo = 4, TOT = 21
Collana massima di lunghezza 19
TEST #9
zaffiro = 7, rubino = 7, topazio = 4, smeraldo = 2, TOT = 20
Collana massima di lunghezza 18
TEST #10
zaffiro = 1, rubino = 3, topazio = 7, smeraldo = 1, TOT = 12
Collana massima di lunghezza 9
TEST #11
zaffiro = 10, rubino = 10, topazio = 9, smeraldo = 10, TOT = 39
Collana massima di lunghezza 39
TEST #12
zaffiro = 8, rubino = 8, topazio = 8, smeraldo = 6, TOT = 30
Collana massima di lunghezza 30
TEST #13
zaffiro = 9, rubino = 6, topazio = 10, smeraldo = 5, TOT = 30
Collana massima di lunghezza 27
TEST #14
zaffiro = 6, rubino = 10, topazio = 9, smeraldo = 5, TOT = 30
Collana massima di lunghezza 30
TEST #15
zaffiro = 9, rubino = 6, topazio = 9, smeraldo = 9, TOT = 33
Collana massima di lunghezza 31

View File

@@ -0,0 +1,16 @@
15
19 6 8 5
19 14 5 11
14 14 5 8
12 16 5 14
12 17 20 20
13 11 14 18
7 14 12 10
13 20 12 17
17 18 6 9
5 5 15 19
18 12 20 17
13 6 19 6
17 20 15 19
12 18 17 8
7 20 12 7

View File

@@ -0,0 +1,45 @@
TEST #1
zaffiro = 19, rubino = 6, topazio = 8, smeraldo = 5, TOT = 38
Collana massima di lunghezza 37
TEST #2
zaffiro = 19, rubino = 14, topazio = 5, smeraldo = 11, TOT = 49
Collana massima di lunghezza 41
TEST #3
zaffiro = 14, rubino = 14, topazio = 5, smeraldo = 8, TOT = 41
Collana massima di lunghezza 33
TEST #4
zaffiro = 12, rubino = 16, topazio = 5, smeraldo = 14, TOT = 47
Collana massima di lunghezza 37
TEST #5
zaffiro = 12, rubino = 17, topazio = 20, smeraldo = 20, TOT = 69
Collana massima di lunghezza 67
TEST #6
zaffiro = 13, rubino = 11, topazio = 14, smeraldo = 18, TOT = 56
Collana massima di lunghezza 54
TEST #7
zaffiro = 7, rubino = 14, topazio = 12, smeraldo = 10, TOT = 43
Collana massima di lunghezza 42
TEST #8
zaffiro = 13, rubino = 20, topazio = 12, smeraldo = 17, TOT = 62
Collana massima di lunghezza 55
TEST #9
zaffiro = 17, rubino = 18, topazio = 6, smeraldo = 9, TOT = 50
Collana massima di lunghezza 39
TEST #10
zaffiro = 5, rubino = 5, topazio = 15, smeraldo = 19, TOT = 44
Collana massima di lunghezza 35
TEST #11
zaffiro = 18, rubino = 12, topazio = 20, smeraldo = 17, TOT = 67
Collana massima di lunghezza 60
TEST #12
zaffiro = 13, rubino = 6, topazio = 19, smeraldo = 6, TOT = 44
Collana massima di lunghezza 32
TEST #13
zaffiro = 17, rubino = 20, topazio = 15, smeraldo = 19, TOT = 71
Collana massima di lunghezza 67
TEST #14
zaffiro = 12, rubino = 18, topazio = 17, smeraldo = 8, TOT = 55
Collana massima di lunghezza 55
TEST #15
zaffiro = 7, rubino = 20, topazio = 12, smeraldo = 7, TOT = 46
Collana massima di lunghezza 39

View File

@@ -0,0 +1,201 @@
// Laboratorio 6 - Esercizio 2
// Matteo Schiff - s295565
#include <stdio.h>
#include <stdlib.h>
int fZ(int z, int r, int t, int s, int len);
int fR(int z, int r, int t, int s, int len);
int fS(int z, int r, int t, int s, int len);
int fT(int z, int r, int t, int s, int len);
enum Pietra{zaffiro, rubino, topazio, smeraldo};
int *cache;
int mz, mr, mt, ms;
// Funzioni helper per semplificare la memorizzazione
// NOTA se `getCache` restituisce 0 vuol dire che la collana non è ancora stata analizzata
int getCache(int p, int z, int r, int t, int s) {
return *(cache + p*mz*mr*mt*ms + z*mr*mt*ms + r*mt*ms + t*ms + s);
}
void saveCache(int p, int z, int r, int t, int s, int val) {
*(cache + p*mz*mr*mt*ms + z*mr*mt*ms + r*mt*ms + t*ms + s) = val;
}
int fZ(int z, int r, int t, int s, int len) {
if (len != 0 && getCache(zaffiro, z,r,t,s) != 0) {
return getCache(zaffiro,z,r,t,s);
}
int x = -1;
int m;
if (z > 0) {
m = fZ(z-1,r,t,s,len +1);
if (m > x)
x = m;
}
if (r > 0) {
m = fR(z,r-1,t,s,len +1);
if (m > x)
x = m;
}
// se non è possibile più aggiungere pietre, ho raggiunto la lunghezza massima ottenibile dal ramo
if (x == -1) {
saveCache(zaffiro,z,r,t,s,len);
return len;
}
// se no restituisco il massimo fin'ora
saveCache(zaffiro,z,r,t,s,x);
return x;
}
int fR(int z, int r, int t, int s, int len) {
if (len != 0 && getCache(rubino, z,r,t,s) != 0) {
return getCache(rubino,z,r,t,s);
}
int x = -1;
int m;
if (s > 0) {
m = fS(z,r,t,s-1,len +1);
if (m > x)
x = m;
}
if (t > 0) {
m = fT(z,r,t-1,s,len +1);
if (m > x)
x = m;
}
// se non è possibile più aggiungere pietre, ho raggiunto la lunghezza massima ottenibile dal ramo
if (x == -1) {
saveCache(rubino,z,r,t,s,len);
return len;
}
// se no restituisco il massimo fin'ora
saveCache(rubino,z,r,t,s,x);
return x;
}
int fT(int z, int r, int t, int s, int len) {
if (len != 0 && getCache(topazio, z,r,t,s) != 0) {
return getCache(topazio,z,r,t,s);
}
int x = -1;
int m;
if (z > 0) {
m = fZ(z-1,r,t,s,len +1);
if (m > x)
x = m;
}
if (r > 0) {
m = fR(z,r-1,t,s,len +1);
if (m > x)
x = m;
}
// se non è possibile più aggiungere pietre, ho raggiunto la lunghezza massima ottenibile dal ramo
if (x == -1) {
saveCache(topazio,z,r,t,s,len);
return len;
}
// se no restituisco il massimo fin'ora
saveCache(topazio,z,r,t,s,x);
return x;
}
int fS(int z, int r, int t, int s, int len) {
if (len != 0 && getCache(smeraldo, z,r,t,s) != 0) {
return getCache(smeraldo,z,r,t,s);
}
int x = -1;
int m;
if (s > 0) {
m = fS(z,r,t,s-1,len +1);
if (m > x)
x = m;
}
if (t > 0) {
m = fT(z,r,t-1,s,len +1);
if (m > x)
x = m;
}
// se non è possibile più aggiungere pietre, ho raggiunto la lunghezza massima ottenibile dal ramo
if (x == -1) {
saveCache(smeraldo,z,r,t,s,len);
return len;
}
// se no restituisco il massimo fin'ora
saveCache(smeraldo,z,r,t,s,x);
return x;
}
void solveCase(int z, int r, int t, int s) {
mz = z+1;
mr = r+1;
mt = t+1;
ms = s+1;
cache = calloc(4*mz*mr*mt*ms, sizeof(int));
int max = z+r+t+s;
int res = -1, x;
printf("zaffiri = %d, rubini = %d, topazi = %d, smeraldi = %d; numero pietre = %d\n", z,r,t,s,max);
x = fZ(z-1,r,t,s,1);
if (x > res)
res = x;
x = fR(z,r-1,t,s,1);
if (x > res)
res = x;
x = fS(z,r,t,s-1,1);
if (x > res)
res = x;
x = fT(z,r,t-1,s,1);
if (x > res)
res = x;
free(cache);
printf("Collana massima di lunghezza %d\n", res);
fflush(stdout);
}
int main() {
int z, r, t, s, N = 0;
FILE *fp;
if ((fp = fopen("hard_test_set.txt", "r")) == NULL)
{
puts("Impossibile aprire il file");
return 1;
}
fscanf(fp, "%d", &N);
for (int i = 0; i < N; i++) {
fscanf(fp, " %d %d %d %d", &z, &r, &t, &s);
printf("Test case %d\n", i+1);
solveCase(z,r,t,s);
}
fclose(fp);
}

View File

@@ -0,0 +1,108 @@
// Laboratorio 6 - Esercizio 3 - equipArray.c
// Matteo Schiff - s295565
#ifndef EQUIPARRAY_C_DEFINED
#define EQUIPARRAY_C_DEFINED
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "invArray.h"
#include "equipArray.h"
#include "inv.h"
/* ADT di prima classe collezione di oggetti di equipaggiamento */
typedef struct equipArray_s {
int inUse;
inv_t *items[EQUIP_SLOT];
} *equipArray_t;
/* creatore e disruttore */
equipArray_t equipArray_init() {
equipArray_t new = malloc(sizeof(struct equipArray_s));
new->inUse = 0;
return new;
}
void equipArray_free(equipArray_t equipArray) {
free(equipArray);
}
/* quanti equipaggiamenti sono in uso */
int equipArray_inUse(equipArray_t equipArray) {
return equipArray->inUse;
}
void equipArray_apply_modifier(stat_t *stats, equipArray_t equipArray) {
for (int i = 0; i < equipArray_inUse(equipArray); i++) {
stat_sum(stats, &equipArray->items[i]->stat);
}
}
/* scrittura su file */
void equipArray_print(FILE *fp, equipArray_t equipArray, invArray_t invArray) {
for (int i = 0; i < equipArray->inUse; i++) {
printf(" %d: ", i);
inv_print(fp, equipArray->items[i]);
}
}
void equipArray_insert(equipArray_t equipArray, invArray_t invArray) {
char name[LEN+1];
if (equipArray->inUse >= EQUIP_SLOT) {
puts("Tutti gli slot sono occupati");
return;
}
puts("Inserisci il nome dell'oggetto da equipaggiare: ");
scanf(" %50s", name);
int index = invArray_searchByName(invArray, name);
if (index == -1) {
puts("Oggetto non trovato");
return;
}
inv_t *selected = invArray_getByIndex(invArray, index);
equipArray->items[(equipArray->inUse)++] = selected;
}
void equipArray_remove(equipArray_t equipArray, invArray_t invArray) {
int index;
if (equipArray->inUse <= 0) {
puts("Tutti gli slot sono vuoti");
return;
}
puts("Oggetti equipaggiati: ");
equipArray_print(stdout, equipArray, invArray);
puts("Inserisci l'indice dell'oggetto da rimuovere: ");
scanf(" %d", &index);
if (index < 0 || index >= equipArray->inUse) {
puts("Indice oggetto non valido");
return;
}
equipArray->items[index] = equipArray->items[--(equipArray->inUse)];
}
/* modifica equipaggiamento scegliendo un oggetto da inventario */
void equipArray_update(equipArray_t equipArray, invArray_t invArray) {
char selection;
puts("Vuoi inserire o rimuovere un oggetto? Rispondi (i) o (r): ");
scanf(" %c", &selection);
if (selection == 'i') {
equipArray_insert(equipArray, invArray);
} else {
equipArray_remove(equipArray, invArray);
}
}
/* Si possono aggiungere altre funzioni se ritenute necessarie */
#endif

View File

@@ -0,0 +1,34 @@
// Laboratorio 6 - Esercizio 3 - equipArray.h
// Matteo Schiff - s295565
#ifndef EQUIPARRAY_H_DEFINED
#define EQUIPARRAY_H_DEFINED
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define EQUIP_SLOT 8
#include "invArray.h"
/* ADT di prima classe collezione di oggetti di equipaggiamento */
typedef struct equipArray_s *equipArray_t;
/* creatore e disruttore */
equipArray_t equipArray_init();
void equipArray_free(equipArray_t equipArray);
/* quanti equipaggiamenti sono in uso */
int equipArray_inUse(equipArray_t equipArray);
void equipArray_apply_modifier(stat_t *stats, equipArray_t equipArray);
/* scrittura su file */
void equipArray_print(FILE *fp, equipArray_t equipArray, invArray_t invArray);
/* modifica equipaggiamento scegliendo un oggetto da inventario */
void equipArray_update(equipArray_t equipArray, invArray_t invArray);
/* Si possono aggiungere altre funzioni se ritenute necessarie */
#endif

View File

@@ -0,0 +1,122 @@
// Laboratorio 6 - Esercizio 3 - gdr.c
// Matteo Schiff - s295565
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "pgList.h"
#include "invArray.h"
#include "pg.h"
#define N_SCELTE 7
#define DBG 0
enum { falso, vero };
typedef int bool;
void stampaMenu(char *scelte[], int *selezione){
int i=0;
printf("\nMENU'\n");
for(i=0;i<N_SCELTE;i++)
printf("%2d > %s\n",i,scelte[i]);
scanf(" %d",selezione);
}
int main(int argc, char **argv) {
char *scelte[] = {
"Uscita",
"Stampa personaggi",
"Stampa inventario",
"Cerca personaggio",
"Aggiungi personaggio",
"Elimina personaggio",
"Modifica equip"
};
char codiceRicerca[LEN];
int selezione;
FILE *fin;
bool fineProgramma;
pgList_t pgList = pgList_init();
invArray_t invArray = invArray_init();
pg_t *pgp, pg;
fin = fopen("pg.txt","r");
pgList_read(fin, pgList);
fclose(fin);
#if DBG
pgList_print(stdout, pgList);
#endif /* DBG */
fin = fopen("inventario.txt","r");
invArray_read(fin, invArray);
fclose(fin);
#if DBG
invArray_print(stdout, invArray);
#endif /* DBG */
fineProgramma = falso;
do {
stampaMenu(scelte, &selezione);
switch(selezione){
case 0: {
fineProgramma = vero;
} break;
case 1: {
pgList_print(stdout, pgList, invArray);
} break;
case 2: {
invArray_print(stdout, invArray);
} break;
case 3: {
printf("Inserire codice personaggio: ");
scanf("%s", codiceRicerca);
pgp = pgList_searchByCode(pgList, codiceRicerca);
if (pgp!=NULL) {
pg_print(stdout, pgp, invArray);
} else {
puts("Personaggio non trovato");
}
} break;
case 4: {
printf("Cod Nome Classe HP MP ATK DEF MAG SPR: ");
if (pg_read(stdin, &pg) != 0) {
pgList_insert(pgList, pg);
}
} break;
case 5: {
printf("Inserire codice personaggio: ");
scanf("%s", codiceRicerca);
pgList_remove(pgList, codiceRicerca);
} break;
case 6: {
printf("Inserire codice personaggio: ");
scanf("%s", codiceRicerca);
pgp = pgList_searchByCode(pgList, codiceRicerca);
if (pgp!=NULL) {
pg_updateEquip(pgp, invArray);
} else {
puts("Personaggio non trovato");
}
} break;
default:{
printf("Scelta non valida\n");
} break;
}
} while(!fineProgramma);
pgList_free(pgList);
return 0;
}

View File

@@ -0,0 +1,71 @@
// Laboratorio 6 - Esercizio 3 - inv.c
// Matteo Schiff - s295565
#ifndef INV_C_DEFINED
#define INV_C_DEFINED
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <limits.h>
#include "inv.h"
/* funzioni di input/output delle statistiche */
void stat_read(FILE *fp, stat_t *statp) {
fscanf(fp, " %d %d %d %d %d %d", &(statp->hp), &(statp->mp), &(statp->atk), &(statp->def), &(statp->mag), &(statp->spr));
}
int zero_se_soglia(int a, int soglia) {
if (a < soglia)
return 0;
return a;
}
void stat_print(FILE *fp, stat_t *statp, int soglia) {
fprintf(fp, "HP: %d, MP: %d, ATK: %d, DEF: %d, MAG: %d, SPR: %d\n",
zero_se_soglia(statp->hp, soglia),
zero_se_soglia(statp->mp, soglia),
zero_se_soglia(statp->atk, soglia),
zero_se_soglia(statp->def, soglia),
zero_se_soglia(statp->mag, soglia),
zero_se_soglia(statp->spr, soglia));
}
void stat_copy(stat_t *a, stat_t *b) {
a->atk = b->atk;
a->def = b->def;
a->hp = b->hp;
a->mag = b->mag;
a->mp = b->mp;
a->spr = b->spr;
}
void stat_sum(stat_t *a, stat_t *b) {
a->atk += b->atk;
a->def += b->def;
a->hp += b->hp;
a->mag += b->mag;
a->mp += b->mp;
a->spr += b->spr;
}
/* funzioni di input/output di un oggetto dell'inventario */
void inv_read(FILE *fp, inv_t *invp) {
fscanf(fp, " %49s %49s", invp->nome, invp->tipo);
stat_read(fp, &(invp->stat));
}
void inv_print(FILE *fp, inv_t *invp) {
fprintf(fp, " %s (%s) - ", invp->nome, invp->tipo);
stat_print(fp, &(invp->stat),INT_MIN);
}
/* ritorna il campo stat di un oggetto dell'inventario */
stat_t inv_getStat(inv_t *invp) {
return invp->stat;
}
/* Si possono aggiungere altre funzioni se ritenute necessarie */
#endif

View File

@@ -0,0 +1,42 @@
// Laboratorio 6 - Esercizio 3 - inv.h
// Matteo Schiff - s295565
#ifndef INV_H_DEFINED
#define INV_H_DEFINED
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define LEN 50
#define MIN_STAT 1
/* quasi ADT statistiche */
typedef struct stat_s {
int hp, mp, atk, def, mag, spr;
} stat_t;
/* quasi ADT oggetto di inventario */
typedef struct inv_s {
char nome[LEN];
char tipo[LEN];
stat_t stat;
} inv_t;
/* funzioni di input/output delle statistiche */
void stat_read(FILE *fp, stat_t *statp);
void stat_print(FILE *fp, stat_t *statp, int soglia);
void stat_copy(stat_t *a, stat_t *b);
void stat_sum(stat_t *a, stat_t *b);
/* funzioni di input/output di un oggetto dell'inventario */
void inv_read(FILE *fp, inv_t *invp);
void inv_print(FILE *fp, inv_t *invp);
/* ritorna il campo stat di un oggetto dell'inventario */
stat_t inv_getStat(inv_t *invp);
/* Si possono aggiungere altre funzioni se ritenute necessarie */
#endif

View File

@@ -0,0 +1,67 @@
// Laboratorio 6 - Esercizio 3 - invArray.c
// Matteo Schiff - s295565
#ifndef INVARRAY_C_DEFINED
#define INVARRAY_C_DEFINED
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "inv.h"
typedef struct invArray_s {
int N;
inv_t *array;
} *invArray_t;
/* creatore e disruttore */
invArray_t invArray_init() {
invArray_t new = malloc(sizeof(struct invArray_s));
new->N = 0;
new->array = NULL;
return new;
}
void invArray_free(invArray_t invArray) {
free(invArray->array);
free(invArray);
}
/* lettura e scrittura su file */
void invArray_read(FILE *fp, invArray_t invArray) {
if (fscanf(fp, " %d", &invArray->N) != 1)
return;
invArray->array = malloc(invArray->N * sizeof(inv_t));
for (int i = 0; i < invArray->N; i++) {
inv_read(fp, &invArray->array[i]);
}
}
void invArray_print(FILE *fp, invArray_t invArray) {
for (int i = 0; i < invArray->N; i++) {
inv_print(fp, &invArray->array[i]);
}
}
/* ritorna puntatore a oggetto selezionato da indice (nel vettore) */
inv_t *invArray_getByIndex(invArray_t invArray, int index) {
if (index >= invArray->N)
return NULL;
return &(invArray->array[index]);
}
/* ritorna indice (nel vettore) a oggetto selezionato da nome */
int invArray_searchByName(invArray_t invArray, char *name) {
for (int i = 0; i < invArray->N; i++) {
if (!strcmp(invArray->array[i].nome, name))
return i;
}
return -1;
}
/* Si possono aggiungere altre funzioni se ritenute necessarie */
#endif

View File

@@ -0,0 +1,30 @@
// Laboratorio 6 - Esercizio 3 - invArray.h
// Matteo Schiff - s295565
#ifndef INVARRAY_H_DEFINED
#define INVARRAY_H_DEFINED
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "inv.h"
/* ADT di prima classe collezione di oggetti di inventario */
typedef struct invArray_s *invArray_t;
/* creatore e disruttore */
invArray_t invArray_init();
void invArray_free(invArray_t invArray);
/* lettura e scrittura su file */
void invArray_read(FILE *fp, invArray_t invArray);
void invArray_print(FILE *fp, invArray_t invArray);
/* ritorna puntatore a oggetto selezionato da indice (nel vettore) */
inv_t *invArray_getByIndex(invArray_t invArray, int index);
/* ritorna indice (nel vettore) a oggetto selezionato da nome */
int invArray_searchByName(invArray_t invArray, char *name);
/* Si possono aggiungere altre funzioni se ritenute necessarie */
#endif

View File

@@ -0,0 +1,16 @@
15
Excalibur Spada2M 0 0 120 0 0 50
Filatterio Accessorio -100 20 -30 -30 25 25
ArmillaDiDiamante Accessorio 0 0 25 0 25
Escutcheon Scudo 1000 50 0 75 0 0
MantoElfico Vesti 0 50 0 10 10 10
Pendragon Scudo 250 0 0 45 0 30
Oricalco Reliquia 0 0 0 0 15 15
TalismanoNero Accessorio -500 150 0 0 100 50
AmmazzaDraghi Spada2M 0 0 80 -20 0 -20
Fiocco Accessorio 0 0 1 1 1 1
CorazzaAdamantina ArmaturaPesante 3333 333 -15 33 -15 33
DagaRunica Pugnale 0 50 10 0 35 0
Tempesta Spada1M 0 0 40 0 -5 0
Maximillian ArmaturaLeggera 500 0 0 30 0 15
Ametista Reliquia 0 0 15 15 0 0

View File

@@ -0,0 +1,49 @@
// Laboratorio 6 - Esercizio 3 - pg.c
// Matteo Schiff - s295565
#ifndef PG_C_DEFINED
#define PG_C_DEFINED
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "equipArray.h"
#include "pg.h"
void pg_calc_stats(pg_t *pgp) {
stat_copy(&pgp->eq_stat, &pgp->b_stat);
equipArray_apply_modifier(&pgp->eq_stat, pgp->equip);
}
/* lettura e scrittura su file */
int pg_read(FILE *fp, pg_t *pgp) {
if (fscanf(fp, " %49s %49s %49s", pgp->cod, pgp->nome, pgp->classe) != 3)
return 0;
stat_read(fp, &(pgp->b_stat));
pgp->equip = equipArray_init();
pg_calc_stats(pgp);
return 1;
}
/* non essendo struct dinamica, pulisce chiamando il distruttore di equipArray */
void pg_clean(pg_t *pgp) {
free(pgp->equip);
}
void pg_print(FILE *fp, pg_t *pgp, invArray_t invArray) {
fprintf(fp, "%s (%s)\n Classe: %s\n Statistiche - ", pgp->nome, pgp->cod, pgp->classe);
stat_print(fp, &(pgp->eq_stat), 0);
equipArray_print(fp, pgp->equip, invArray);
}
/* modifica personaggio aggiungendo/togliendo un equipaggiamento selezionato da inventario:
di fatto e' sufficiente chiamare l'opportuna funzione dal modulo equipArray */
void pg_updateEquip(pg_t *pgp, invArray_t invArray) {
equipArray_update(pgp->equip, invArray);
pg_calc_stats(pgp);
}
/* Si possono aggiungere altre funzioni se ritenute necessarie */
#endif

View File

@@ -0,0 +1,35 @@
// Laboratorio 6 - Esercizio 3 - pg.h
// Matteo Schiff - s295565
#ifndef PG_H_DEFINED
#define PG_H_DEFINED
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "equipArray.h"
/* quasi ADT personaggio; si noti che si tratta di un composto con riferimento
a un equipArray di proprieta' */
typedef struct pg_s {
char cod[LEN];
char nome[LEN];
char classe[LEN];
stat_t b_stat, eq_stat;
equipArray_t equip;
} pg_t;
/* lettura e scrittura su file */
int pg_read(FILE *fp, pg_t *pgp);
/* non essendo struct dinamica, pulisce chiamando il distruttire di equipArray */
void pg_clean(pg_t *pgp);
void pg_print(FILE *fp, pg_t *pgp, invArray_t invArray);
/* modifica personaggio aggiungendo/togliendo un equipaggiamento selezionato da inventario:
di fatto e' sufficiente chiamare l'opportuna funzione dal modulo equipArray */
void pg_updateEquip(pg_t *pgp, invArray_t invArray);
/* Si possono aggiungere altre funzioni se ritenute necessarie */
#endif

View File

@@ -0,0 +1,10 @@
PG0001 Sephiroth Guerriero 1832 71 116 65 41 49
PG0002 Aerith MagoBianco 976 144 12 39 121 140
PG0003 Vivi MagoNero 1001 136 17 36 131 115
PG0004 Beatrix Templare 1654 99 85 35 70 61
PG0005 Orlandeau Paladino 1701 84 81 68 34 48
PG0006 Basch Capitano 2199 46 32 98 33 89
PG0007 Lulu MagoNero 999 139 21 33 119 117
PG0008 Yuna Evocatrice 1019 100 32 17 97 99
PG0009 DarkCecil CavaliereNero 1901 48 106 90 12 18
PG0010 Kefka Arcimago 1271 89 39 47 89 64

View File

@@ -0,0 +1,131 @@
// Laboratorio 6 - Esercizio 3 - pgList.c
// Matteo Schiff - s295565
#ifndef PGLIST_C_DEFINED
#define PGLIST_C_DEFINED
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "pgList.h"
typedef struct node_s *link;
typedef struct node_s {
pg_t val;
link next;
} node;
/* ADT di prima classe collezione di personaggi */
typedef struct pgList_s {
link head;
link tail;
int nPg;
} *pgList_t;
link new_node(pg_t val, link next) {
link t = malloc(sizeof(node));
if (t == NULL) {
printf("ERROR: out of memory");
exit(2);
}
t->val = val;
t->next = next;
return t;
}
void free_node(link p) {
pg_clean(&p->val);
free(p);
}
/* creatore e distruttore */
pgList_t pgList_init() {
pgList_t new = malloc(sizeof(struct pgList_s));
new->head = NULL;
new->tail = NULL;
new->nPg = 0;
return new;
}
void pgList_free(pgList_t pgList) {
link p, x;
for (p = pgList->head, x = pgList->head->next; x != NULL; p = x, x = x->next){
free_node(p);
}
free(pgList);
}
/* lettura e scrittura su file */
void pgList_read(FILE *fp, pgList_t pgList) {
while (!feof(fp))
{
pg_t pgp;
if (pg_read(fp, &pgp) != 0) {
pgList_insert(pgList, pgp);
}
}
}
void pgList_print(FILE *fp, pgList_t pgList, invArray_t invArray) {
link p;
for (p = pgList->head; p != NULL; p = p->next) {
pg_print(fp, &(p->val), invArray);
}
}
/* inserimento di un nuovo personaggio */
void pgList_insert(pgList_t pgList, pg_t pg) {
link new = new_node(pg, NULL);
if (pgList->head == NULL) {
pgList->head = new;
} else {
pgList->tail->next = new;
}
pgList->tail = new;
}
/* cancellazione con rimozione */
void pgList_remove(pgList_t pgList, char* cod) {
link p, x;
if (pgList->head == NULL)
return;
for (x = pgList->head, p = NULL; x != NULL; p = x, x = x->next) {
if (!strcmp(x->val.cod, cod)) {
if (p == NULL) {
pgList->head = x->next;
} else {
p->next = x->next;
// se tolgo l'ultimo elemento devo aggiornare `tail`
if (x->next == NULL)
pgList->tail = p;
}
free_node(x);
break;
}
}
}
/* ricerca per codice, ritornando il puntatore */
pg_t *pgList_searchByCode(pgList_t pgList, char* cod) {
link p;
for (p = pgList->head; p != NULL; p = p->next) {
if (!strcmp(p->val.cod, cod)) {
return &(p->val);
}
}
return NULL;
}
/* Si possono aggiungere altre funzioni se ritenute necessarie */
#endif

View File

@@ -0,0 +1,33 @@
// Laboratorio 6 - Esercizio 3 - pgList.h
// Matteo Schiff - s295565
#ifndef PGLIST_H_DEFINED
#define PGLIST_H_DEFINED
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "pg.h"
/* ADT di prima classe collezione di personaggi */
typedef struct pgList_s *pgList_t;
/* creatore e distruttore */
pgList_t pgList_init();
void pgList_free(pgList_t pgList);
/* lettura e scrittura su file */
void pgList_read(FILE *fp, pgList_t pgList);
void pgList_print(FILE *fp, pgList_t pgList, invArray_t invArray);
/* inserimento di un nuovo personaggio */
void pgList_insert(pgList_t pgList, pg_t pg);
/* cancellazione con rimozione */
void pgList_remove(pgList_t pgList, char* cod);
/* ricerca per codice, ritornando il puntatore */
pg_t *pgList_searchByCode(pgList_t pgList, char* cod);
/* Si possono aggiungere altre funzioni se ritenute necessarie */
#endif

View File

@@ -0,0 +1,103 @@
// Laboratorio 7 - Esercizio 1 - equipArray.c
// Matteo Schiff - s295565
#ifndef EQUIPARRAY_C_DEFINED
#define EQUIPARRAY_C_DEFINED
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "invArray.h"
#include "equipArray.h"
/* ADT di prima classe collezione di oggetti di equipaggiamento */
typedef struct equipArray_s {
int inUse;
int items[EQUIP_SLOT];
} *equipArray_t;
/* creatore e disruttore */
equipArray_t equipArray_init() {
equipArray_t new = malloc(sizeof(struct equipArray_s));
new->inUse = 0;
return new;
}
void equipArray_free(equipArray_t equipArray) {
free(equipArray);
}
/* quanti equipaggiamenti sono in uso */
int equipArray_inUse(equipArray_t equipArray) {
return equipArray->inUse;
}
int equipArray_getEquipByIndex(equipArray_t equipArray, int index) {
return equipArray->items[index];
}
/* scrittura su file */
void equipArray_print(FILE *fp, equipArray_t equipArray, invArray_t invArray) {
for (int i = 0; i < equipArray->inUse; i++) {
printf(" %d: ", i);
invArray_printByIndex(fp, invArray, equipArray->items[i]);
}
}
void equipArray_insert(equipArray_t equipArray, invArray_t invArray) {
char name[LEN+1];
if (equipArray->inUse >= EQUIP_SLOT) {
puts("Tutti gli slot sono occupati");
return;
}
puts("Inserisci il nome dell'oggetto da equipaggiare: ");
scanf(" %50s", name);
int index = invArray_searchByName(invArray, name);
if (index == -1) {
puts("Oggetto non trovato");
return;
}
equipArray->items[(equipArray->inUse)++] = index;
}
void equipArray_remove(equipArray_t equipArray, invArray_t invArray) {
int index;
if (equipArray->inUse <= 0) {
puts("Tutti gli slot sono vuoti");
return;
}
puts("Oggetti equipaggiati: ");
equipArray_print(stdout, equipArray, invArray);
puts("Inserisci l'indice dell'oggetto da rimuovere: ");
scanf(" %d", &index);
if (index < 0 || index >= equipArray->inUse) {
puts("Indice oggetto non valido");
return;
}
equipArray->items[index] = equipArray->items[--(equipArray->inUse)];
}
/* modifica equipaggiamento scegliendo un oggetto da inventario */
void equipArray_update(equipArray_t equipArray, invArray_t invArray) {
char selection;
puts("Vuoi inserire o rimuovere un oggetto? Rispondi (i) o (r): ");
scanf(" %c", &selection);
if (selection == 'i') {
equipArray_insert(equipArray, invArray);
} else {
equipArray_remove(equipArray, invArray);
}
}
/* Si possono aggiungere altre funzioni se ritenute necessarie */
#endif

View File

@@ -0,0 +1,33 @@
// Laboratorio 7 - Esercizio 1 - equipArray.h
// Matteo Schiff - s295565
#ifndef EQUIPARRAY_H_DEFINED
#define EQUIPARRAY_H_DEFINED
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define EQUIP_SLOT 8
#include "invArray.h"
/* ADT di prima classe collezione di oggetti di equipaggiamento */
typedef struct equipArray_s *equipArray_t;
/* creatore e disruttore */
equipArray_t equipArray_init();
void equipArray_free(equipArray_t equipArray);
/* quanti equipaggiamenti sono in uso */
int equipArray_inUse(equipArray_t equipArray);
/* scrittura su file */
void equipArray_print(FILE *fp, equipArray_t equipArray, invArray_t invArray);
/* modifica equipaggiamento scegliendo un oggetto da inventario */
void equipArray_update(equipArray_t equipArray, invArray_t invArray);
int equipArray_getEquipByIndex(equipArray_t equipArray, int index);
/* Si possono aggiungere altre funzioni se ritenute necessarie */
#endif

View File

@@ -0,0 +1,122 @@
// Laboratorio 7 - Esercizio 1 - gdr.c
// Matteo Schiff - s295565
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "pgList.h"
#include "invArray.h"
#include "pg.h"
#define N_SCELTE 7
#define DBG 0
enum { falso, vero };
typedef int bool;
void stampaMenu(char *scelte[], int *selezione){
int i=0;
printf("\nMENU'\n");
for(i=0;i<N_SCELTE;i++)
printf("%2d > %s\n",i,scelte[i]);
scanf(" %d",selezione);
}
int main(int argc, char **argv) {
char *scelte[] = {
"Uscita",
"Stampa personaggi",
"Stampa inventario",
"Cerca personaggio",
"Aggiungi personaggio",
"Elimina personaggio",
"Modifica equip"
};
char codiceRicerca[LEN];
int selezione;
FILE *fin;
bool fineProgramma;
pgList_t pgList = pgList_init();
invArray_t invArray = invArray_init();
pg_t *pgp, pg;
fin = fopen("pg.txt","r");
pgList_read(fin, pgList);
fclose(fin);
#if DBG
pgList_print(stdout, pgList);
#endif /* DBG */
fin = fopen("inventario.txt","r");
invArray_read(fin, invArray);
fclose(fin);
#if DBG
invArray_print(stdout, invArray);
#endif /* DBG */
fineProgramma = falso;
do {
stampaMenu(scelte, &selezione);
switch(selezione){
case 0: {
fineProgramma = vero;
} break;
case 1: {
pgList_print(stdout, pgList, invArray);
} break;
case 2: {
invArray_print(stdout, invArray);
} break;
case 3: {
printf("Inserire codice personaggio: ");
scanf("%s", codiceRicerca);
pgp = pgList_searchByCode(pgList, codiceRicerca);
if (pgp!=NULL) {
pg_print(stdout, pgp, invArray);
} else {
puts("Personaggio non trovato");
}
} break;
case 4: {
printf("Cod Nome Classe HP MP ATK DEF MAG SPR: ");
if (pg_read(stdin, &pg) != 0) {
pgList_insert(pgList, pg);
}
} break;
case 5: {
printf("Inserire codice personaggio: ");
scanf("%s", codiceRicerca);
pgList_remove(pgList, codiceRicerca);
} break;
case 6: {
printf("Inserire codice personaggio: ");
scanf("%s", codiceRicerca);
pgp = pgList_searchByCode(pgList, codiceRicerca);
if (pgp!=NULL) {
pg_updateEquip(pgp, invArray);
} else {
puts("Personaggio non trovato");
}
} break;
default:{
printf("Scelta non valida\n");
} break;
}
} while(!fineProgramma);
pgList_free(pgList);
return 0;
}

View File

@@ -0,0 +1,71 @@
// Laboratorio 7 - Esercizio 1 - inv.c
// Matteo Schiff - s295565
#ifndef INV_C_DEFINED
#define INV_C_DEFINED
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <limits.h>
#include "inv.h"
/* funzioni di input/output delle statistiche */
void stat_read(FILE *fp, stat_t *statp) {
fscanf(fp, " %d %d %d %d %d %d", &(statp->hp), &(statp->mp), &(statp->atk), &(statp->def), &(statp->mag), &(statp->spr));
}
int zero_se_soglia(int a, int soglia) {
if (a < soglia)
return 0;
return a;
}
void stat_print(FILE *fp, stat_t *statp, int soglia) {
fprintf(fp, "HP: %d, MP: %d, ATK: %d, DEF: %d, MAG: %d, SPR: %d\n",
zero_se_soglia(statp->hp, soglia),
zero_se_soglia(statp->mp, soglia),
zero_se_soglia(statp->atk, soglia),
zero_se_soglia(statp->def, soglia),
zero_se_soglia(statp->mag, soglia),
zero_se_soglia(statp->spr, soglia));
}
void stat_copy(stat_t *a, stat_t *b) {
a->atk = b->atk;
a->def = b->def;
a->hp = b->hp;
a->mag = b->mag;
a->mp = b->mp;
a->spr = b->spr;
}
void stat_sum(stat_t *a, stat_t *b) {
a->atk += b->atk;
a->def += b->def;
a->hp += b->hp;
a->mag += b->mag;
a->mp += b->mp;
a->spr += b->spr;
}
/* funzioni di input/output di un oggetto dell'inventario */
void inv_read(FILE *fp, inv_t *invp) {
fscanf(fp, " %49s %49s", invp->nome, invp->tipo);
stat_read(fp, &(invp->stat));
}
void inv_print(FILE *fp, inv_t *invp) {
fprintf(fp, " %s (%s) - ", invp->nome, invp->tipo);
stat_print(fp, &(invp->stat),INT_MIN);
}
/* ritorna il campo stat di un oggetto dell'inventario */
stat_t inv_getStat(inv_t *invp) {
return invp->stat;
}
/* Si possono aggiungere altre funzioni se ritenute necessarie */
#endif

View File

@@ -0,0 +1,42 @@
// Laboratorio 7 - Esercizio 1 - inv.h
// Matteo Schiff - s295565
#ifndef INV_H_DEFINED
#define INV_H_DEFINED
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#define LEN 50
#define MIN_STAT 1
/* quasi ADT statistiche */
typedef struct stat_s {
int hp, mp, atk, def, mag, spr;
} stat_t;
/* quasi ADT oggetto di inventario */
typedef struct inv_s {
char nome[LEN];
char tipo[LEN];
stat_t stat;
} inv_t;
/* funzioni di input/output delle statistiche */
void stat_read(FILE *fp, stat_t *statp);
void stat_print(FILE *fp, stat_t *statp, int soglia);
void stat_copy(stat_t *a, stat_t *b);
void stat_sum(stat_t *a, stat_t *b);
/* funzioni di input/output di un oggetto dell'inventario */
void inv_read(FILE *fp, inv_t *invp);
void inv_print(FILE *fp, inv_t *invp);
/* ritorna il campo stat di un oggetto dell'inventario */
stat_t inv_getStat(inv_t *invp);
/* Si possono aggiungere altre funzioni se ritenute necessarie */
#endif

View File

@@ -0,0 +1,75 @@
// Laboratorio 7 - Esercizio 1 - invArray.c
// Matteo Schiff - s295565
#ifndef INVARRAY_C_DEFINED
#define INVARRAY_C_DEFINED
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "inv.h"
typedef struct invArray_s {
int N;
inv_t *array;
} *invArray_t;
/* creatore e disruttore */
invArray_t invArray_init() {
invArray_t new = malloc(sizeof(struct invArray_s));
new->N = 0;
new->array = NULL;
return new;
}
void invArray_free(invArray_t invArray) {
free(invArray->array);
free(invArray);
}
/* lettura e scrittura su file */
void invArray_read(FILE *fp, invArray_t invArray) {
if (fscanf(fp, " %d", &invArray->N) != 1)
return;
invArray->array = malloc(invArray->N * sizeof(inv_t));
for (int i = 0; i < invArray->N; i++) {
inv_read(fp, &invArray->array[i]);
}
}
void invArray_print(FILE *fp, invArray_t invArray) {
for (int i = 0; i < invArray->N; i++) {
inv_print(fp, &invArray->array[i]);
}
}
void invArray_printByIndex(FILE *fp, invArray_t invArray, int index) {
if (index >= invArray->N)
return;
inv_print(fp, &invArray->array[index]);
}
/* ritorna puntatore a oggetto selezionato da indice (nel vettore) */
inv_t *invArray_getByIndex(invArray_t invArray, int index) {
if (index >= invArray->N)
return NULL;
return &(invArray->array[index]);
}
/* ritorna indice (nel vettore) a oggetto selezionato da nome */
int invArray_searchByName(invArray_t invArray, char *name) {
for (int i = 0; i < invArray->N; i++) {
if (!strcmp(invArray->array[i].nome, name))
return i;
}
return -1;
}
/* Si possono aggiungere altre funzioni se ritenute necessarie */
#endif

View File

@@ -0,0 +1,31 @@
// Laboratorio 7 - Esercizio 1 - invArray.h
// Matteo Schiff - s295565
#ifndef INVARRAY_H_DEFINED
#define INVARRAY_H_DEFINED
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "inv.h"
/* ADT di prima classe collezione di oggetti di inventario */
typedef struct invArray_s *invArray_t;
/* creatore e disruttore */
invArray_t invArray_init();
void invArray_free(invArray_t invArray);
/* lettura e scrittura su file */
void invArray_read(FILE *fp, invArray_t invArray);
void invArray_print(FILE *fp, invArray_t invArray);
/* ritorna puntatore a oggetto selezionato da indice (nel vettore) */
void invArray_printByIndex(FILE *fp, invArray_t invArray, int index);
inv_t *invArray_getByIndex(invArray_t invArray, int index);
/* ritorna indice (nel vettore) a oggetto selezionato da nome */
int invArray_searchByName(invArray_t invArray, char *name);
/* Si possono aggiungere altre funzioni se ritenute necessarie */
#endif

View File

@@ -0,0 +1,16 @@
15
Excalibur Spada2M 0 0 120 0 0 50
Filatterio Accessorio -100 20 -30 -30 25 25
ArmillaDiDiamante Accessorio 0 0 25 0 25
Escutcheon Scudo 1000 50 0 75 0 0
MantoElfico Vesti 0 50 0 10 10 10
Pendragon Scudo 250 0 0 45 0 30
Oricalco Reliquia 0 0 0 0 15 15
TalismanoNero Accessorio -500 150 0 0 100 50
AmmazzaDraghi Spada2M 0 0 80 -20 0 -20
Fiocco Accessorio 0 0 1 1 1 1
CorazzaAdamantina ArmaturaPesante 3333 333 -15 33 -15 33
DagaRunica Pugnale 0 50 10 0 35 0
Tempesta Spada1M 0 0 40 0 -5 0
Maximillian ArmaturaLeggera 500 0 0 30 0 15
Ametista Reliquia 0 0 15 15 0 0

View File

@@ -0,0 +1,58 @@
// Laboratorio 7 - Esercizio 1 - pg.c
// Matteo Schiff - s295565
#ifndef PG_C_DEFINED
#define PG_C_DEFINED
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "equipArray.h"
#include "pg.h"
void pg_calc_stats(pg_t *pgp, invArray_t invArray)
{
stat_copy(&pgp->eq_stat, &pgp->b_stat);
for (int i = 0; i < equipArray_inUse(pgp->equip); i++) {
int index = equipArray_getEquipByIndex(pgp->equip, i);
inv_t *item = invArray_getByIndex(invArray, index);
stat_sum(&pgp->eq_stat, &item->stat);
}
}
/* lettura e scrittura su file */
int pg_read(FILE *fp, pg_t *pgp)
{
if (fscanf(fp, " %49s %49s %49s", pgp->cod, pgp->nome, pgp->classe) != 3)
return 0;
stat_read(fp, &(pgp->b_stat));
pgp->equip = equipArray_init();
stat_copy(&pgp->eq_stat, &pgp->b_stat);
return 1;
}
/* non essendo struct dinamica, pulisce chiamando il distruttore di equipArray */
void pg_clean(pg_t *pgp)
{
free(pgp->equip);
}
void pg_print(FILE *fp, pg_t *pgp, invArray_t invArray)
{
fprintf(fp, "%s (%s)\n Classe: %s\n Statistiche - ", pgp->nome, pgp->cod, pgp->classe);
stat_print(fp, &(pgp->eq_stat), 0);
equipArray_print(fp, pgp->equip, invArray);
}
/* modifica personaggio aggiungendo/togliendo un equipaggiamento selezionato da inventario:
di fatto e' sufficiente chiamare l'opportuna funzione dal modulo equipArray */
void pg_updateEquip(pg_t *pgp, invArray_t invArray)
{
equipArray_update(pgp->equip, invArray);
pg_calc_stats(pgp, invArray);
}
/* Si possono aggiungere altre funzioni se ritenute necessarie */
#endif

View File

@@ -0,0 +1,35 @@
// Laboratorio 7 - Esercizio 1 - pg.h
// Matteo Schiff - s295565
#ifndef PG_H_DEFINED
#define PG_H_DEFINED
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "equipArray.h"
/* quasi ADT personaggio; si noti che si tratta di un composto con riferimento
a un equipArray di proprieta' */
typedef struct pg_s {
char cod[LEN];
char nome[LEN];
char classe[LEN];
stat_t b_stat, eq_stat;
equipArray_t equip;
} pg_t;
/* lettura e scrittura su file */
int pg_read(FILE *fp, pg_t *pgp);
/* non essendo struct dinamica, pulisce chiamando il distruttire di equipArray */
void pg_clean(pg_t *pgp);
void pg_print(FILE *fp, pg_t *pgp, invArray_t invArray);
/* modifica personaggio aggiungendo/togliendo un equipaggiamento selezionato da inventario:
di fatto e' sufficiente chiamare l'opportuna funzione dal modulo equipArray */
void pg_updateEquip(pg_t *pgp, invArray_t invArray);
/* Si possono aggiungere altre funzioni se ritenute necessarie */
#endif

View File

@@ -0,0 +1,10 @@
PG0001 Sephiroth Guerriero 1832 71 116 65 41 49
PG0002 Aerith MagoBianco 976 144 12 39 121 140
PG0003 Vivi MagoNero 1001 136 17 36 131 115
PG0004 Beatrix Templare 1654 99 85 35 70 61
PG0005 Orlandeau Paladino 1701 84 81 68 34 48
PG0006 Basch Capitano 2199 46 32 98 33 89
PG0007 Lulu MagoNero 999 139 21 33 119 117
PG0008 Yuna Evocatrice 1019 100 32 17 97 99
PG0009 DarkCecil CavaliereNero 1901 48 106 90 12 18
PG0010 Kefka Arcimago 1271 89 39 47 89 64

View File

@@ -0,0 +1,131 @@
// Laboratorio 7 - Esercizio 1 - pgList.c
// Matteo Schiff - s295565
#ifndef PGLIST_C_DEFINED
#define PGLIST_C_DEFINED
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "pgList.h"
typedef struct node_s *link;
typedef struct node_s {
pg_t val;
link next;
} node;
/* ADT di prima classe collezione di personaggi */
typedef struct pgList_s {
link head;
link tail;
int nPg;
} *pgList_t;
link new_node(pg_t val, link next) {
link t = malloc(sizeof(node));
if (t == NULL) {
printf("ERROR: out of memory");
exit(2);
}
t->val = val;
t->next = next;
return t;
}
void free_node(link p) {
pg_clean(&p->val);
free(p);
}
/* creatore e distruttore */
pgList_t pgList_init() {
pgList_t new = malloc(sizeof(struct pgList_s));
new->head = NULL;
new->tail = NULL;
new->nPg = 0;
return new;
}
void pgList_free(pgList_t pgList) {
link p, x;
for (p = pgList->head, x = pgList->head->next; x != NULL; p = x, x = x->next){
free_node(p);
}
free(pgList);
}
/* lettura e scrittura su file */
void pgList_read(FILE *fp, pgList_t pgList) {
while (!feof(fp))
{
pg_t pgp;
if (pg_read(fp, &pgp) != 0) {
pgList_insert(pgList, pgp);
}
}
}
void pgList_print(FILE *fp, pgList_t pgList, invArray_t invArray) {
link p;
for (p = pgList->head; p != NULL; p = p->next) {
pg_print(fp, &(p->val), invArray);
}
}
/* inserimento di un nuovo personaggio */
void pgList_insert(pgList_t pgList, pg_t pg) {
link new = new_node(pg, NULL);
if (pgList->head == NULL) {
pgList->head = new;
} else {
pgList->tail->next = new;
}
pgList->tail = new;
}
/* cancellazione con rimozione */
void pgList_remove(pgList_t pgList, char* cod) {
link p, x;
if (pgList->head == NULL)
return;
for (x = pgList->head, p = NULL; x != NULL; p = x, x = x->next) {
if (!strcmp(x->val.cod, cod)) {
if (p == NULL) {
pgList->head = x->next;
} else {
p->next = x->next;
// se tolgo l'ultimo elemento devo aggiornare `tail`
if (x->next == NULL)
pgList->tail = p;
}
free_node(x);
break;
}
}
}
/* ricerca per codice, ritornando il puntatore */
pg_t *pgList_searchByCode(pgList_t pgList, char* cod) {
link p;
for (p = pgList->head; p != NULL; p = p->next) {
if (!strcmp(p->val.cod, cod)) {
return &(p->val);
}
}
return NULL;
}
/* Si possono aggiungere altre funzioni se ritenute necessarie */
#endif

View File

@@ -0,0 +1,33 @@
// Laboratorio 7 - Esercizio 1 - pgList.h
// Matteo Schiff - s295565
#ifndef PGLIST_H_DEFINED
#define PGLIST_H_DEFINED
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "pg.h"
/* ADT di prima classe collezione di personaggi */
typedef struct pgList_s *pgList_t;
/* creatore e distruttore */
pgList_t pgList_init();
void pgList_free(pgList_t pgList);
/* lettura e scrittura su file */
void pgList_read(FILE *fp, pgList_t pgList);
void pgList_print(FILE *fp, pgList_t pgList, invArray_t invArray);
/* inserimento di un nuovo personaggio */
void pgList_insert(pgList_t pgList, pg_t pg);
/* cancellazione con rimozione */
void pgList_remove(pgList_t pgList, char* cod);
/* ricerca per codice, ritornando il puntatore */
pg_t *pgList_searchByCode(pgList_t pgList, char* cod);
/* Si possono aggiungere altre funzioni se ritenute necessarie */
#endif

View File

@@ -0,0 +1,73 @@
// Laboratorio 7 - Esercizio 2 - Diagonali.c
// Matteo Schiff - s295565
#include <stdlib.h>
#include "Elementi.h"
#include "Diagonali.h"
typedef struct node_s *link;
typedef struct node_s {
Diagonale diag;
link next;
} node;
typedef struct diagonali
{
link head;
int N;
} *Diagonali;
link new_node(Diagonale diag, link next) {
link t = malloc(sizeof(node));
if (t == NULL) {
printf("Errore: impossibile allocare memoria");
exit(2);
}
t->diag = diag;
t->next = next;
return t;
}
void free_node(link p) {
free(p);
}
/* creatore e distruttore */
Diagonali DiagionaliInit() {
Diagonali new = malloc(sizeof(struct diagonali));
new->head = NULL;
new->N = 0;
return new;
}
void DiagonaliFree(Diagonali diags) {
link p, x;
for (p = diags->head, x = diags->head->next; x != NULL; p = x, x = x->next){
free_node(p);
}
free(diags);
}
void DiagonaliInsert(Diagonali diags, Diagonale newDiag) {
link nd = new_node(newDiag, diags->head);
diags->head = nd;
diags->N++;
}
link DiagonaliTraverse(Diagonali diags, link prev, Diagonale ** elem) {
link next;
if (prev == NULL) {
next = diags->head;
} else {
next = prev->next;
}
if (next == NULL)
return NULL;
*elem = &next->diag;
return next;
}

View File

@@ -0,0 +1,27 @@
// Laboratorio 7 - Esercizio 2 - Diagonali.h
// Matteo Schiff - s295565
#ifndef DIAG_H_DEFINED
#define DIAG_H_DEFINED
#include "Elementi.h"
#include <stdbool.h>
#define MAX_ELEM 5
typedef struct node_s *link;
typedef struct diagonali *Diagonali;
typedef struct diagonale {
Elemento elementi[MAX_ELEM];
int N;
float punti;
int diff;
bool hasFront;
bool hasBack;
bool hasSeq;
} Diagonale;
Diagonali DiagionaliInit();
void DiagonaliFree(Diagonali diags);
void DiagonaliInsert(Diagonali diags, Diagonale newDiag);
link DiagonaliTraverse(Diagonali diags, link prev, Diagonale ** elem);
#endif

View File

@@ -0,0 +1,11 @@
// Laboratorio 7 - Esercizio 2 - Elementi.c
// Matteo Schiff - s295565
#include<stdio.h>
#include"Elementi.h"
Elemento leggiElemento(FILE * fp) {
Elemento e;
fscanf(fp, "%s %d %d %d %d %d %f %d", e.nome, &e.tipo, &e.dirIngresso, &e.dirUscita, (int *) &e.reqPreced, (int *) &e.finale, &e.valore, &e.diff);
return e;
}

View File

@@ -0,0 +1,25 @@
// Laboratorio 7 - Esercizio 2 - Elementi.h
// Matteo Schiff - s295565
#ifndef ELEM_H_DEFINED
#define ELEM_H_DEFINED
#include<stdbool.h>
#include<stdio.h>
#define MAX_LEN 30
enum tipo { TRANSIZIONE, INDIETRO, AVANTI };
enum direzione { SPALLE, FRONTE };
typedef struct elemento {
char nome[MAX_LEN+1];
int tipo;
int dirIngresso;
int dirUscita;
bool reqPreced;
bool finale;
float valore;
int diff;
} Elemento;
Elemento leggiElemento(FILE * fp);
#endif

View File

@@ -0,0 +1,20 @@
19
ruota 0 1 0 0 0 0.0 1
rondata 0 1 0 0 0 0.2 1
ribaltata_a_2 0 1 1 0 0 0.25 2
back_handspring 0 0 0 0 0 0.4 2
front_tuck 2 1 1 0 0 1.75 3
front_pike 2 1 1 0 0 2.0 4
front_layout 2 1 1 0 0 2.25 5
back_tuck 1 0 0 0 0 1.75 3
back_pike 1 0 0 0 0 2.0 4
back_layout 1 0 0 0 0 2.25 5
double_front_tuck 2 1 1 1 0 3.0 6
double_front_layout 2 1 1 1 1 4.0 7
double_back_tuck 1 0 0 1 0 3.0 6
double_back_layout 1 0 0 1 1 4.0 7
triple_front_tuck 2 1 1 1 1 6.5 8
triple_back_tuck 1 0 0 1 1 6.0 8
back_layout_double_twist 1 0 0 1 0 8.0 9
back_layout_quad_twist 1 0 0 1 1 12.0 10
arabian 1 0 1 0 0 2.5 4

View File

@@ -0,0 +1,189 @@
// Laboratorio 7 - Esercizio 2 - main.c
// Matteo Schiff - s295565
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include "Elementi.h"
#include "Diagonali.h"
Elemento *leggiFile(char *filename, int *N)
{
FILE *fin;
if ((fin = fopen(filename, "r")) == NULL)
{
puts("Impossibile aprire il file");
return NULL;
}
fscanf(fin, "%d", N);
Elemento *lista = malloc(*N * sizeof(Elemento));
for (int i = 0; i < *N; i++)
{
lista[i] = leggiElemento(fin);
}
fclose(fin);
return lista;
}
float calcolaPunti(Diagonale diag)
{
float p = 0;
for (int i = 0; i < diag.N; i++)
{
p += diag.elementi[i].valore;
}
return p;
}
void generaDiagonaleR(Diagonale tmp, Elemento *scelte, int N_scelte, int max_len, int DD, Diagonali diags)
{
if (tmp.N > 0 && tmp.N <= max_len)
{
bool el_acr = false;
tmp.hasBack = false;
tmp.hasFront = false;
tmp.hasSeq = false;
for (int i = 0; i < tmp.N; i++)
{
if (tmp.elementi[i].tipo == AVANTI)
{
el_acr = true;
tmp.hasFront = true;
}
if (tmp.elementi[i].tipo == INDIETRO)
{
el_acr = true;
tmp.hasBack = true;
}
}
for (int i = 0; i<tmp.N-1 && !tmp.hasSeq;i++) {
if (tmp.elementi[i].tipo != TRANSIZIONE && tmp.elementi[i+1].tipo != TRANSIZIONE)
tmp.hasSeq = true;
}
if (el_acr)
{
tmp.punti = calcolaPunti(tmp);
DiagonaliInsert(diags, tmp);
}
}
if (tmp.N == max_len || (tmp.N > 0 && tmp.elementi[tmp.N - 1].finale))
{
return;
}
for (int i = 0; i < N_scelte; i++)
{
// Se devo mettere il primo elemento
if (tmp.N == 0)
{
if (scelte[i].reqPreced == true || scelte[i].dirIngresso == SPALLE)
continue;
}
else
{
if (scelte[i].dirIngresso != tmp.elementi[tmp.N - 1].dirUscita)
continue;
}
if (tmp.diff + scelte[i].diff > DD)
continue;
tmp.elementi[tmp.N++] = scelte[i];
tmp.diff += scelte[i].diff;
generaDiagonaleR(tmp, scelte, N_scelte, max_len, DD, diags);
tmp.diff -= scelte[i].diff;
tmp.N--;
}
}
Diagonali generaDiagonaliValide(Elemento *elementi, int N, int DD)
{
Diagonali set = DiagionaliInit();
Diagonale tmp;
tmp.diff = 0;
tmp.N = 0;
generaDiagonaleR(tmp, elementi, N, 5, DD, set);
return set;
}
void trovaProgrammaMiglioreR(Diagonali diag, int c, Diagonale **sel, float *max, Diagonale **res, int DP, int diff)
{
if (c == 3)
{
bool hasFront = sel[0]->hasFront || sel[1]->hasFront || sel[2]->hasFront;
bool hasBack = sel[0]->hasBack || sel[1]->hasBack || sel[2]->hasBack;
bool hasSeq = sel[0]->hasSeq || sel[1]->hasSeq || sel[2]->hasSeq;
float puntiUltimaDiag = (sel[2]->elementi[sel[2]->N - 1].valore >= 8) ? sel[2]->punti * 1.5 : sel[2]->punti;
float points = sel[0]->punti + sel[1]->punti + puntiUltimaDiag;
if (points > *max && diff <= DP && hasFront && hasBack && hasSeq)
{
*max = points;
res[0] = sel[0];
res[1] = sel[1];
res[2] = sel[2];
}
return;
}
link p = NULL;
Diagonale *curr;
do
{
p = DiagonaliTraverse(diag, p, &curr);
if (curr->diff + diff > DP)
continue;
sel[c] = curr;
diff += curr->diff;
trovaProgrammaMiglioreR(diag, c + 1, sel, max, res, DP, diff);
diff -= curr->diff;
} while (p != NULL);
}
void stampaDiagonale(Diagonale *diag)
{
printf("Diagonale: [punti=%f], [difficoltà=%d] -", diag->punti, diag->diff);
for (int i = 0; i < diag->N; i++)
{
printf(" %s", diag->elementi[i].nome);
}
putchar('\n');
}
void trovaProgrammaMigliore(Diagonali diags, int DP)
{
float max = 0;
Diagonale *sel[3];
Diagonale *res[3];
trovaProgrammaMiglioreR(diags, 0, sel, &max, res, DP, 0);
printf("Massimo valore: %f\n", max);
stampaDiagonale(res[0]);
stampaDiagonale(res[1]);
stampaDiagonale(res[2]);
}
int main()
{
int N = 0, DP, DD;;
Elemento *l = leggiFile("elementi.txt", &N);
printf("Inserisci DD e DP: ");
scanf("%d %d", &DD, &DP);
Diagonali diags = generaDiagonaliValide(l, N, DD);
trovaProgrammaMigliore(diags, DP);
DiagonaliFree(diags);
free(l);
return 0;
}

View File

@@ -0,0 +1,59 @@
--- Test Case #1 ---
DD = 10 DP = 20
TOT = 17.800
DIAG #1 > 1.750
front_tuck
DIAG #2 > 3.750
front_tuck front_pike
DIAG #3 > 8.200 * 1.5 (BONUS)
rondata back_layout_double_twist
--- Test Case #2 ---
DD = 7 DP = 30
TOT = 11.200
DIAG #1 > 3.700
rondata back_tuck back_tuck
DIAG #2 > 3.750
front_tuck front_pike
DIAG #3 > 3.750
front_tuck front_pike
--- Test Case #3 ---
DD = 10 DP = 35
TOT = 26.250
DIAG #1 > 5.750
front_tuck double_front_layout
DIAG #2 > 8.200
rondata back_layout_double_twist
DIAG #3 > 8.200 * 1.5 (BONUS)
rondata back_layout_double_twist
--- Test Case #4 ---
DD = 12 DP = 28
TOT = 34.000
DIAG #1 > 12.200
rondata back_layout_quad_twist
DIAG #2 > 3.500
front_tuck front_tuck
DIAG #3 > 12.200 * 1.5 (BONUS)
rondata back_layout_quad_twist
--- Test Case #5 ---
DD = 12 DP = 30
TOT = 34.950
DIAG #1 > 4.450
rondata arabian front_tuck
DIAG #2 > 12.200
rondata back_layout_quad_twist
DIAG #3 > 12.200 * 1.5 (BONUS)
rondata back_layout_quad_twist
--- Test Case #6 ---
DD = 11 DP = 33
TOT = 38.750
DIAG #1 > 12.200
rondata back_layout_quad_twist
DIAG #2 > 8.250
front_tuck triple_front_tuck
DIAG #3 > 12.200 * 1.5 (BONUS)
rondata back_layout_quad_twist

View File

@@ -0,0 +1,11 @@
// Laboratorio 8 - Esercizio 1 - Elementi.c
// Matteo Schiff - s295565
#include<stdio.h>
#include"Elementi.h"
Elemento leggiElemento(FILE * fp) {
Elemento e;
fscanf(fp, "%s %d %d %d %d %d %f %d", e.nome, &e.tipo, &e.dirIngresso, &e.dirUscita, (int *) &e.reqPreced, (int *) &e.finale, &e.valore, &e.diff);
return e;
}

View File

@@ -0,0 +1,25 @@
// Laboratorio 8 - Esercizio 1 - Elementi.h
// Matteo Schiff - s295565
#ifndef ELEM_H_DEFINED
#define ELEM_H_DEFINED
#include<stdbool.h>
#include<stdio.h>
#define MAX_LEN 30
enum tipo { TRANSIZIONE, INDIETRO, AVANTI };
enum direzione { SPALLE, FRONTE };
typedef struct elemento {
char nome[MAX_LEN+1];
int tipo;
int dirIngresso;
int dirUscita;
bool reqPreced;
bool finale;
float valore;
int diff;
} Elemento;
Elemento leggiElemento(FILE * fp);
#endif

View File

@@ -0,0 +1,20 @@
19
ruota 0 1 0 0 0 0.0 1
rondata 0 1 0 0 0 0.2 1
ribaltata_a_2 0 1 1 0 0 0.25 2
back_handspring 0 0 0 0 0 0.4 2
front_tuck 2 1 1 0 0 1.75 3
front_pike 2 1 1 0 0 2.0 4
front_layout 2 1 1 0 0 2.25 5
back_tuck 1 0 0 0 0 1.75 3
back_pike 1 0 0 0 0 2.0 4
back_layout 1 0 0 0 0 2.25 5
double_front_tuck 2 1 1 1 0 3.0 6
double_front_layout 2 1 1 1 1 4.0 7
double_back_tuck 1 0 0 1 0 3.0 6
double_back_layout 1 0 0 1 1 4.0 7
triple_front_tuck 2 1 1 1 1 6.5 8
triple_back_tuck 1 0 0 1 1 6.0 8
back_layout_double_twist 1 0 0 1 0 8.0 9
back_layout_quad_twist 1 0 0 1 1 12.0 10
arabian 1 0 1 0 0 2.5 4

View File

@@ -0,0 +1,345 @@
// Laboratorio 8 - Esercizio 1 - main.c
// Matteo Schiff - s295565
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include "Elementi.h"
#define MAX_ELEM 5
#define MAX_DIAG 3
typedef struct params
{
bool acrobNecessaria;
bool acrobAvantiNecessaria;
bool acrobIndietroNecessaria;
} Requirements;
Elemento *leggiFile(char *filename, int *N)
{
FILE *fin;
if ((fin = fopen(filename, "r")) == NULL)
{
puts("Impossibile aprire il file");
return NULL;
}
fscanf(fin, "%d", N);
Elemento *lista = malloc(*N * sizeof(Elemento));
for (int i = 0; i < *N; i++)
{
lista[i] = leggiElemento(fin);
}
fclose(fin);
return lista;
}
float calcElementValue(Elemento e, Requirements reqs, bool acrobInSeqNecessaria)
{
float value = (e.valore / e.diff);
if (e.tipo == AVANTI && reqs.acrobAvantiNecessaria)
{
value += 1;
}
if (e.tipo == INDIETRO && reqs.acrobIndietroNecessaria)
{
value += 1;
}
if (e.tipo > 0 && reqs.acrobNecessaria)
{
value += 1;
}
if (e.tipo > 0 && acrobInSeqNecessaria)
{
value += 1;
}
return value;
}
// variabili passate come contesto alla funzione di confronto chiamata da qsort
Requirements context;
bool acrobInSeqNecessariaSort;
int greedyChoice(const void *a, const void *b)
{
Elemento x = *(Elemento *)a;
Elemento y = *(Elemento *)b;
float va = calcElementValue(x, context, acrobInSeqNecessariaSort);
float vb = calcElementValue(y, context, acrobInSeqNecessariaSort);
return vb > va;
}
void swap(int *a, int *b)
{
int c = *a;
*a = *b;
*b = c;
}
void swapE(Elemento *a, Elemento *b)
{
Elemento c = *a;
*a = *b;
*b = c;
}
void sortAccettabili(Elemento *accettabili, int N, Requirements *reqs, bool acrobInSeqNecessaria)
{
context = *reqs;
acrobInSeqNecessariaSort = acrobInSeqNecessaria;
qsort(accettabili, N, sizeof(Elemento), greedyChoice);
}
int getAccettabili(Elemento *accettabili, Elemento *elementi, int N, int DD, int DP, Elemento *soluzione, int posizioneAssoluta, int posInDiag, int currKp, int diffDiags[MAX_DIAG], int diffTot)
{
int N_accettabili = 0;
for (int i = 0; i < N; i++)
{
if (diffDiags[currKp] + elementi[i].diff > DD || diffTot + elementi[i].diff > DP)
continue;
if (posInDiag == 0 && elementi[i].dirIngresso != FRONTE)
continue;
if (posInDiag > 0 && elementi[i].dirIngresso != soluzione[posizioneAssoluta - 1].dirUscita)
continue;
if (posInDiag == 0 && elementi[i].reqPreced)
continue;
accettabili[N_accettabili++] = elementi[i];
}
return N_accettabili;
}
void stampaSoluzione(Elemento *soluzione, int *diagSize)
{
float totPoints = 0, diagPoints;
for (int i = 0; i < MAX_DIAG; i++)
{
diagPoints = 0;
for (int j = 0; j < diagSize[i]; j++)
{
diagPoints += soluzione[i * MAX_ELEM + j].valore;
}
printf("DIAG #%d > %.3f", i + 1, diagPoints);
if (i == MAX_DIAG - 1 && soluzione[diagSize[i] + i * MAX_ELEM - 1].diff >= 8)
{
printf(" * 1.5 (BONUS)");
diagPoints *= 1.5;
}
printf("\n");
totPoints += diagPoints;
for (int j = 0; j < diagSize[i]; j++)
{
printf("%s ", soluzione[i * MAX_ELEM + j].nome);
}
printf("\n");
}
printf("TOT = %.3f\n", totPoints);
}
void trovaProgrammaGreedy(Elemento *elementi, int N, int DD, int DP)
{
int diffDiags[MAX_DIAG] = {0};
int tmp, minDiffAvanti = DD, minDiffIndietro = DD;
Requirements reqs[MAX_DIAG];
bool found;
bool contieneElemFinale[MAX_DIAG];
bool acrobInSeqNecessaria = true;
for (int i = 0; i < N; i++)
{
if (elementi[i].diff < minDiffAvanti && elementi[i].tipo == AVANTI)
minDiffAvanti = elementi[i].diff;
if (elementi[i].diff < minDiffIndietro && elementi[i].tipo == INDIETRO)
minDiffIndietro = elementi[i].diff;
}
for (int i = 0; i < MAX_DIAG; i++)
{
contieneElemFinale[i] = false;
reqs[i].acrobAvantiNecessaria = reqs[i].acrobIndietroNecessaria = reqs[i].acrobNecessaria = true;
}
int *diagSize = (int *)malloc(MAX_DIAG * sizeof(int));
for (int i = 0; i < MAX_DIAG; i++)
diagSize[i] = 0;
Elemento *soluzione = (Elemento *)malloc(MAX_DIAG * MAX_ELEM * sizeof(Elemento));
Elemento *accettabili = (Elemento *)malloc(N * sizeof(Elemento));
int diffTot = 0;
for (int numElem = 0; numElem < MAX_ELEM; numElem++)
{
for (int numDiag = 0; numDiag < MAX_DIAG; numDiag++)
{
int posizioneAssoluta = numElem + numDiag * MAX_ELEM;
if (!contieneElemFinale[numDiag])
{
int numAcc = getAccettabili(accettabili, elementi, N, DD, DP, soluzione, posizioneAssoluta, numElem, numDiag, diffDiags, diffTot);
if (numAcc > 0)
{
// Ordinamento descrescente delle scelte possibili
sortAccettabili(accettabili, numAcc, &reqs[numDiag], acrobInSeqNecessaria);
if (reqs[numDiag].acrobAvantiNecessaria != reqs[numDiag].acrobIndietroNecessaria)
{
found = false;
if (reqs[numDiag].acrobAvantiNecessaria)
{
for (int i = 0; i < numAcc && !found; i++)
{
// Scelgo la prima diagonale che soddisfa la condizione
if (accettabili[i].tipo == AVANTI)
{
found = true;
soluzione[posizioneAssoluta] = accettabili[i];
diagSize[numDiag]++;
}
}
if (!found)
{
for (int i = 0; i < numAcc && !found; i++)
{
// "cambio" la direzione in uscita dell'ultimo elemento in modo che nell'iterazione dopo si possa provare ad inserire un elemento acrobatico
if (accettabili[i].dirIngresso != accettabili[i].dirUscita && diffDiags[numDiag] + accettabili[i].diff + minDiffAvanti <= DD && !accettabili[i].finale)
{
soluzione[posizioneAssoluta] = accettabili[i];
diagSize[numDiag]++;
found = true;
// voglio vincolare l'inserimento della acrobazia nell'iterazione successiva (rispetto alle posizioni degli elementi) a questa diagonale
for (tmp = 0; tmp < MAX_DIAG; tmp++)
reqs[tmp].acrobAvantiNecessaria = false;
reqs[numDiag].acrobAvantiNecessaria = true;
}
}
if (!found)
{
// Effettuo la scelta localmente ottima
soluzione[posizioneAssoluta] = accettabili[0];
diagSize[numDiag]++;
}
}
}
if (reqs[numDiag].acrobIndietroNecessaria)
{
for (int i = 0; i < numAcc && !found; i++)
{
if (accettabili[i].tipo == INDIETRO)
{
found = true;
// Effettuo la scelta localmente ottima
soluzione[posizioneAssoluta] = accettabili[i];
diagSize[numDiag]++;
}
}
if (!found)
{
found = false;
for (int i = 0; i < numAcc && !found; i++)
{
if (accettabili[i].dirIngresso != accettabili[i].dirUscita && diffDiags[numDiag] + accettabili[i].diff + minDiffIndietro <= DD && !accettabili[i].finale)
{
soluzione[posizioneAssoluta] = accettabili[i];
diagSize[numDiag]++;
for (tmp = 0; tmp < MAX_DIAG; tmp++)
reqs[tmp].acrobIndietroNecessaria = false;
reqs[numDiag].acrobIndietroNecessaria = true;
found = true;
}
}
if (!found)
{
// Effettuo scelta localmente ottima
soluzione[posizioneAssoluta] = accettabili[0];
diagSize[numDiag]++;
}
}
}
}
else
{
// Effettuo scelta localmente ottima
soluzione[posizioneAssoluta] = accettabili[0];
diagSize[numDiag]++;
}
// Aggiorno le difficoltà di ogni diagonale
diffDiags[numDiag] += soluzione[posizioneAssoluta].diff;
diffTot += soluzione[posizioneAssoluta].diff;
// Aggiorno i parametri della funzione obiettivo
if (soluzione[posizioneAssoluta].tipo == AVANTI)
{
for (int i = 0; i < MAX_DIAG; i++)
reqs[i].acrobAvantiNecessaria = false;
}
if (soluzione[posizioneAssoluta].tipo == INDIETRO)
{
for (int i = 0; i < MAX_DIAG; i++)
reqs[i].acrobIndietroNecessaria = false;
}
if (numElem > 0 && soluzione[posizioneAssoluta].tipo > 0 && soluzione[posizioneAssoluta - 1].tipo > 0)
{
acrobInSeqNecessaria = false;
}
if (soluzione[posizioneAssoluta].finale)
{
// Blocco l'inserimento di elementi nella diagonale
contieneElemFinale[numDiag] = true;
}
}
}
}
}
// Cerco la diagonale con l'elemento che permette di ottenere il bonus
int bonusDiag = -1;
for (int numDiag = 0; numDiag < MAX_DIAG; numDiag++)
{
if (soluzione[diagSize[numDiag] + numDiag * MAX_ELEM - 1].diff >= 8)
bonusDiag = numDiag;
}
// Sposto se ho trovato una diagonale idonea al bonus che non è già in ultima posizione
if (bonusDiag != -1 && bonusDiag != MAX_DIAG - 1)
{
swap(&diagSize[MAX_DIAG - 1], &diagSize[bonusDiag]);
for (int i = 0; i < MAX_ELEM; i++)
swapE(&soluzione[i + (MAX_DIAG - 1) * MAX_ELEM], &soluzione[i + bonusDiag * MAX_ELEM]);
}
stampaSoluzione(soluzione, diagSize);
free(accettabili);
free(soluzione);
free(diagSize);
return;
}
int main()
{
int N = 0, DP, DD;
;
Elemento *l = leggiFile("elementi.txt", &N);
printf("Inserisci DD e DP: ");
scanf("%d %d", &DD, &DP);
trovaProgrammaGreedy(l, N, DD, DP);
free(l);
return 0;
}

View File

@@ -0,0 +1,297 @@
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include "Elementi.h"
#define MAX_ELEM 5
#define MAX_DIAG 3
typedef struct params {
bool acrobNecessaria;
bool acrobAvantiNecessaria;
bool acrobIndietroNecessaria;
} Requirements;
Elemento *leggiFile(char *filename, int *N)
{
FILE *fin;
if ((fin = fopen(filename, "r")) == NULL)
{
puts("Impossibile aprire il file");
return NULL;
}
fscanf(fin, "%d", N);
Elemento *lista = malloc(*N * sizeof(Elemento));
for (int i = 0; i < *N; i++)
{
lista[i] = leggiElemento(fin);
}
fclose(fin);
return lista;
}
float calcElementValue(Elemento e, Requirements reqs, bool acrobInSeqNecessaria) {
float value = (e.valore / e.diff);
if (e.tipo == AVANTI && reqs.acrobAvantiNecessaria) {
value += 1;
}
if (e.tipo == INDIETRO && reqs.acrobIndietroNecessaria) {
value += 1;
}
if (e.tipo > 0 && reqs.acrobNecessaria) {
value += 1;
}
if (e.tipo > 0 && acrobInSeqNecessaria) {
value += 1;
}
return value;
}
// variabili passate come contesto alla funzione di confronto chiamata da qsort
Requirements context;
bool acrobInSeqNecessariaSort;
int greedyChoice(const void *a, const void *b) {
Elemento x = *(Elemento *)a;
Elemento y = *(Elemento *)b;
float va = calcElementValue(x, context, acrobInSeqNecessariaSort);
float vb = calcElementValue(y, context, acrobInSeqNecessariaSort);
return vb > va;
}
void sortAccettabili(Elemento *accettabili, int N, Requirements *reqs, bool acrobInSeqNecessaria) {
context = *reqs;
acrobInSeqNecessariaSort = acrobInSeqNecessaria;
qsort(accettabili, N, sizeof(Elemento), greedyChoice);
}
int getAccettabili(Elemento *accettabili, Elemento *elementi, int N, int DD, int DP, Elemento *soluzione, int posizioneAssoluta, int posInDiag, int currKp, int diffDiags[MAX_DIAG], int diffTot) {
int N_accettabili = 0;
for (int i = 0; i < N; i++) {
if (diffDiags[currKp] + elementi[i].diff > DD || diffTot + elementi[i].diff > DP)
continue;
if (posInDiag == 0 && elementi[i].dirIngresso != FRONTE)
continue;
if (posInDiag > 0 && elementi[i].dirIngresso != soluzione[posizioneAssoluta-1].dirUscita)
continue;
if (posInDiag == 0 && elementi[i].reqPreced)
continue;
accettabili[N_accettabili++] = elementi[i];
}
return N_accettabili;
}
void stampaSoluzione(Elemento *sol, int N, int *kp) {
int i, j, diagonaleBonus = -1;
float tot = 0, parz;
// Ricerca possibile diagonale con elemento bonus
for (i = 0; i < MAX_DIAG && diagonaleBonus == -1; i++) {
for (j = 0; j < MAX_ELEM && diagonaleBonus == -1; j++) {
if ((kp[j + MAX_ELEM * i] == -1 || j == MAX_ELEM - 1) && sol[j + MAX_ELEM * i - 1].diff >= 8) {
diagonaleBonus = i;
}
}
}
// Scambio diagonale bonus, se trovata, con l'ultima diagonale
if (diagonaleBonus != -1 && diagonaleBonus != MAX_DIAG - 1) {
for (i = 0; i < N; i++) {
if (kp[i] == diagonaleBonus) kp[i] = MAX_DIAG;
if (kp[i] == MAX_DIAG - 1) kp[i] = diagonaleBonus;
}
for (i = 0; i < N; i++) {
if (kp[i] == MAX_DIAG) kp[i] = MAX_DIAG - 1;
}
diagonaleBonus = MAX_DIAG - 1;
}
for (j = 0; j < MAX_DIAG; j++) {
parz = 0;
for (i = 0; i < N; i++) {
if (kp[i] == j) {
parz += sol[i].valore;
}
}
printf("DIAG #%d > %.3f", j+1, parz);
if (j == diagonaleBonus)
printf(" * 1.5 (BONUS)");
printf("\n");
if (j == diagonaleBonus) {
parz = parz * 1.5;
}
tot += parz;
for (i = 0; i < N; i++) {
if (kp[i] == j) {
printf("%s ", sol[i].nome);
}
}
printf("\n");
}
printf("TOT = %.3f\n", tot);
}
void trovaProgrammaGreedy(Elemento *elementi, int N, int DD, int DP) {
int diffDiags[MAX_DIAG] = {0};
int tmp, minDiffAvanti = DD, minDiffIndietro = DD;
Requirements reqs[MAX_DIAG];
bool found;
bool contieneElemFinale[MAX_DIAG];
bool acrobInSeqNecessaria = true;
for (int i = 0; i < N; i++) {
if (elementi[i].diff < minDiffAvanti && elementi[i].tipo == AVANTI)
minDiffAvanti = elementi[i].diff;
if (elementi[i].diff < minDiffIndietro && elementi[i].tipo == INDIETRO)
minDiffIndietro = elementi[i].diff;
}
for (int i = 0; i < MAX_DIAG; i++) {
contieneElemFinale[i] = false;
reqs[i].acrobAvantiNecessaria = reqs[i].acrobIndietroNecessaria = reqs[i].acrobNecessaria = true;
}
int *kp = (int *) malloc(MAX_DIAG * MAX_ELEM * sizeof(int));
for (int i = 0; i < MAX_DIAG * MAX_ELEM; i++)
kp[i] = -1;
Elemento *soluzione = (Elemento *) malloc(MAX_DIAG * MAX_ELEM * sizeof(Elemento));
Elemento *accettabili = (Elemento *) malloc(N * sizeof(Elemento));
int diffTot = 0;
for (int numElem = 0; numElem < MAX_ELEM; numElem++) {
for (int numDiag = 0; numDiag < MAX_DIAG; numDiag++) {
int posizioneAssoluta = numElem + numDiag * MAX_ELEM;
if (!contieneElemFinale[numDiag]) {
int numAcc = getAccettabili(accettabili, elementi, N, DD, DP, soluzione, posizioneAssoluta, numElem, numDiag, diffDiags, diffTot);
if (numAcc > 0) {
// Ordinamento descrescente delle scelte possibili
sortAccettabili(accettabili, numAcc, &reqs[numDiag], acrobInSeqNecessaria);
if (reqs[numDiag].acrobAvantiNecessaria != reqs[numDiag].acrobIndietroNecessaria) {
found = false;
if (reqs[numDiag].acrobAvantiNecessaria) {
for (int i = 0; i < numAcc && !found; i++) {
// Scelgo la prima diagonale che soddisfa la condizione
if (accettabili[i].tipo == AVANTI) {
found = true;
soluzione[posizioneAssoluta] = accettabili[i];
kp[posizioneAssoluta] = numDiag;
}
}
if (!found) {
for (int i = 0; i < numAcc && !found; i++) {
if (accettabili[i].dirIngresso != accettabili[i].dirUscita && diffDiags[numDiag] + accettabili[i].diff + minDiffAvanti <= DD && !accettabili[i].finale) {
soluzione[posizioneAssoluta] = accettabili[i];
kp[posizioneAssoluta] = numDiag;
found = true;
for (tmp = 0; tmp < MAX_DIAG; tmp++)
reqs[tmp].acrobAvantiNecessaria = false;
reqs[numDiag].acrobAvantiNecessaria = true;
}
}
if (!found) {
// Effettuo scelta localmente ottima
soluzione[posizioneAssoluta] = accettabili[0];
kp[posizioneAssoluta] = numDiag;
}
}
}
if (reqs[numDiag].acrobIndietroNecessaria) {
for (int i = 0; i < numAcc && !found; i++) {
if (accettabili[i].tipo == INDIETRO) {
found = true;
// Effettuo scelta localmente ottima
soluzione[posizioneAssoluta] = accettabili[i];
kp[posizioneAssoluta] = numDiag;
}
}
if (!found) {
found = false;
for (int i = 0; i < numAcc && !found; i++) {
if (accettabili[i].dirIngresso != accettabili[i].dirUscita && diffDiags[numDiag] + accettabili[i].diff + minDiffIndietro <= DD && !accettabili[i].finale) {
soluzione[posizioneAssoluta] = accettabili[i];
kp[posizioneAssoluta] = numDiag;
for (tmp = 0; tmp < MAX_DIAG; tmp++)
reqs[tmp].acrobIndietroNecessaria = false;
reqs[numDiag].acrobIndietroNecessaria = true;
found = true;
}
}
if (!found) {
// Effettuo scelta localmente ottima
soluzione[posizioneAssoluta] = accettabili[0];
kp[posizioneAssoluta] = numDiag;
}
}
}
} else {
// Effettuo scelta localmente ottima
soluzione[posizioneAssoluta] = accettabili[0];
kp[posizioneAssoluta] = numDiag;
}
// Aggiornamento difficoltà
diffDiags[numDiag] += soluzione[posizioneAssoluta].diff;
diffTot += soluzione[posizioneAssoluta].diff;
// Aggiornamento parametri funzione obiettivo
if (soluzione[posizioneAssoluta].tipo == AVANTI) {
for (int i = 0; i < MAX_DIAG; i++)
reqs[i].acrobAvantiNecessaria = false;
reqs[numDiag].acrobIndietroNecessaria = false;
}
if (soluzione[posizioneAssoluta].tipo == INDIETRO) {
for (int i = 0; i < MAX_DIAG; i++)
reqs[i].acrobIndietroNecessaria = false;
reqs[numDiag].acrobAvantiNecessaria = false;
}
if (numElem > 0 && soluzione[posizioneAssoluta].tipo > 0 && soluzione[posizioneAssoluta-1].tipo > 0) {
for (int i = 0; i < MAX_DIAG; i++)
acrobInSeqNecessaria = false;
}
if (soluzione[posizioneAssoluta].finale) {
// Blocco l'inserimento di elementi nella diagonale
contieneElemFinale[numDiag] = true;
}
}
}
}
}
stampaSoluzione(soluzione, MAX_DIAG * MAX_ELEM, kp);
free(accettabili);
free(soluzione);
free(kp);
return;
}
int main()
{
int N = 0, DP, DD;;
Elemento *l = leggiFile("elementi.txt", &N);
printf("Inserisci DD e DP: ");
scanf("%d %d", &DD, &DP);
trovaProgrammaGreedy(l, N, DD, DP);
free(l);
return 0;
}

View File

@@ -0,0 +1,376 @@
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include "Elementi.h"
#define MAX_ELEM 5
#define MAX_DIAG 3
typedef struct params
{
bool acrobNecessaria;
} Requirements;
typedef struct gparams
{
bool acrobAvantiNecessaria;
bool acrobIndietroNecessaria;
bool acrobInSeqNecessaria;
} GlobalRequirements;
Elemento *leggiFile(char *filename, int *N)
{
FILE *fin;
if ((fin = fopen(filename, "r")) == NULL)
{
puts("Impossibile aprire il file");
return NULL;
}
fscanf(fin, "%d", N);
Elemento *lista = malloc(*N * sizeof(Elemento));
for (int i = 0; i < *N; i++)
{
lista[i] = leggiElemento(fin);
}
fclose(fin);
return lista;
}
float calcElementValue(Elemento e, Requirements reqs, GlobalRequirements greqs)
{
float value = (e.valore / e.diff);
if (e.tipo == AVANTI && greqs.acrobAvantiNecessaria)
{
value += 1;
}
if (e.tipo == INDIETRO && greqs.acrobIndietroNecessaria)
{
value += 1;
}
if (e.tipo > 0 && reqs.acrobNecessaria)
{
value += 1;
}
if (e.tipo > 0 && greqs.acrobInSeqNecessaria)
{
value += 1;
}
return value;
}
// variabili passate come contesto alla funzione di confronto chiamata da qsort
Requirements context;
GlobalRequirements gcontext;
int greedyChoice(const void *a, const void *b)
{
Elemento x = *(Elemento *)a;
Elemento y = *(Elemento *)b;
float va = calcElementValue(x, context, gcontext);
float vb = calcElementValue(y, context, gcontext);
return vb > va;
}
void swap(int *a, int *b)
{
int c = *a;
*a = *b;
*b = c;
}
void swapE(Elemento *a, Elemento *b)
{
Elemento c = *a;
*a = *b;
*b = c;
}
void sortAccettabili(Elemento *accettabili, int N, Requirements *reqs, GlobalRequirements *greqs)
{
context = *reqs;
gcontext = *greqs;
qsort(accettabili, N, sizeof(Elemento), greedyChoice);
}
int getAccettabili(Elemento *accettabili, Elemento *elementi, int N, int DD, int DP, Elemento *soluzione, int posizioneAssoluta, int posInDiag, int currKp, int diffDiags[MAX_DIAG], int diffTot)
{
int N_accettabili = 0;
for (int i = 0; i < N; i++)
{
if (diffDiags[currKp] + elementi[i].diff > DD || diffTot + elementi[i].diff > DP)
continue;
if (posInDiag == 0 && elementi[i].dirIngresso != FRONTE)
continue;
if (posInDiag > 0 && elementi[i].dirIngresso != soluzione[posizioneAssoluta - 1].dirUscita)
continue;
if (posInDiag == 0 && elementi[i].reqPreced)
continue;
accettabili[N_accettabili++] = elementi[i];
}
return N_accettabili;
}
void stampaSoluzione(Elemento *soluzione, int *diagSize)
{
float totPoints = 0, diagPoints;
for (int i = 0; i < MAX_DIAG; i++)
{
diagPoints = 0;
for (int j = 0; j < diagSize[i]; j++)
{
diagPoints += soluzione[i * MAX_ELEM + j].valore;
}
printf("DIAG #%d > %.3f", i + 1, diagPoints);
if (i == MAX_DIAG - 1 && soluzione[diagSize[i] + i * MAX_ELEM - 1].diff >= 8)
{
printf(" * 1.5 (BONUS)");
diagPoints *= 1.5;
}
printf("\n");
totPoints += diagPoints;
for (int j = 0; j < diagSize[i]; j++)
{
printf("%s ", soluzione[i * MAX_ELEM + j].nome);
}
printf("\n");
}
printf("TOT = %.3f\n", totPoints);
}
void trovaProgrammaGreedy(Elemento *elementi, int N, int DD, int DP)
{
int diffDiags[MAX_DIAG] = {0};
int tmp, minDiffAvanti = DD, minDiffIndietro = DD;
Requirements reqs[MAX_DIAG];
GlobalRequirements greqs;
bool found;
bool contieneElemFinale[MAX_DIAG];
for (int i = 0; i < N; i++)
{
if (elementi[i].diff < minDiffAvanti && elementi[i].tipo == AVANTI)
minDiffAvanti = elementi[i].diff;
if (elementi[i].diff < minDiffIndietro && elementi[i].tipo == INDIETRO)
minDiffIndietro = elementi[i].diff;
}
for (int i = 0; i < MAX_DIAG; i++)
{
contieneElemFinale[i] = false;
reqs[i].acrobNecessaria = true;
}
greqs.acrobAvantiNecessaria = greqs.acrobIndietroNecessaria = greqs.acrobInSeqNecessaria = true;
int *diagSize = (int *)malloc(MAX_DIAG * sizeof(int));
for (int i = 0; i < MAX_DIAG; i++)
diagSize[i] = 0;
Elemento *soluzione = (Elemento *)malloc(MAX_DIAG * MAX_ELEM * sizeof(Elemento));
Elemento *accettabili = (Elemento *)malloc(N * sizeof(Elemento));
int diffTot = 0;
for (int numElem = 0; numElem < MAX_ELEM; numElem++)
{
for (int numDiag = 0; numDiag < MAX_DIAG; numDiag++)
{
int posizioneAssoluta = numElem + numDiag * MAX_ELEM;
if (!contieneElemFinale[numDiag])
{
int numAcc = getAccettabili(accettabili, elementi, N, DD, DP, soluzione, posizioneAssoluta, numElem, numDiag, diffDiags, diffTot);
if (numAcc > 0)
{
// Ordinamento descrescente delle scelte possibili
sortAccettabili(accettabili, numAcc, &reqs[numDiag], &greqs);
if (greqs.acrobAvantiNecessaria != greqs.acrobIndietroNecessaria || reqs->acrobNecessaria)
{
found = false;
if (greqs.acrobAvantiNecessaria)
{
for (int i = 0; i < numAcc && !found; i++)
{
// Scelgo il primo elemento che soddisfa la condizione
if (accettabili[i].tipo == AVANTI)
{
found = true;
soluzione[posizioneAssoluta] = accettabili[i];
diagSize[numDiag]++;
}
}
if (!found)
{
for (int i = 0; i < numAcc && !found; i++)
{
if (accettabili[i].dirIngresso != accettabili[i].dirUscita && diffDiags[numDiag] + accettabili[i].diff + minDiffAvanti <= DD && !accettabili[i].finale)
{
soluzione[posizioneAssoluta] = accettabili[i];
diagSize[numDiag]++;
found = true;
}
}
if (!found)
{
// Effettuo scelta localmente ottima
soluzione[posizioneAssoluta] = accettabili[0];
diagSize[numDiag]++;
}
}
}
else if (greqs.acrobIndietroNecessaria)
{
for (int i = 0; i < numAcc && !found; i++)
{
if (accettabili[i].tipo == INDIETRO)
{
found = true;
// Effettuo scelta localmente ottima
soluzione[posizioneAssoluta] = accettabili[i];
diagSize[numDiag]++;
}
}
if (!found)
{
found = false;
for (int i = 0; i < numAcc && !found; i++)
{
if (accettabili[i].dirIngresso != accettabili[i].dirUscita && diffDiags[numDiag] + accettabili[i].diff + minDiffIndietro <= DD && !accettabili[i].finale)
{
soluzione[posizioneAssoluta] = accettabili[i];
diagSize[numDiag]++;
found = true;
}
}
if (!found)
{
// Effettuo scelta localmente ottima
soluzione[posizioneAssoluta] = accettabili[0];
diagSize[numDiag]++;
}
}
}
else
{
if (!greqs.acrobInSeqNecessaria)
{
for (int i = 0; i < numAcc && !found; i++)
{
if (accettabili[i].tipo != TRANSIZIONE && diffDiags[numDiag] + accettabili[i].diff + minDiffAvanti <= DD && !accettabili[i].finale)
{
soluzione[posizioneAssoluta] = accettabili[i];
diagSize[numDiag]++;
found = true;
}
}
if (!found)
{
// Effettuo scelta localmente ottima
soluzione[posizioneAssoluta] = accettabili[0];
diagSize[numDiag]++;
}
}
else
{
for (int i = 0; i < numAcc && !found; i++)
{
// Scelgo il primo elemento che soddisfa la condizione
if (accettabili[i].tipo != TRANSIZIONE)
{
found = true;
soluzione[posizioneAssoluta] = accettabili[i];
diagSize[numDiag]++;
if (!greqs.acrobInSeqNecessaria)
{
reqs[i].acrobNecessaria = false;
}
}
}
}
}
}
else
{
// Effettuo scelta localmente ottima
soluzione[posizioneAssoluta] = accettabili[0];
diagSize[numDiag]++;
}
// Aggiornamento difficoltà
diffDiags[numDiag] += soluzione[posizioneAssoluta].diff;
diffTot += soluzione[posizioneAssoluta].diff;
// Aggiornamento parametri funzione obiettivo
if (soluzione[posizioneAssoluta].tipo == AVANTI)
{
greqs.acrobAvantiNecessaria = false;
}
if (soluzione[posizioneAssoluta].tipo == INDIETRO)
{
greqs.acrobIndietroNecessaria = false;
}
if (numElem > 0 && soluzione[posizioneAssoluta].tipo > 0 && soluzione[posizioneAssoluta - 1].tipo > 0)
{
greqs.acrobInSeqNecessaria = false;
}
if (soluzione[posizioneAssoluta].finale)
{
// Blocco l'inserimento di elementi nella diagonale
contieneElemFinale[numDiag] = true;
}
}
}
}
}
// Cerco la diagonale con l'elemento che permette di ottenere il bonus
int bonusDiag = -1;
for (int numDiag = 0; numDiag < MAX_DIAG; numDiag++)
{
if (soluzione[diagSize[numDiag] + numDiag * MAX_ELEM - 1].diff >= 8)
bonusDiag = numDiag;
}
// Sposto se ho trovato un elemento con bonus che non è già in ultima posizione
if (bonusDiag != -1 && bonusDiag != MAX_DIAG - 1)
{
swap(&diagSize[MAX_DIAG - 1], &diagSize[bonusDiag]);
for (int i = 0; i < MAX_ELEM; i++)
swapE(&soluzione[i + (MAX_DIAG - 1) * MAX_ELEM], &soluzione[i + bonusDiag * MAX_ELEM]);
}
stampaSoluzione(soluzione, diagSize);
free(accettabili);
free(soluzione);
free(diagSize);
return;
}
int main()
{
int N = 0, DP, DD;
;
Elemento *l = leggiFile("elementi.txt", &N);
printf("Inserisci DD e DP: ");
scanf("%d %d", &DD, &DP);
trovaProgrammaGreedy(l, N, DD, DP);
free(l);
return 0;
}

View File

@@ -0,0 +1,301 @@
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
#include "Elementi.h"
#define MAX_ELEM 5
#define MAX_DIAG 3
typedef struct params {
bool acrobNecessaria;
bool acrobAvantiNecessaria;
bool acrobIndietroNecessaria;
bool haAcrobInSeq;
bool acrobInSeqNecessaria;
} Requirements;
Elemento *leggiFile(char *filename, int *N)
{
FILE *fin;
if ((fin = fopen(filename, "r")) == NULL)
{
puts("Impossibile aprire il file");
return NULL;
}
fscanf(fin, "%d", N);
Elemento *lista = malloc(*N * sizeof(Elemento));
for (int i = 0; i < *N; i++)
{
lista[i] = leggiElemento(fin);
}
fclose(fin);
return lista;
}
float calcElementValue(Elemento e, Requirements reqs) {
float value = (e.valore / e.diff);
if (e.tipo == AVANTI && reqs.acrobAvantiNecessaria) {
value += 1;
}
if (e.tipo == INDIETRO && reqs.acrobIndietroNecessaria) {
value += 1;
}
if (e.tipo > 0 && reqs.acrobNecessaria) {
value += 1;
}
if (e.tipo > 0 && reqs.acrobInSeqNecessaria) {
value += 1;
}
return value;
}
Requirements context;
int greedyChoice(const void *a, const void *b) {
Elemento x = *(Elemento *)a;
Elemento y = *(Elemento *)b;
float va = calcElementValue(x, context);
float vb = calcElementValue(y, context);
return vb > va;
}
void sortAccettabili(Elemento *accettabili, int N, Requirements *reqs) {
context = *reqs;
qsort(accettabili, N, sizeof(Elemento), greedyChoice);
}
int getAccettabili(Elemento *accettabili, Elemento *elementi, int N, int DD, int DP, Elemento *soluzione, int posizioneAssoluta, int posInDiag, int currKp, int diffDiags[MAX_DIAG], int diffTot) {
int N_accettabili = 0;
for (int i = 0; i < N; i++) {
if (diffDiags[currKp] + elementi[i].diff > DD || diffTot + elementi[i].diff > DP)
continue;
if (posInDiag == 0 && elementi[i].dirIngresso != FRONTE)
continue;
if (posInDiag > 0 && elementi[i].dirIngresso != soluzione[posizioneAssoluta-1].dirUscita)
continue;
if (posInDiag == 0 && elementi[i].reqPreced)
continue;
accettabili[N_accettabili++] = elementi[i];
}
return N_accettabili;
}
void stampaSoluzione(Elemento *sol, int N, int *kp) {
int i, j, bonusKp = -1;
float tot = 0, parz;
// Ricerca possibile diagonale con elemento bonus
for (i = 0; i < MAX_DIAG && bonusKp == -1; i++) {
for (j = 0; j < MAX_ELEM && bonusKp == -1; j++) {
if ((kp[j + MAX_ELEM * i] == -1 || j == MAX_ELEM - 1) && sol[j + MAX_ELEM * i - 1].diff >= 8) {
bonusKp = i;
}
}
}
// Scambio diagonale bonus, se trovata, con l'ultima diagonale
if (bonusKp != -1 && bonusKp != MAX_DIAG - 1) {
for (i = 0; i < N; i++) {
if (kp[i] == bonusKp) kp[i] = MAX_DIAG;
if (kp[i] == MAX_DIAG - 1) kp[i] = bonusKp;
}
for (i = 0; i < N; i++) {
if (kp[i] == MAX_DIAG) kp[i] = MAX_DIAG - 1;
}
bonusKp = MAX_DIAG - 1;
}
for (j = 0; j < MAX_DIAG; j++) {
parz = 0;
for (i = 0; i < N; i++) {
if (kp[i] == j) {
parz += sol[i].valore;
}
}
printf("DIAG #%d > %.3f", j+1, parz);
if (j == bonusKp)
printf(" * 1.5 (BONUS)");
printf("\n");
if (j == bonusKp) {
parz = parz * 1.5;
}
tot += parz;
for (i = 0; i < N; i++) {
if (kp[i] == j) {
printf("%s ", sol[i].nome);
}
}
printf("\n");
}
printf("TOT = %.3f\n", tot);
}
void trovaProgrammaGreedy(Elemento *elementi, int N, int DD, int DP) {
int diffDiags[MAX_DIAG] = {0};
int tmp, minDiffAvanti = DD, minDiffIndietro = DD;
Requirements reqs[MAX_DIAG];
bool found;
bool contieneElemFinale[MAX_DIAG];
for (int i = 0; i < N; i++) {
if (elementi[i].diff < minDiffAvanti && elementi[i].tipo == AVANTI)
minDiffAvanti = elementi[i].diff;
if (elementi[i].diff < minDiffIndietro && elementi[i].tipo == INDIETRO)
minDiffIndietro = elementi[i].diff;
}
for (int i = 0; i < MAX_DIAG; i++) {
contieneElemFinale[i] = false;
reqs[i].acrobInSeqNecessaria = reqs[i].haAcrobInSeq = false;
reqs[i].acrobAvantiNecessaria = reqs[i].acrobIndietroNecessaria = reqs[i].acrobNecessaria = true;
}
int *kp = (int *) malloc(MAX_DIAG * MAX_ELEM * sizeof(int));
for (int i = 0; i < MAX_DIAG * MAX_ELEM; i++)
kp[i] = -1;
Elemento *soluzione = (Elemento *) malloc(MAX_DIAG * MAX_ELEM * sizeof(Elemento));
Elemento *accettabili = (Elemento *) malloc(N * sizeof(Elemento));
int diffTot = 0;
for (int numElem = 0; numElem < MAX_ELEM; numElem++) {
for (int numDiag = 0; numDiag < MAX_DIAG; numDiag++) {
int posizioneAssoluta = numElem + numDiag * MAX_ELEM;
if (!contieneElemFinale[numDiag]) {
int numAcc = getAccettabili(accettabili, elementi, N, DD, DP, soluzione, posizioneAssoluta, numElem, numDiag, diffDiags, diffTot);
if (numAcc > 0) {
// Ordinamento descrescente delle scelte possibili
sortAccettabili(accettabili, numAcc, &reqs[numDiag]);
if (reqs[numDiag].acrobAvantiNecessaria != reqs[numDiag].acrobIndietroNecessaria) {
found = false;
if (reqs[numDiag].acrobAvantiNecessaria) {
for (int i = 0; i < numAcc && !found; i++) {
// Scelgo la prima diagonale che soddisfa la condizione
if (accettabili[i].tipo == AVANTI) {
found = true;
soluzione[posizioneAssoluta] = accettabili[i];
kp[posizioneAssoluta] = numDiag;
}
}
if (!found) {
for (int i = 0; i < numAcc && !found; i++) {
if (accettabili[i].dirIngresso != accettabili[i].dirUscita && diffDiags[numDiag] + accettabili[i].diff + minDiffAvanti <= DD && !accettabili[i].finale) {
soluzione[posizioneAssoluta] = accettabili[i];
kp[posizioneAssoluta] = numDiag;
found = true;
for (tmp = 0; tmp < MAX_DIAG; tmp++)
reqs[tmp].acrobAvantiNecessaria = false;
reqs[numDiag].acrobAvantiNecessaria = true;
}
}
if (!found) {
// Effettuo scelta localmente ottima
soluzione[posizioneAssoluta] = accettabili[0];
kp[posizioneAssoluta] = numDiag;
}
}
}
if (reqs[numDiag].acrobIndietroNecessaria) {
for (int i = 0; i < numAcc && !found; i++) {
if (accettabili[i].tipo == INDIETRO) {
found = true;
// Effettuo scelta localmente ottima
soluzione[posizioneAssoluta] = accettabili[i];
kp[posizioneAssoluta] = numDiag;
}
}
if (!found) {
found = false;
for (int i = 0; i < numAcc && !found; i++) {
if (accettabili[i].dirIngresso != accettabili[i].dirUscita && diffDiags[numDiag] + accettabili[i].diff + minDiffIndietro <= DD && !accettabili[i].finale) {
soluzione[posizioneAssoluta] = accettabili[i];
kp[posizioneAssoluta] = numDiag;
for (tmp = 0; tmp < MAX_DIAG; tmp++)
reqs[tmp].acrobIndietroNecessaria = false;
reqs[numDiag].acrobIndietroNecessaria = true;
found = true;
}
}
if (!found) {
// Effettuo scelta localmente ottima
soluzione[posizioneAssoluta] = accettabili[0];
kp[posizioneAssoluta] = numDiag;
}
}
}
} else {
// Effettuo scelta localmente ottima
soluzione[posizioneAssoluta] = accettabili[0];
kp[posizioneAssoluta] = numDiag;
}
// Aggiornamento difficoltà
diffDiags[numDiag] += soluzione[posizioneAssoluta].diff;
diffTot += soluzione[posizioneAssoluta].diff;
// Aggiornamento parametri funzione obiettivo
if (soluzione[posizioneAssoluta].tipo == AVANTI) {
for (int i = 0; i < MAX_DIAG; i++)
reqs[i].acrobAvantiNecessaria = false;
reqs[numDiag].acrobIndietroNecessaria = false;
}
if (soluzione[posizioneAssoluta].tipo == INDIETRO) {
for (int i = 0; i < MAX_DIAG; i++)
reqs[i].acrobIndietroNecessaria = false;
reqs[numDiag].acrobAvantiNecessaria = false;
}
if (numElem > 0 && soluzione[posizioneAssoluta].tipo > 0 && soluzione[posizioneAssoluta-1].tipo > 0) {
for (int i = 0; i < MAX_DIAG; i++)
reqs[i].haAcrobInSeq = true;
}
if (numElem > 0 && soluzione[posizioneAssoluta-1].tipo > 0 && !reqs[numDiag].haAcrobInSeq) {
reqs[numDiag].acrobInSeqNecessaria = true;
} else
reqs[numDiag].acrobInSeqNecessaria = false;
if (soluzione[posizioneAssoluta].finale) {
// Skip a prossima diagonale se è stato inserito un elemento finale
contieneElemFinale[numDiag] = true;
}
}
}
}
}
stampaSoluzione(soluzione, MAX_DIAG * MAX_ELEM, kp);
free(accettabili);
free(soluzione);
free(kp);
return;
}
int main()
{
int N = 0, DP, DD;;
Elemento *l = leggiFile("elementi.txt", &N);
printf("Inserisci DD e DP: ");
scanf("%d %d", &DD, &DP);
trovaProgrammaGreedy(l, N, DD, DP);
free(l);
return 0;
}

View File

@@ -0,0 +1,59 @@
--- Test Case #1 ---
DD = 10 DP = 20
TOT = 17.800
DIAG #1 > 1.750
front_tuck
DIAG #2 > 3.750
front_tuck front_pike
DIAG #3 > 8.200 * 1.5 (BONUS)
rondata back_layout_double_twist
--- Test Case #2 ---
DD = 7 DP = 30
TOT = 11.200
DIAG #1 > 3.700
rondata back_tuck back_tuck
DIAG #2 > 3.750
front_tuck front_pike
DIAG #3 > 3.750
front_tuck front_pike
--- Test Case #3 ---
DD = 10 DP = 35
TOT = 26.250
DIAG #1 > 5.750
front_tuck double_front_layout
DIAG #2 > 8.200
rondata back_layout_double_twist
DIAG #3 > 8.200 * 1.5 (BONUS)
rondata back_layout_double_twist
--- Test Case #4 ---
DD = 12 DP = 28
TOT = 34.000
DIAG #1 > 12.200
rondata back_layout_quad_twist
DIAG #2 > 3.500
front_tuck front_tuck
DIAG #3 > 12.200 * 1.5 (BONUS)
rondata back_layout_quad_twist
--- Test Case #5 ---
DD = 12 DP = 30
TOT = 34.950
DIAG #1 > 4.450
rondata arabian front_tuck
DIAG #2 > 12.200
rondata back_layout_quad_twist
DIAG #3 > 12.200 * 1.5 (BONUS)
rondata back_layout_quad_twist
--- Test Case #6 ---
DD = 11 DP = 33
TOT = 38.750
DIAG #1 > 12.200
rondata back_layout_quad_twist
DIAG #2 > 8.250
front_tuck triple_front_tuck
DIAG #3 > 12.200 * 1.5 (BONUS)
rondata back_layout_quad_twist

View File

@@ -0,0 +1,316 @@
// Laboratorio 8 - Esercizio 2 - Graph.c
// Matteo Schiff - s295565
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "Graph.h"
#include "ST.h"
typedef struct node *link;
struct node
{
int id;
int wt;
link next;
};
struct graph
{
int V;
int E;
int **madj;
link *ladj;
link z;
ST tab;
};
static link newNode(int id, int wt, link next)
{
link t = (link)malloc(sizeof(*t));
t->id = id;
t->wt = wt;
t->next = next;
return t;
}
static void freeList(link t, link z)
{
link q, x = t;
if (t == z)
return;
while (x != z)
{
q = x->next;
free(x);
x = q;
}
}
static int searchList(link t, link z, int id)
{
for (link x = t; x != z; x = x->next)
{
if (x->id == id)
return 1;
}
return 0;
}
static Edge EDGEcreate(int v, int w, int wt)
{
Edge e;
e.v = v;
e.w = w;
e.wt = wt;
return e;
}
// Questa variabile è usata dalla funzione `vertexCompare` che è chiamata da qsort
Graph tmpG;
static int vertexCompare(const void *a, const void *b)
{
return (strcmp(STsearchByIndex(tmpG->tab, (*(Edge *)a).w).name, STsearchByIndex(tmpG->tab, (*(Edge *)b).w).name));
}
static void EDGEsort(Edge *edges, int N, Graph G)
{
tmpG = G;
qsort(edges, N, sizeof(Edge), vertexCompare);
}
Graph GRAPHload(FILE *fin)
{
int lines = 0, wt;
Graph G;
Item item1, item2;
for (char c = getc(fin); c != EOF; c = getc(fin))
if (c == '\n') // Se leggo un newline aumento il numero delle linee
lines = lines + 1;
fseek(fin, 0, SEEK_SET);
G = GRAPHinit(2 * lines); // Alloco sovrastimando il numero di vertici
for (int i = 0; i < lines; i++)
{
item1 = ITEMread(fin);
item2 = ITEMread(fin);
fscanf(fin, " %d", &wt);
int id1 = GRAPHgetIndex(G, item1);
int id2 = GRAPHgetIndex(G, item2);
GRAPHinsertE(G, id1, id2, wt);
}
return G;
}
void GRAPHinsertE(Graph G, int v, int w, int wt)
{
if (G->madj[v][w] == 0)
G->E++;
G->madj[v][w] = 1;
G->madj[v][w] = wt;
G->madj[w][v] = 1;
G->madj[w][v] = wt;
}
void GRAPHremoveE(Graph G, int v, int w)
{
if (G->madj[v][w] != 0)
G->E--;
G->madj[v][w] = 0;
G->madj[w][v] = 0;
}
static int **MATRIXinit(int r, int c, int val)
{
int i, j;
int **t = malloc(r * sizeof(int *));
for (i = 0; i < r; i++)
t[i] = malloc(c * sizeof(int));
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
t[i][j] = val;
return t;
}
static link *LISTinit(int V, link z)
{
link *list = (link *)malloc(V * sizeof(link));
for (int v = 0; v < V; v++)
list[v] = z;
return list;
}
Graph GRAPHinit(int V)
{
Graph G = malloc(sizeof *G);
G->V = 0;
G->E = 0;
G->madj = MATRIXinit(V, V, 0);
G->z = newNode(-1, -1, NULL);
G->ladj = LISTinit(V, G->z);
G->tab = STinit(V);
return G;
}
void GRAPHfree(Graph G)
{
int i;
for (i = 0; i < G->V; i++)
free(G->madj[i]);
free(G->madj);
for (i = 0; i < G->V; i++)
{
freeList(G->ladj[i], G->z);
}
free(G->ladj);
free(G->z);
STfree(G->tab);
free(G);
}
int GRAPHgetIndex(Graph G, Item item)
{
int id = STsearch(G->tab, item);
if (id == -1)
{
id = STinsert(G->tab, item);
G->V++;
}
return id;
}
void GRAPHbuildLadj(Graph G)
{
link t;
for (int i = 0; i < G->V; i++)
{
freeList(G->ladj[i], G->z);
G->ladj[i] = G->z;
}
for (int i = 0; i < G->V; i++)
{
for (int j = 0; j < G->V; j++)
{
if (G->madj[i][j] != 0)
G->ladj[i] = newNode(j, G->madj[i][j], G->ladj[i]);
}
}
for (int i = 0; i < G->V; i++)
{
if (G->ladj[i] != G->z)
{
printf("%d", i);
for (t = G->ladj[i]; t != G->z; t = t->next)
{
printf(" -> (%d,%d)", t->id, t->wt);
}
printf("\n");
}
}
}
static int checkAdjacencyM(Graph G, int id1, int id2, int id3)
{
if (!G->madj[id1][id2] || !G->madj[id1][id3])
return 0;
if (!G->madj[id2][id1] || !G->madj[id2][id3])
return 0;
if (!G->madj[id3][id1] || !G->madj[id3][id2])
return 0;
return 1;
}
static int checkAdjacencyL(Graph G, int id1, int id2, int id3)
{
if (!searchList(G->ladj[id1], G->z, id2) || !searchList(G->ladj[id1], G->z, id2))
return 0;
if (!searchList(G->ladj[id2], G->z, id1) || !searchList(G->ladj[id2], G->z, id3))
return 0;
if (!searchList(G->ladj[id3], G->z, id1) || !searchList(G->ladj[id3], G->z, id2))
return 0;
return 1;
}
void GRAPHCheckVertexAdiacency(Graph G)
{
puts("Inserisci i tre vertici specificando per ogni vertice \"<nome> <subnet>\"");
Item i1 = ITEMread(stdin);
Item i2 = ITEMread(stdin);
Item i3 = ITEMread(stdin);
int id1 = STsearch(G->tab, i1);
int id2 = STsearch(G->tab, i2);
int id3 = STsearch(G->tab, i3);
if (id1 == -1 || id2 == -1 || id3 == -1)
{
puts("Attenzione: vertici non validi");
return;
}
if (checkAdjacencyM(G, id1, id2, id3))
{
puts("I vertici formano un sottografo completo");
}
else
{
puts("I vertici non formano un sottografo completo");
}
}
void GRAPHprintOrdered(Graph G)
{
Item *items = malloc(G->V * sizeof(Item));
Edge *edges = malloc(G->V * sizeof(Edge));
for (int i = 0; i < G->V; i++)
{
items[i] = STsearchByIndex(G->tab, i);
}
ITEMsort(items, G->V);
for (int i = 0; i < G->V; i++)
{
int id = GRAPHgetIndex(G, items[i]);
printf("%s %s:\n", items[i].name, items[i].subnet);
// Crea lista di edges
int N = 0;
for (int j = 0; j < G->V; j++)
{
if (G->madj[id][j] != 0)
edges[N++] = EDGEcreate(id, j, G->madj[id][j]);
}
EDGEsort(edges, N, G);
for (int j = 0; j < N; j++)
{
printf(" - %s %s, peso %d\n", STsearchByIndex(G->tab, edges[j].w).name, STsearchByIndex(G->tab, edges[j].w).subnet, edges[j].wt);
}
}
free(edges);
free(items);
}

View File

@@ -0,0 +1,26 @@
// Laboratorio 8 - Esercizio 2 - Graph.h
// Matteo Schiff - s295565
#ifndef GRAPH_DEFINED
#define GRAPH_DEFINED
#include<stdio.h>
#include"Item.h"
#define MAXC 100
typedef struct edge
{
int v;
int w;
int wt;
} Edge;
typedef struct graph *Graph;
Graph GRAPHinit(int V);
void GRAPHfree(Graph G);
Graph GRAPHload(FILE *fin);
void GRAPHbuildLadj(Graph G);
void GRAPHCheckVertexAdiacency(Graph G);
void GRAPHprintOrdered(Graph G);
int GRAPHgetIndex(Graph G, Item item);
void GRAPHinsertE(Graph G, int v, int w, int wt);
#endif

View File

@@ -0,0 +1,37 @@
// Laboratorio 8 - Esercizio 2 - Item.c
// Matteo Schiff - s295565
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "Item.h"
Item ITEMcreate(char *name, char *subnet) {
Item t;
strncpy(t.name, name, MAX_STR+1);
strncpy(t.subnet, subnet, MAX_STR+1);
return t;
}
Item ITEMread(FILE * fp) {
Item item;
fscanf(fp, " %s %s", item.name, item.subnet);
return item;
}
Item ITEMnull() {
Item t;
strcpy(t.name, "");
strcpy(t.subnet, "");
return t;
}
static int compareItem(const void *a, const void *b) {
return strcmp((*(Item*)a).name, (*(Item*)b).name);
}
void ITEMsort(Item *v, int N) {
qsort(v, N, sizeof(Item), compareItem);
}

View File

@@ -0,0 +1,23 @@
// Laboratorio 8 - Esercizio 2 - Item.h
// Matteo Schiff - s295565
#ifndef ITEM_DEFINED
#define ITEM_DEFINED
#include <stdio.h>
#define MAX_STR 30
typedef struct item {
char name[MAX_STR+1];
char subnet[MAX_STR+1];
} Item;
Item ITEMcreate(char *name, char *subnet);
Item ITEMread(FILE * fp);
Item ITEMnull();
void ITEMsort(Item *v, int N);
#endif

View File

@@ -0,0 +1,61 @@
// Laboratorio 8 - Esercizio 2 - ST.c
// Matteo Schiff - s295565
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "ST.h"
#include "Item.h"
struct st {
Item *v;
int N;
int maxN;
};
ST STinit(int N) {
ST st = (ST) malloc(sizeof(*st));
st->v = (Item *) malloc(N * sizeof(Item));
st->N = 0;
st->maxN = N;
return st;
}
void STfree(ST st) {
free(st->v);
free(st);
}
int STinsert(ST st, Item item) {
if (st->N == st->maxN) {
printf("Errore, spazio esaurito nella ST\n");
return -1;
}
st->v[st->N] = item;
st->N++;
return st->N -1;
}
Item STsearchByIndex(ST st, int index) {
if (index >= st->N)
return ITEMnull();
return st->v[index];
}
int STsearch(ST st, Item item) {
int i;
for (i = 0; i < st->N; i++) {
if (strcmp(item.name, st->v[i].name) == 0)
return i;
}
return -1;
}
int STcount(ST st) {
return st->N;
}

View File

@@ -0,0 +1,21 @@
// Laboratorio 8 - Esercizio 2 - ST.h
// Matteo Schiff - s295565
#ifndef ST_DEFINED
#define ST_DEFINED
#include "Item.h"
typedef struct st *ST;
ST STinit(int N);
void STfree(ST st);
int STinsert(ST st, Item item);
Item STsearchByIndex(ST st, int index);
int STsearch(ST st, Item item);
int STcount(ST st);
#endif

View File

@@ -0,0 +1,21 @@
Uriel Net3 Bahamut Net2 99
Uriel Net3 Igni Net0 45
Igni Net0 Tatooine Net1 67
Tatooine Net1 Bahamut Net2 33
Axii Net0 Igni Net0 42
Quen Net0 Igni Net0 18
Shiva Net2 Tatooine Net1 12
Ifrit Net2 Tatooine Net1 2
Ramuh Net2 Tatooine Net1 111
Shiva Net2 Ifrit Net2 46
Quen Net0 Coruscan Net1 45
Shiva Net2 Alderaan Net1 98
Ifrit Net2 Alderaan Net1 13
Ramuh Net2 Alderaan Net1 9
Ramuh Net2 Azrael Net3 23
Axii Net0 Cassiel Net3 13
Shiva Net2 Cassiel Net3 1
Shiva Net2 Yrden Net0 17
Alderaan Net1 Yrden Net0 20
Cassiel Net3 Yrden Net0 20
Cassiel Net3 Azrael Net3 9

View File

@@ -0,0 +1,92 @@
// Laboratorio 8 - Esercizio 2 - main.c
// Matteo Schiff - s295565
#include<ctype.h>
#include<string.h>
#include"Graph.h"
#define MAX_LEN 30
const int MAXL = 100;
typedef enum
{
r_print,
r_adj,
r_build,
r_fine
} t_comandi;
char *toLower(char *s)
{
for (char *p = s; *p; p++)
*p = tolower(*p);
return s;
}
t_comandi leggiComando()
{
t_comandi c;
char cmd[MAXL];
char tabella[4][20] = {
"stampa", "adiacenza", "converti", "fine"};
printf("comando (stampa/adiacenza/converti/fine): ");
scanf("%s", cmd);
toLower(cmd);
c = r_print;
while (c < 4 && strcmp(cmd, tabella[c]) != 0)
c++;
return (c);
}
void menuParola(Graph G)
{
t_comandi comando;
int i, continua = 1;
while (continua)
{
comando = leggiComando();
switch (comando)
{
case r_print:
GRAPHprintOrdered(G);
break;
case r_adj:
GRAPHCheckVertexAdiacency(G);
break;
case r_build:
GRAPHbuildLadj(G);
break;
case r_fine:
continua = 0;
break;
default:
puts("Comando non valido\n");
}
}
}
int main(int argc, char const *argv[])
{
FILE * fp_read;
Graph G;
if (argc < 1) {
puts("Specifica il file tra gli argomenti");
return 1;
}
if ((fp_read = fopen(argv[1], "r")) == NULL)
{
puts("Impossibile aprire il file");
return 1;
}
G = GRAPHload(fp_read);
fclose(fp_read);
menuParola(G);
GRAPHfree(G);
return 0;
}

View File

@@ -0,0 +1,53 @@
// Laboratorio 8 - Esercizio 3 - Asset.c
// Matteo Schiff - s295565
#include <stdlib.h>
#include <string.h>
#include "Asset.h"
#include "ExrateBST.h"
struct asset
{
char titolo[STR_LEN];
ExrateBST exrates;
};
Asset AssetCreate() {
Asset a = malloc(sizeof(*a));
a->exrates = ExrateBSTCreate();
return a;
}
void AssetFree(Asset a) {
ExrateBSTFree(a->exrates);
free(a);
}
int AssetCompare(Asset a, Asset b) {
return strcmp(a->titolo, b->titolo);
}
char * AssetTitle(Asset a) {
return a->titolo;
}
ExrateBST AssetGetExrates(Asset a) {
return a->exrates;
}
Asset AssetRead(FILE *fp) {
Asset n = AssetCreate();
Exrate je;
int Nitems;
fscanf(fp, " %s %d",n->titolo, &Nitems);
for (int i = 0; i < Nitems; i++) {
ExrateRead(&je, fp);
ExrateBSTInsert(n->exrates, je);
}
return n;
}
void AssetPrint(Asset a) {
printf(" - %s\n", a->titolo);
}

View File

@@ -0,0 +1,16 @@
// Laboratorio 8 - Esercizio 3 - Asset.h
// Matteo Schiff - s295565
#ifndef ASSET_DEFINED
#define ASSET_DEFINED
#define STR_LEN 20
#include "ExrateBST.h"
typedef struct asset *Asset;
void AssetFree(Asset a);
int AssetCompare(Asset a, Asset b);
ExrateBST AssetGetExrates(Asset a);
Asset AssetRead(FILE *fp);
void AssetPrint(Asset a);
char * AssetTitle(Asset a);
#endif

View File

@@ -0,0 +1,113 @@
// Laboratorio 8 - Esercizio 3 - AssetList.c
// Matteo Schiff - s295565
#include <stdlib.h>
#include <string.h>
#include "Asset.h"
#include "AssetList.h"
#include "ExrateBST.h"
typedef struct node *link;
struct node
{
Asset asset;
link next;
};
struct assetList
{
link head;
int N;
};
static link createNode(Asset asset, link next)
{
link new = malloc(sizeof(*new));
new->asset = asset;
new->next = next;
return new;
}
AssetList AssetListCreate()
{
AssetList al = malloc(sizeof(*al));
al->head = NULL;
al->N = 0;
return al;
}
void AssetListFree(AssetList al)
{
for (link x = al->head, p = x->next; p != NULL; x = p, p = x->next)
{
free(x);
}
free(al);
}
int AssetListLength(AssetList al) {
return al->N;
}
void AssetListPrint(AssetList al) {
link h = al->head;
while (h != NULL) {
AssetPrint(h->asset);
h = h->next;
}
}
Asset * AssetListGet(AssetList al, int index) {
link h;
int i = 0;
h = al->head;
while (h != NULL) {
if (i == index)
return &(h->asset);
h = h->next;
i++;
}
return NULL;
}
Asset * AssetListSearch(AssetList al, char * query) {
link h;
h = al->head;
while (h != NULL) {
if (strcmp(AssetTitle(h->asset), query) == 0)
return &(h->asset);
h = h->next;
}
return NULL;
}
void AssetListInsert(AssetList al, Asset asset)
{
link x, p;
if (al->head == NULL)
{
al->head = createNode(asset, al->head);
al->N++;
return;
}
for (x = al->head, p = x->next; p != NULL; x = p, p = x->next)
{
if (AssetCompare(asset, x->asset) == 0)
{
ExrateBSTMerge(AssetGetExrates(x->asset), AssetGetExrates(asset));
return;
}
else if (AssetCompare(asset, x->asset) < 0)
{
break;
}
}
x->next = createNode(asset, p);
al->N++;
}

View File

@@ -0,0 +1,18 @@
// Laboratorio 8 - Esercizio 3 - AssetList.h
// Matteo Schiff - s295565
#ifndef ASSETLIST_DEFINED
#define ASSETLIST_DEFINED
#include "Asset.h"
typedef struct assetList *AssetList;
AssetList AssetListCreate();
void AssetListFree(AssetList al);
void AssetListInsert(AssetList al, Asset asset);
Asset * AssetListGet(AssetList al, int index);
Asset * AssetListSearch(AssetList al, char * query);
void AssetListPrint(AssetList al);
int AssetListLength(AssetList al);
#endif

View File

@@ -0,0 +1,36 @@
// Laboratorio 8 - Esercizio 3 - Datetime.c
// Matteo Schiff - s295565
#include <stdbool.h>
#include <stdio.h>
#include "Datetime.h"
int DateTimeCompare(DateTime a, DateTime b) {
if (a.year > b.year)
return 1;
else if (a.year < b.year)
return -1;
if (a.month > b.month)
return 1;
else if (a.month < b.month)
return -1;
if (a.day > b.day)
return 1;
else if (a.day < b.day)
return -1;
return 0;
}
int DateTimeRead(DateTime * dt, FILE * fp) {
return fscanf(fp, " %d/%d/%d %d:%d", &dt->year, &dt->month,&dt->day,&dt->hours,&dt->minutes) == 5;
}
int DateRead(DateTime * dt, FILE * fp) {
dt->hours = 0;
dt->minutes = 0;
return fscanf(fp, " %d/%d/%d", &dt->year, &dt->month,&dt->day) == 3;
}

Some files were not shown because too many files have changed in this diff Show More