feat: Initial commit
This commit is contained in:
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;
|
||||
}
|
||||
Reference in New Issue
Block a user