// Laboratorio 7 - Esercizio 2 - main.c // Matteo Schiff - s295565 #include #include #include #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 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; }