1
0
Files
2024-03-22 17:37:24 +01:00

189 lines
4.5 KiB
C

// 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;
}