feat: Initial commit
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@@ -52,3 +52,5 @@ Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
|
||||
# GDB history
|
||||
.gdb_history
|
||||
|
||||
94
Laboratorio 1/Esercizio 1/main.c
Normal file
94
Laboratorio 1/Esercizio 1/main.c
Normal 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;
|
||||
}
|
||||
7
Laboratorio 1/Esercizio 2/corse.txt
Normal file
7
Laboratorio 1/Esercizio 2/corse.txt
Normal 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
|
||||
249
Laboratorio 1/Esercizio 2/main.c
Normal file
249
Laboratorio 1/Esercizio 2/main.c
Normal 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;
|
||||
}
|
||||
7
Laboratorio 1/Esercizio 3/corse.txt
Normal file
7
Laboratorio 1/Esercizio 3/corse.txt
Normal 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
|
||||
451
Laboratorio 1/Esercizio 3/main.c
Normal file
451
Laboratorio 1/Esercizio 3/main.c
Normal 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;
|
||||
}
|
||||
7
Laboratorio 1/Esercizio 4/corse.txt
Normal file
7
Laboratorio 1/Esercizio 4/corse.txt
Normal 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
|
||||
476
Laboratorio 1/Esercizio 4/main.c
Normal file
476
Laboratorio 1/Esercizio 4/main.c
Normal 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;
|
||||
}
|
||||
45
Laboratorio 2/Esercizio 1/main.c
Normal file
45
Laboratorio 2/Esercizio 1/main.c
Normal 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));
|
||||
}
|
||||
89
Laboratorio 2/Esercizio 2/main.c
Normal file
89
Laboratorio 2/Esercizio 2/main.c
Normal 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;
|
||||
}
|
||||
4
Laboratorio 2/Esercizio 2/mat.txt
Normal file
4
Laboratorio 2/Esercizio 2/mat.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
3 3
|
||||
1 2 3
|
||||
4 5 6
|
||||
7 8 9
|
||||
8
Laboratorio 2/Esercizio 3/corse.txt
Normal file
8
Laboratorio 2/Esercizio 3/corse.txt
Normal 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
|
||||
|
||||
8
Laboratorio 2/Esercizio 3/corse2.txt
Normal file
8
Laboratorio 2/Esercizio 3/corse2.txt
Normal 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
|
||||
|
||||
496
Laboratorio 2/Esercizio 3/main.c
Normal file
496
Laboratorio 2/Esercizio 3/main.c
Normal 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;
|
||||
}
|
||||
56
Laboratorio 3/Esercizio 1/main.c
Normal file
56
Laboratorio 3/Esercizio 1/main.c
Normal 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));
|
||||
}
|
||||
26
Laboratorio 3/Esercizio 2/brani.txt
Normal file
26
Laboratorio 3/Esercizio 2/brani.txt
Normal 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
|
||||
87
Laboratorio 3/Esercizio 2/main.c
Normal file
87
Laboratorio 3/Esercizio 2/main.c
Normal 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;
|
||||
}
|
||||
5
Laboratorio 4/Esercizio 1/grafo.txt
Normal file
5
Laboratorio 4/Esercizio 1/grafo.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
4 4
|
||||
0 1
|
||||
0 2
|
||||
1 2
|
||||
1 3
|
||||
77
Laboratorio 4/Esercizio 1/main.c
Normal file
77
Laboratorio 4/Esercizio 1/main.c
Normal 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;
|
||||
}
|
||||
3
Laboratorio 4/Esercizio 2/anag1.txt
Normal file
3
Laboratorio 4/Esercizio 2/anag1.txt
Normal 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
|
||||
2
Laboratorio 4/Esercizio 2/anag2.txt
Normal file
2
Laboratorio 4/Esercizio 2/anag2.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
A0004 Anna Gialli 04/09/1995 FratelliAlinari Firenze 50123
|
||||
A0005 Marco Bianchi 03/07/1993 PiazzaMazzini Napoli 80135
|
||||
192
Laboratorio 4/Esercizio 2/item.c
Normal file
192
Laboratorio 4/Esercizio 2/item.c
Normal 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
|
||||
55
Laboratorio 4/Esercizio 2/item.h
Normal file
55
Laboratorio 4/Esercizio 2/item.h
Normal 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
|
||||
220
Laboratorio 4/Esercizio 2/main.c
Normal file
220
Laboratorio 4/Esercizio 2/main.c
Normal 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;
|
||||
}
|
||||
2
Laboratorio 4/Esercizio 2/out
Normal file
2
Laboratorio 4/Esercizio 2/out
Normal file
@@ -0,0 +1,2 @@
|
||||
A0004 Anna Gialli 04/09/1995 FratelliAlinari Firenze 50123
|
||||
A0002 Lucia Verdi 07/11/1989 ViaTorino Milano 20123
|
||||
17
Laboratorio 4/Esercizio 3/easy_test_set.txt
Normal file
17
Laboratorio 4/Esercizio 3/easy_test_set.txt
Normal 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
|
||||
|
||||
45
Laboratorio 4/Esercizio 3/easy_test_set_result.txt
Normal file
45
Laboratorio 4/Esercizio 3/easy_test_set_result.txt
Normal 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
|
||||
16
Laboratorio 4/Esercizio 3/hard_test_set.txt
Normal file
16
Laboratorio 4/Esercizio 3/hard_test_set.txt
Normal 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
|
||||
45
Laboratorio 4/Esercizio 3/hard_test_set_result.txt
Normal file
45
Laboratorio 4/Esercizio 3/hard_test_set_result.txt
Normal 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
|
||||
107
Laboratorio 4/Esercizio 3/main.c
Normal file
107
Laboratorio 4/Esercizio 3/main.c
Normal 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);
|
||||
}
|
||||
7
Laboratorio 4/Esercizio 3/very_easy_test_set.txt
Normal file
7
Laboratorio 4/Esercizio 3/very_easy_test_set.txt
Normal 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
|
||||
3
Laboratorio 4/Esercizio 3/very_very_easy_test_set.txt
Normal file
3
Laboratorio 4/Esercizio 3/very_very_easy_test_set.txt
Normal file
@@ -0,0 +1,3 @@
|
||||
1
|
||||
2 1 2 2
|
||||
|
||||
122
Laboratorio 4/Esercizio 4/main.c
Normal file
122
Laboratorio 4/Esercizio 4/main.c
Normal 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);
|
||||
}
|
||||
21
Laboratorio 4/Esercizio 4/test_set.txt
Normal file
21
Laboratorio 4/Esercizio 4/test_set.txt
Normal 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
|
||||
80
Laboratorio 4/Esercizio 4/test_set_results.txt
Normal file
80
Laboratorio 4/Esercizio 4/test_set_results.txt
Normal 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
|
||||
7
Laboratorio 5/Esercizio 1/att.txt
Normal file
7
Laboratorio 5/Esercizio 1/att.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
6
|
||||
1 2
|
||||
2 4
|
||||
2 5
|
||||
3 5
|
||||
5 7
|
||||
6 8
|
||||
9
Laboratorio 5/Esercizio 1/att1.txt
Normal file
9
Laboratorio 5/Esercizio 1/att1.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
8
|
||||
0 6
|
||||
1 4
|
||||
3 5
|
||||
3 8
|
||||
4 7
|
||||
5 9
|
||||
6 10
|
||||
8 11
|
||||
103
Laboratorio 5/Esercizio 1/main.c
Normal file
103
Laboratorio 5/Esercizio 1/main.c
Normal 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;
|
||||
}
|
||||
4
Laboratorio 5/Esercizio 2/board.txt
Normal file
4
Laboratorio 5/Esercizio 2/board.txt
Normal 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
|
||||
245
Laboratorio 5/Esercizio 2/main.c
Normal file
245
Laboratorio 5/Esercizio 2/main.c
Normal 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;
|
||||
}
|
||||
10
Laboratorio 5/Esercizio 2/tiles.txt
Normal file
10
Laboratorio 5/Esercizio 2/tiles.txt
Normal 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
|
||||
17
Laboratorio 6/Esercizio 2/easy_test_set.txt
Normal file
17
Laboratorio 6/Esercizio 2/easy_test_set.txt
Normal 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
|
||||
|
||||
45
Laboratorio 6/Esercizio 2/easy_test_set_result.txt
Normal file
45
Laboratorio 6/Esercizio 2/easy_test_set_result.txt
Normal 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
|
||||
16
Laboratorio 6/Esercizio 2/hard_test_set.txt
Normal file
16
Laboratorio 6/Esercizio 2/hard_test_set.txt
Normal 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
|
||||
45
Laboratorio 6/Esercizio 2/hard_test_set_result.txt
Normal file
45
Laboratorio 6/Esercizio 2/hard_test_set_result.txt
Normal 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
|
||||
201
Laboratorio 6/Esercizio 2/main.c
Normal file
201
Laboratorio 6/Esercizio 2/main.c
Normal 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);
|
||||
}
|
||||
108
Laboratorio 6/Esercizio 3/equipArray.c
Normal file
108
Laboratorio 6/Esercizio 3/equipArray.c
Normal 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
|
||||
34
Laboratorio 6/Esercizio 3/equipArray.h
Normal file
34
Laboratorio 6/Esercizio 3/equipArray.h
Normal 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
|
||||
122
Laboratorio 6/Esercizio 3/gdr.c
Normal file
122
Laboratorio 6/Esercizio 3/gdr.c
Normal 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;
|
||||
}
|
||||
71
Laboratorio 6/Esercizio 3/inv.c
Normal file
71
Laboratorio 6/Esercizio 3/inv.c
Normal 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
|
||||
42
Laboratorio 6/Esercizio 3/inv.h
Normal file
42
Laboratorio 6/Esercizio 3/inv.h
Normal 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
|
||||
67
Laboratorio 6/Esercizio 3/invArray.c
Normal file
67
Laboratorio 6/Esercizio 3/invArray.c
Normal 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
|
||||
30
Laboratorio 6/Esercizio 3/invArray.h
Normal file
30
Laboratorio 6/Esercizio 3/invArray.h
Normal 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
|
||||
16
Laboratorio 6/Esercizio 3/inventario.txt
Normal file
16
Laboratorio 6/Esercizio 3/inventario.txt
Normal 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
|
||||
49
Laboratorio 6/Esercizio 3/pg.c
Normal file
49
Laboratorio 6/Esercizio 3/pg.c
Normal 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
|
||||
35
Laboratorio 6/Esercizio 3/pg.h
Normal file
35
Laboratorio 6/Esercizio 3/pg.h
Normal 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
|
||||
10
Laboratorio 6/Esercizio 3/pg.txt
Normal file
10
Laboratorio 6/Esercizio 3/pg.txt
Normal 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
|
||||
131
Laboratorio 6/Esercizio 3/pgList.c
Normal file
131
Laboratorio 6/Esercizio 3/pgList.c
Normal 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
|
||||
33
Laboratorio 6/Esercizio 3/pgList.h
Normal file
33
Laboratorio 6/Esercizio 3/pgList.h
Normal 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
|
||||
103
Laboratorio 7/Esercizio 1/equipArray.c
Normal file
103
Laboratorio 7/Esercizio 1/equipArray.c
Normal 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
|
||||
33
Laboratorio 7/Esercizio 1/equipArray.h
Normal file
33
Laboratorio 7/Esercizio 1/equipArray.h
Normal 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
|
||||
122
Laboratorio 7/Esercizio 1/gdr.c
Normal file
122
Laboratorio 7/Esercizio 1/gdr.c
Normal 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;
|
||||
}
|
||||
71
Laboratorio 7/Esercizio 1/inv.c
Normal file
71
Laboratorio 7/Esercizio 1/inv.c
Normal 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
|
||||
42
Laboratorio 7/Esercizio 1/inv.h
Normal file
42
Laboratorio 7/Esercizio 1/inv.h
Normal 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
|
||||
75
Laboratorio 7/Esercizio 1/invArray.c
Normal file
75
Laboratorio 7/Esercizio 1/invArray.c
Normal 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
|
||||
31
Laboratorio 7/Esercizio 1/invArray.h
Normal file
31
Laboratorio 7/Esercizio 1/invArray.h
Normal 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
|
||||
16
Laboratorio 7/Esercizio 1/inventario.txt
Normal file
16
Laboratorio 7/Esercizio 1/inventario.txt
Normal 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
|
||||
58
Laboratorio 7/Esercizio 1/pg.c
Normal file
58
Laboratorio 7/Esercizio 1/pg.c
Normal 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
|
||||
35
Laboratorio 7/Esercizio 1/pg.h
Normal file
35
Laboratorio 7/Esercizio 1/pg.h
Normal 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
|
||||
10
Laboratorio 7/Esercizio 1/pg.txt
Normal file
10
Laboratorio 7/Esercizio 1/pg.txt
Normal 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
|
||||
131
Laboratorio 7/Esercizio 1/pgList.c
Normal file
131
Laboratorio 7/Esercizio 1/pgList.c
Normal 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
|
||||
33
Laboratorio 7/Esercizio 1/pgList.h
Normal file
33
Laboratorio 7/Esercizio 1/pgList.h
Normal 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
|
||||
73
Laboratorio 7/Esercizio 2/Diagonali.c
Normal file
73
Laboratorio 7/Esercizio 2/Diagonali.c
Normal 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;
|
||||
}
|
||||
27
Laboratorio 7/Esercizio 2/Diagonali.h
Normal file
27
Laboratorio 7/Esercizio 2/Diagonali.h
Normal 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
|
||||
11
Laboratorio 7/Esercizio 2/Elementi.c
Normal file
11
Laboratorio 7/Esercizio 2/Elementi.c
Normal 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;
|
||||
}
|
||||
25
Laboratorio 7/Esercizio 2/Elementi.h
Normal file
25
Laboratorio 7/Esercizio 2/Elementi.h
Normal 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
|
||||
20
Laboratorio 7/Esercizio 2/elementi.txt
Normal file
20
Laboratorio 7/Esercizio 2/elementi.txt
Normal 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
|
||||
189
Laboratorio 7/Esercizio 2/main.c
Normal file
189
Laboratorio 7/Esercizio 2/main.c
Normal 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;
|
||||
}
|
||||
59
Laboratorio 7/Esercizio 2/testset_risulutati.txt
Normal file
59
Laboratorio 7/Esercizio 2/testset_risulutati.txt
Normal 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
|
||||
11
Laboratorio 8/Esercizio 1/Elementi.c
Normal file
11
Laboratorio 8/Esercizio 1/Elementi.c
Normal 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;
|
||||
}
|
||||
25
Laboratorio 8/Esercizio 1/Elementi.h
Normal file
25
Laboratorio 8/Esercizio 1/Elementi.h
Normal 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
|
||||
20
Laboratorio 8/Esercizio 1/elementi.txt
Normal file
20
Laboratorio 8/Esercizio 1/elementi.txt
Normal 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
|
||||
345
Laboratorio 8/Esercizio 1/main.c
Normal file
345
Laboratorio 8/Esercizio 1/main.c
Normal 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;
|
||||
}
|
||||
297
Laboratorio 8/Esercizio 1/main2.c
Normal file
297
Laboratorio 8/Esercizio 1/main2.c
Normal 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;
|
||||
}
|
||||
376
Laboratorio 8/Esercizio 1/mainlosttest.c
Normal file
376
Laboratorio 8/Esercizio 1/mainlosttest.c
Normal 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;
|
||||
}
|
||||
301
Laboratorio 8/Esercizio 1/mainstr.c
Normal file
301
Laboratorio 8/Esercizio 1/mainstr.c
Normal 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;
|
||||
}
|
||||
59
Laboratorio 8/Esercizio 1/testset_risulutati.txt
Normal file
59
Laboratorio 8/Esercizio 1/testset_risulutati.txt
Normal 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
|
||||
316
Laboratorio 8/Esercizio 2/Graph.c
Normal file
316
Laboratorio 8/Esercizio 2/Graph.c
Normal 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);
|
||||
}
|
||||
26
Laboratorio 8/Esercizio 2/Graph.h
Normal file
26
Laboratorio 8/Esercizio 2/Graph.h
Normal 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
|
||||
37
Laboratorio 8/Esercizio 2/Item.c
Normal file
37
Laboratorio 8/Esercizio 2/Item.c
Normal 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);
|
||||
}
|
||||
23
Laboratorio 8/Esercizio 2/Item.h
Normal file
23
Laboratorio 8/Esercizio 2/Item.h
Normal 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
|
||||
61
Laboratorio 8/Esercizio 2/ST.c
Normal file
61
Laboratorio 8/Esercizio 2/ST.c
Normal 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;
|
||||
}
|
||||
21
Laboratorio 8/Esercizio 2/ST.h
Normal file
21
Laboratorio 8/Esercizio 2/ST.h
Normal 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
|
||||
21
Laboratorio 8/Esercizio 2/grafo.txt
Normal file
21
Laboratorio 8/Esercizio 2/grafo.txt
Normal 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
|
||||
92
Laboratorio 8/Esercizio 2/main.c
Normal file
92
Laboratorio 8/Esercizio 2/main.c
Normal 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;
|
||||
}
|
||||
53
Laboratorio 8/Esercizio 3/Asset.c
Normal file
53
Laboratorio 8/Esercizio 3/Asset.c
Normal 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);
|
||||
}
|
||||
16
Laboratorio 8/Esercizio 3/Asset.h
Normal file
16
Laboratorio 8/Esercizio 3/Asset.h
Normal 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
|
||||
113
Laboratorio 8/Esercizio 3/AssetList.c
Normal file
113
Laboratorio 8/Esercizio 3/AssetList.c
Normal 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++;
|
||||
}
|
||||
18
Laboratorio 8/Esercizio 3/AssetList.h
Normal file
18
Laboratorio 8/Esercizio 3/AssetList.h
Normal 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
|
||||
36
Laboratorio 8/Esercizio 3/Datetime.c
Normal file
36
Laboratorio 8/Esercizio 3/Datetime.c
Normal 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
Reference in New Issue
Block a user