/*
	Soluz. Compito Esame Fondamenti di Informatica (Amb. & Territorio),
	a cura del docente. 14 luglio 1999.
*/

#include <stdio.h>
#include <stdlib.h>

#define NTERM 3
#define NGATE 3
/* numero terminali e numero gate */

#define MAXLUNGH 21
/* max lunghezza del nome di un file */

typedef unsigned short tipogate;
typedef char tipoterm;
typedef unsigned tipopasseggeri;

typedef char nomefile[MAXLUNGH];


/* opportuna struttura dati richiesta al punto 1: una matrice */
typedef tipopasseggeri tipopartenze[NTERM][NGATE];
/* I riga associata a terminale 'A', II a 'B' ecc. */
/* per accedere agli elementi della matrice, dati terminale e gate
   usiamo le funzioni riga e colonna
   riga_1 e colonna_1 rappresentano le funzioni inverse */

typedef struct elem {
	tipoterm term;
	tipogate gate;
	tipopasseggeri pass;
	struct elem *next;
} elista;


/* prototipi */
	int main(void);
	void LeggiStrutturaDaFile(tipopartenze, nomefile);
	int Riga(tipoterm);
	int Colonna(tipogate);
	tipoterm Riga_1(int);
	tipogate Colonna_1(int);
	void AzzeraStruttura(tipopartenze);
	void LeggiRiga(FILE *, tipoterm *, tipogate *, tipopasseggeri *);
	void StampaStruttura(tipopartenze);
	elista *CostruisciLista(tipopartenze, tipopasseggeri);
	elista *Crea(tipoterm, tipogate, tipopasseggeri);
	void InTesta(elista **, elista *);
	void StampaLista(elista *);

main(void)
{
	tipopartenze partenze;
	elista *lista;
	nomefile nome;
	tipopasseggeri n;
	
	printf("Inserisci il nome del file partenze: ");
	gets(nome);

	LeggiStrutturaDaFile(partenze,nome);
	StampaStruttura(partenze);
	
	printf("Inserisci numero passeggeri per lista: ");
	scanf("%u",&n);
	getchar();

	lista=CostruisciLista(partenze,n);
	StampaLista(lista);
	
	return 0;
}


void LeggiStrutturaDaFile(tipopartenze p, nomefile z)
/* funz. richiesta al punto 2 */
{
	FILE *f;
	tipoterm t;
	tipogate g;
	tipopasseggeri n;
	
	AzzeraStruttura(p); /* azzera, cosi` le celle non lette contengono zero */
	
	f=fopen(z,"r");
	if(f==NULL) {
		fprintf(stderr, "Impossibile aprire il file \"%s\" in modalita` \"r\". Stop.\n",z
		);
		exit(1);
	}
	
	LeggiRiga(f, &t, &g, &n);
	while(!feof(f)) {
		p[Riga(t)][Colonna(g)]=n;
		LeggiRiga(f, &t, &g, &n);
	}
	
	fclose(f);
	return;
}


int Riga(tipoterm t)
/* dato nome di un terminale, restituisce indice di riga relativa nella matrice */
{
	return t-'A';
}



int Colonna(tipogate g)
/* dato nome di un gate, restituisce indice di colonna relativa nella matrice */
{
	return g-1;
}


tipoterm Riga_1(int i)
/* dato l'indice di riga di una matrice, restituisce nome terminale corrispondente */
{
	return 'A'+i;
}


tipogate Colonna_1(int j)
/* dato l'indice di colonna di una matrice, restituisce codice gate corrispondente */
{
	return j+1;
}


void AzzeraStruttura(tipopartenze zz)
{
	int i,j;
	for(i=0;i<NTERM;i++)
		for(j=0;j<NGATE;j++)
			zz[i][j]=0;
	return;
}

void LeggiRiga(FILE *f, tipoterm *t, tipogate *g, tipopasseggeri *n)
{
	fscanf(f,"%c %hu %u", t, g, n);
	fgetc(f); /* per consumare '\n' */
	return;
}


void StampaStruttura(tipopartenze p)
{
	int i, j;
	
	for(i=0; i<NTERM; i++)
		for(j=0; j<NGATE; j++)
			printf("%c %d %u\n", Riga_1(i), Colonna_1(j), p[i][j]);
	return;
}


elista *CostruisciLista(tipopartenze p, tipopasseggeri n)
/* funz. richiesta al punto 3 */
{
	int i,j;
	elista *testa=NULL, *nuovo;
	
	/* scandisco la matrice alla rovescia, cosi`
	   posso costruire la lista con gli elementi nell'ordine
	   richiesto semplicemente inserendo in testa */
	for(i=NTERM-1;i>=0;i--)
		for(j=NGATE-1;j>=0;j--)
			if(p[i][j]<=n) {
				nuovo=Crea(Riga_1(i),Colonna_1(j),p[i][j]);
				InTesta(&testa,nuovo);
			}
	return testa;
}


elista *Crea(tipoterm t, tipogate g, tipopasseggeri n)
{
	elista *nuovo;
	nuovo=malloc(sizeof(elista));
	if(nuovo==NULL) {
		fprintf(stderr,"malloc fallita. Programma terminato.\n");
		exit(2);
	}
	nuovo->term=t;
	nuovo->gate=g;
	nuovo->pass=n;
	nuovo->next=NULL;
	return nuovo;
}


void InTesta(elista **e, elista *nuovo)
{
	nuovo->next=*e;
	*e=nuovo;
	return;
}


void StampaLista(elista *p)
{
	for(; p!=NULL; p=p->next)
		printf("TERM=%c GATE=%hu PASSEGGERI=%u\n",p->term,p->gate,p->pass);
	return;
}