189 lines
4.5 KiB
C
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;
|
|
} |