#include #include #include #include // Structure to keep information for each student // read from file "names" struct studs { char name[10]; int *DesiredClassE1; int *DesiredClassE2; int *NotDesiredClassE1; int *NotDesiredClassE2; int *SlackClassE1; int *SlackClassE2; int ind[6]; char FriendName1[10]; char FriendName2[10]; int InR1; int InR2; int locked1; int locked2; int OnSameTime; struct studs *next; }; // Typedefed declaration for easy of use typedef struct studs PERSON; // Instead of "struct studs" typedef PERSON *LINK; // Instead of "struct studs *" void Display_Message(int argc); int Read_parameter(char *inputfile, int *classesE1, int *classesE2, int *spaceE1, int *spaceE2, int *sameTimeE1, int *sameTimeE2, int *couples); void Help_Insert(char *tmp, char *dmp, void *var, FILE *fp, char type); int *v_get(int Nmax); void PrintList(LINK head); LINK Lexicographical(char *filename); void Allocate_In_LabE1(int classesE1, int *spaceE1, char ***roomsE1, LINK top, int *fullE1); void Allocate_In_LabE2(int classesE2, int *spaceE2, char ***roomsE2, LINK top, int *fullE2, int *sameTimeE1, int *sameTimeE2, int couples, int *fullE1, char ***roomsE1); void Print_Classes(int s, int classesE1, char ***roomsE1, int *fullE1); char ***m_get(int classes, int *space); int main(int argc, char **argv) { int classesE1; // The number of classes in E1 laboratory int classesE2; // The number of classes in E2 laboratory int couples; // The nymber of the couples int spaceE1[10]; // The stowage of eash class of E1 int spaceE2[10]; // The stowage of each class of E2 int sameTimeE1[10]; // Couple of classes on same time int sameTimeE2[10]; char ***roomsE1; char ***roomsE2; int *fullE1; int *fullE2; char *filename1 = argv[1]; // The file stored the initital parameters char *filename2 = argv[2]; // The file stored students information int i, j, x; LINK top = NULL; /* Displays a message if number of parameters is wrong */ Display_Message(argc); /* Read parameter values from file */ Read_parameter(filename1,&classesE1,&classesE2,spaceE1,spaceE2,sameTimeE1,sameTimeE2,&couples); /* Keeps space for each class for the names */ fullE1 = v_get(classesE1); fullE2 = v_get(classesE2); roomsE1 = m_get(classesE1,spaceE1); roomsE2 = m_get(classesE2,spaceE2); /* Does the lexicographical analysis */ top = Lexicographical(filename2); /* Allocate the students in the classes of lab E1 */ Allocate_In_LabE1(classesE1,spaceE1,roomsE1,top,fullE1); /* Allocate the students in the classes of lab E2 */ Allocate_In_LabE2(classesE2,spaceE2,roomsE2,top,fullE2,sameTimeE1,sameTimeE2,couples, fullE1,roomsE1); /* Prints the lists of students on the screen */ Print_Classes(1,classesE1,roomsE1,fullE1); Print_Classes(2,classesE2,roomsE2,fullE2); return 0; } // This function is used to allocate students into the classes of laboratory E1. void Allocate_In_LabE1(int classesE1, int *spaceE1, char ***roomsE1, LINK top, int *fullE1) { int i, j, t, x; LINK current = NULL; // current = &x; for(i = 0; i < classesE1; i++) { // At first we put only those who are locked. They cannot go enywhere else if(i == 0) { for(current = top; current != NULL; current=current->next) { // If he wants only this class. Lock him permanentaly if(current->ind[2] == (classesE1-1)) { int k = current->DesiredClassE1[0]; if(fullE1[k] < spaceE1[k]) { // Enter a student in the room roomsE1[k][fullE1[k]] = current->name; // Increase the number of fulled places in the room fullE1[k]++; current->InR1 = 1; current->locked1 = 1; } } } } else { // For the other choices for(current = top; current != NULL; current=current->next) { printf("i = %d\n ", i); if(current->locked1 == 1) continue; if(current->InR1 == 1) continue; // Look at the list of first preferences of a student for(t = 0; t < current->ind[0]; t++) { int k = current->DesiredClassE1[t]; if(fullE1[k] < spaceE1[k]) { // Enter a student in the room roomsE1[k][fullE1[k]] = current->name; // Increase the number of fulled places in the room fullE1[k]++; current->InR1 = 1; break; } } // Look at the list of slack preferences of a student if(current->InR1 != 1) { for(t = 0; t < current->ind[4]; t++) { int k = current->SlackClassE1[t]; if(fullE1[k] < spaceE1[k]) { // Enter a student in the room roomsE1[k][fullE1[k]] = current->name; // Increase the number of fulled places in the room fullE1[k]++; current->InR1 = 1; break; } } } // If the student can be inserted anywhrere, place him somewhere if(current->InR1 != 1) { for(t = 0; t < classesE1; t++) { if(fullE1[t] < spaceE1[t]) { // Enter a student in the room roomsE1[t][fullE1[t]] = current->name; // Increase the number of fulled places in the room fullE1[t]++; current->InR1 = 1; break; } } } } } // End of else } return; } // This function is used to allocate students into the classes of laboratory E2. void Allocate_In_LabE2(int classesE2, int *spaceE2, char ***roomsE2, LINK top, int *fullE2, int *sameTimeE1, int *sameTimeE2, int couples, int *fullE1, char ***roomsE1) { int i, j, t, l; int OnSameTime = 0; LINK current = NULL; for(i = 0; i < classesE2; i++) { // At first we put only those who are locked. They cannot go enywhere else if(i == 0) { for(current = top; current != NULL; current=current->next) { // If he wants only this class. Lock him permanentaly if(current->ind[3] == (classesE2-1)) { int k = current->DesiredClassE2[0]; if(fullE2[k] < spaceE2[k] ) { // If a student is the same time to the other lab, take care of that for(j = 0; j < couples; j++) { if( k == sameTimeE2[j]) { for(l = 0; l < fullE1[sameTimeE1[j]]; l++) if(current->name == roomsE1[sameTimeE1[j]][l]) OnSameTime = 1; } } if(OnSameTime != 1) { // Enter a student in the room roomsE2[k][fullE2[k]] = current->name; // Increase the number of fulled places in the room fullE2[k]++; current->locked2 = 1; // The student is locked in the room current->InR2 = 1; // The student is in a room } else OnSameTime = 0; } } } } else { // For the other choices for(current = top; current != NULL; current=current->next) { if(current->locked2 == 1) continue; if(current->InR2 == 1) continue; // Look at the list of first preferences of a student for(t = 0; t < current->ind[1]; t++) { int k = current->DesiredClassE2[t]; if(fullE2[k] < spaceE2[k]) { // If a student is the same time to the other lab, take care of that for(j = 0; j < couples; j++) { if( k == sameTimeE2[j]) { for(l = 0; l < fullE1[sameTimeE1[j]]; l++) if(current->name == roomsE1[sameTimeE1[j]][l]) OnSameTime = 1; } } if(OnSameTime != 1) { // Enter a student in the room roomsE2[k][fullE2[k]] = current->name; // Increase the number of fulled places in the room fullE2[k]++; // The student is in the room current->InR2 = 1; break; }else OnSameTime = 0; } } // Look at the list of slack preferences of a student if(current->InR2 != 1) { for(t = 0; t < current->ind[5]; t++) { int k = current->SlackClassE2[t]; if(fullE2[k] < spaceE2[k]) { // If a student is the same time to the other lab, take care of that for(j = 0; j < couples; j++) { if( k == sameTimeE2[j]) { for(l = 0; l < fullE1[sameTimeE1[j]]; l++) if(current->name == roomsE1[sameTimeE1[j]][l]) OnSameTime = 1; } } if(OnSameTime != 1) { // Enter a student in the room roomsE2[k][fullE2[k]] = current->name; // Increase the number of fulled places in the room fullE2[k]++; current->InR2 = 1; break; }else OnSameTime = 0; } } } // Check the student depended the restrictions if(current->InR2 != 1) { for(t = 0; t < classesE2; t++) { if(fullE2[t] < spaceE2[t]) { // If a student is the same time to the other lab, take care of that for(j = 0; j < couples; j++) { if( t == sameTimeE2[j]) { for(l = 0; l < fullE1[sameTimeE1[j]]; l++) if(current->name == roomsE1[sameTimeE1[j]][l]) OnSameTime = 1; } } if(OnSameTime != 1) { // Enter a student in the room roomsE2[t][fullE2[t]] = current->name; // Increase the number of fulled places in the room fullE2[t]++; current->InR2 = 1; break; } else { OnSameTime = 0; continue;} } } } // If the student can be inserted anywhrere, place him somewhere if(current->InR2 != 1) { for(t = 0; t < classesE2; t++) { if(fullE2[t] < spaceE2[t]) { // Enter a student in the room roomsE2[t][fullE2[t]] = current->name; // Increase the number of fulled places in the room fullE2[t]++; current->InR2 = 1; break; } } } } } // End of else } return; } // This function allocates memory for a two-dimensioned matrix and initializes its values. char ***m_get(int classes, int *space) { int i, j; char ***rooms; // We make a two-dimensioned matrix of char pointers. We will use it to // enter the names for E1 lab. if( (rooms = (char***)malloc(classes*sizeof(char**)) ) == NULL) perror("malloc"), exit(1); for(i = 0; i < classes; i++) if ( (rooms[i] = (char**)malloc(space[i]*sizeof(char*)) ) == NULL) perror("malloc"), exit(0); // Initialize matrix rooms with the value NONE for(i = 0; i < classes; i++) for(j = 0; j < space[i]; j++) rooms[i][j] = "NONE"; return rooms; } // This function prints on the screen the complete name list of students. Is s is 1 // then it prints the classes and the names of labE1. On the contrary, if s is 2, then // it prints information for labE2. void Print_Classes(int s, int classes, char ***rooms, int *full) { int t, j; if (s == 1) { printf("\nLABORATORY E1: (Lists of students)\n"); for(t = 0; t < classes; t++) { printf("CLASS [%d] : ", t); for(j = 0; j < full[t]; j++) printf("%s ",rooms[t][j]); printf("\n"); } printf("\n\n"); } else if( s == 2) { printf("LABORATORY E2: (Lists of students)\n"); for(t = 0; t < classes; t++) { printf("CLASS [%d] : ", t); for(j = 0; j < full[t]; j++) printf("%s ",rooms[t][j]); printf("\n"); } printf("\n\n"); } return; } // This function does the lexicographical analysis. We open a file named "names". This file // inlcudes the students and their preferences. We read the file line by line. Every line is // read as a string of characters. We analyse the string and get all information we need to // continue processing. LINK Lexicographical(char *filename) { // Variables used in lexicographical analysis int k, l; int time; int tmpNum[10]; char tmpName[10]; int down; int seen; int count; FILE *fp; // Pointer to struct FILE int i, j, m; // Used in for loops int NumOfStuds; // Keep the number of the students char tmp[100]; // Keep one line from the file LINK head = NULL; LINK new = NULL; // Checks if the file opens correctry for read if( (fp = (FILE*)fopen(filename,"r")) == NULL) perror("fopen"), exit(1); fgets(tmp,90,fp); //Get the first line fscanf(fp,"%d",&NumOfStuds); fgets(tmp,3,fp); for(i = 0; i < NumOfStuds; i++) { new = (LINK)malloc(sizeof(PERSON)); new->next = head; head = new; new->InR1 = 0; new->InR2 = 0; new->OnSameTime = 0; //Get the first line fgets(tmp,100,fp); time = 1; seen = 0; count = 1; k = l = 0; down = 1; // We do lexicographical analysis of this string for(j = 0; j < 100; j++) { if(isspace(tmp[j])) continue; // If you find a blank character continue // Gets the first name if(time == 1) { if(tmp[j] != '-') { tmpName[k++] = tmp[j]; continue; } else { tmpName[k] = '\0'; // Copy the tmpName1 to Name1 strcpy(new->name,tmpName); time = 2; k = 0; continue; } } // Gets the rest of the information if(isdigit(tmp[j]) && down == 1) { // Gets the information about classes char a[2]; // Store this information as integers a[0] = tmp[j]; a[1] = '\0'; tmpNum[l++] = atoi(a); continue; } else { //This part of code constructs the arrays of classes for each student if(count == 1) { new->DesiredClassE1 = v_get(l); for(m = 0; m < l; m++) new->DesiredClassE1[m] = tmpNum[m]; new->ind[0] = l; count++; l = 0; }else if(count == 2) { new->DesiredClassE2 = v_get(l); for(m = 0; m < l; m++) new->DesiredClassE2[m] = tmpNum[m]; new->ind[1] = l; count++; l = 0; }else if(count == 3) { new->NotDesiredClassE1 = v_get(l); for(m = 0; m < l; m++) new->NotDesiredClassE1[m] = tmpNum[m]; new->ind[2] = l; count++; l = 0; }else if(count == 4) { new->NotDesiredClassE2 = v_get(l); for(m = 0; m < l; m++) new->NotDesiredClassE2[m] = tmpNum[m]; new->ind[3] = l; count++; l = 0; }else if(count == 5) { new->SlackClassE1 = v_get(l); for(m = 0; m < l; m++) new->SlackClassE1[m] = tmpNum[m]; new->ind[4] = l; count++; l = 0; }else if(count == 6) { new->SlackClassE2 = v_get(l); for(m = 0; m < l; m++) new->SlackClassE2[m] = tmpNum[m]; new->ind[5] = l; count++; l = 0; } // Gets the second name. First friend's name if(time == 2) { if(tmp[j] != '-') { down = 2; tmpName[k++] = tmp[j]; seen = 1; continue; } else { if(seen == 1) { tmpName[k] = '\0'; strcpy(new->FriendName1,tmpName); time = 3; k = 0; continue; } else continue; } } // Gets the third name. Second friend's name if(time == 3) { if(tmp[j] != '-') { down = 2; tmpName[k++] = tmp[j]; continue; } else { tmpName[k] = '\0'; strcpy(new->FriendName2,tmpName); time = 3; continue; } } } } } fclose(fp); return head; } // Function which prints the contents of the linked list void PrintList(LINK head) { LINK current; int j; for(current = head; current != NULL; current=current->next) { for(j = 0; j < current->ind[0]; j++) printf("%d ", current->DesiredClassE1[j]); printf(" | "); for(j = 0; j < current->ind[1]; j++) printf("%d ", current->DesiredClassE2[j]); printf(" | "); for(j = 0; j < current->ind[2]; j++) printf("%d ", current->NotDesiredClassE1[j]); printf(" | "); for(j = 0; j < current->ind[3]; j++) printf("%d ", current->NotDesiredClassE2[j]); printf(" | "); for(j = 0; j < current->ind[4]; j++) printf("%d ", current->SlackClassE1[j]); printf(" | "); for(j = 0; j < current->ind[5]; j++) printf("%d ", current->SlackClassE2[j]); printf(" | \n"); printf("Name = %s\n", current->name); //printf("FName1 = %s\n", current->FriendName1); //printf("FName2 = %s\n", current->FriendName2); printf("Locked1 = %d\n", current->locked1); printf("Locked2 = %d\n", current->locked2); } return; } /*Function which controls if have inserted all the needed parameters from * the command line.the proper usage is './a.out filename'.If the name of the * filename does not exist then a message displayed on the screen*/ void Display_Message(int argc) { system("clear"); if(argc != 3) { fprintf(stdout,"\nError: Wrong number of parameters..."); fprintf(stdout,"\n\nUsage:\n ./x filename1 filename2\n"); fprintf(stdout,"\n\n Where:"); fprintf(stdout,"\n\tfilename1 = \"The name of input data file\"\n\n"); fprintf(stdout,"\n\tfilename2 = \"The name of students info file\"\n\n"); exit(1); } return; } /*This function read all program parameters and store them at the variables.The * name of the file is given from the command line. This function return a * value may be used for error handling*/ int Read_parameter(char *inputfile, int *classesE1, int *classesE2, int *spaceE1, int *spaceE2, int *sameTimeE1, int *sameTimeE2, int *couples) { FILE *fp1; char tmp[80], dmp[3]; int i; if( (fp1 = (FILE*)fopen(inputfile,"r+")) == NULL ) fprintf(stderr,"Error opening file.\n"), exit(1); Help_Insert(tmp,dmp,&(*classesE1),fp1,'i'); Help_Insert(tmp,dmp,&(*classesE2),fp1,'i'); for(i = 0; i < *classesE1; i++) Help_Insert(tmp,dmp,&(spaceE1[i]),fp1,'i'); for(i = 0; i < *classesE2; i++) Help_Insert(tmp,dmp,&(spaceE2[i]),fp1,'i'); Help_Insert(tmp,dmp,&(*couples),fp1,'i'); for(i = 0; i < (*couples); i++) { Help_Insert(tmp,dmp,&(sameTimeE1[i]),fp1,'i'); Help_Insert(tmp,dmp,&(sameTimeE2[i]),fp1,'i'); } fclose(fp1); return 0; } /*function which provides us a method to insert the values from the data * file with the call of one function for each variable*/ void Help_Insert(char *tmp, char *dmp, void *var, FILE *fp, char type) { switch (type) { case 'i': { fgets(tmp,80,fp); fscanf(fp,"%d",&(*((int *)var))); fgets(dmp,3,fp); break; } case 'd': { fgets(tmp,80,fp); fscanf(fp,"%lf",&(*((double *)var))); fgets(dmp,3,fp); break; } } return; } /*Sunarthsh poy elegxei an yparxei xwros na desmeytei apo thn malloc*/ /*Xrhsimopoieitai gia th dhmioyrgreia dianysmatwn*/ int *v_get(int Nmax) { register int i; int *ptr; ptr = (int*)malloc((Nmax+1)*sizeof(int)); if(ptr == NULL) { fprintf(stdout,"Not enough memory to allocate the buffer\n\n"); exit(1); } for(i = 0; i < Nmax+1; i++) *(ptr+i) = 0.; return ptr; }