I needed help coding the functions in bold in the code given below. (1) enroll -
ID: 3853072 • Letter: I
Question
I needed help coding the functions in bold in the code given below.
(1) enroll - Attempt to enroll the student in the course
(2) addSeats - Add the specified number of seats to the course and adds students from the waitlist to fill these seats
(3) drop - Drop the student from the course and fill the empty seat from the waitlist
Some code has been provided for you to help in creating functions to execute the above three operations. In addition to the above you also need to implement your priority queue using a doubly linked list. Specifically,
(1) enqueue - Add a new waitlist element to the priority queue. This element needs to be inserted in sorted order.
(2) dequeue - Remove and return the front element from the LL.
Code Provideed:
data in a3_CourseData.txt
Explanation / Answer
Here is completed code for the question.
Please note: the input file containing course data should have 1st line containing the number of courses. The main function (given in question) expects the number of courses to be in first line. So the input format of a3_CourseData.txt given in the question is wrong. You need the 1st line to be 4 and then followed by whatever is given there. So please make sure to follow this format, otherwise the code will not function correctly. Hope I am conveyed clearly.
Also assuming priority queue should be in descending order . For example, students with priority 1, 2, 4 will be in queue as 4, 2 ,1 so that 4 has maximum priority. If you want to consider 1 as highest priority the program needs to be changed. Let me know if that is the case.
In case of any doubt, please post a comment and I will respond.
If the answer helped, don't forget to rate it. Thank you very much.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
int iPriority; /* Priority of the student to be enrolled */
int iStudentID; /* ID of the student */
} WaitlistEntry;
typedef struct PQNode {
WaitlistEntry info; /* WaitlistEntry stored in the node (sorted with largest priority first) */
struct PQNode* pNext; /* Pointer to next node in the LL */
struct PQNode* pPrev; /* Pointer to previous node in the LL */
} PQNode;
typedef struct{
int iCourseNumber; /* Course number of the course */
int* iStudentIDs; /* Array of IDs of students enrolled in the course */
int iNumEnrolled; /* Number of Students currently enrolled in course */
int iMaxEnrolled; /* Max number of Students that can enroll in the course */
PQNode* pFront; /* Priority queue representing the waitlist for the course */
} Course;
typedef enum { FALSE, TRUE } bool;
/* PQ function prototypes */
void printQueue( PQNode* pFront );
/* To be completed by you */
WaitlistEntry dequeue( PQNode** ppFront );
void enqueue( PQNode** ppFront, WaitlistEntry info );
/* function prototypes for course management */
void enrollStudent( Course* pCourse, int iStudentID );
void waitlistStudent( Course* pCourse, WaitlistEntry wl );
int searchCourses( Course* pCourses, int iNumCourses, int iCourseID );
int findStudent( Course* pCourse, int iStudentID );
/* To be completed by you */
void addSeats( Course* pCourse, int NumAdded );
void attemptEnrollment( Course* pCourse, int iStudentID, int iPriority );
void dropStudent( Course* pCourse, int iStudentID );
/* provided code - DO NOT CHANGE
* main simulates the waitlist for a number of courses by calling your functions
*/
int main( )
{
char courseFileName[] = "a3_CourseData.txt";
char enrollFileName[] = "a3_EnrollData.txt";
char szCommand[256];
FILE *in_file = fopen(courseFileName, "r");
Course *pCourses;
int i;
int iNumCourses;
int iCourseNumber;
int iCourse;
int iStudent;
int iPriority;
int iNumAdd;
printf("CS 2123 Assignment 3 ");
if (in_file == NULL)
{
printf("File %s not found. ", courseFileName);
return -1;
}
/* read the number of courses from file and allocate space to store them */
fscanf( in_file, "%d", &iNumCourses );
pCourses = (Course*) malloc( iNumCourses*sizeof(Course) );
/* initialize course data */
for( i=0 ; i<iNumCourses; i++){
if( fscanf( in_file, "%d %d", &pCourses[i].iCourseNumber, &pCourses[i].iMaxEnrolled )!=2 )
break;
pCourses[i].iStudentIDs = (int*) malloc( pCourses[i].iMaxEnrolled*sizeof(int) );
pCourses[i].iNumEnrolled = 0;
pCourses[i].pFront = NULL;
}
fclose(in_file);
/* open enrollment data file */
in_file = fopen(enrollFileName, "r");
if (in_file == NULL)
{
printf("File %s not found. ", enrollFileName);
return -1;
}
/* reads enrollment data and calls your functions to handle the commands */
while( !feof(in_file) ){
if(fscanf( in_file, "%s", szCommand)!=1 )
break;
if( strcmp(szCommand, "enroll")==0 ){
fscanf( in_file, "%d %d %d", &iCourse, &iStudent, &iPriority );
iCourseNumber = searchCourses( pCourses, iNumCourses, iCourse );
attemptEnrollment( &pCourses[iCourseNumber], iStudent, iPriority );
}
else if( strcmp(szCommand, "addSeats")==0 ){
fscanf( in_file, "%d %d", &iCourse, &iNumAdd);
iCourseNumber = searchCourses( pCourses, iNumCourses, iCourse );
addSeats( &pCourses[iCourseNumber], iNumAdd );
}
else if( strcmp(szCommand, "drop")==0 ){
fscanf( in_file, "%d %d", &iCourse, &iStudent);
iCourseNumber = searchCourses( pCourses, iNumCourses, iCourse );
dropStudent( &pCourses[iCourseNumber], iStudent );
}
printf(" " );
}
fclose(in_file);
/* Free course data */
for( i=0 ; i<iNumCourses; i++){
free( pCourses[i].iStudentIDs );
}
free( pCourses );
return 0;
}
/* provided code - DO NOT CHANGE
* search courses for one with iCourseNumber equal to iCourseID and return its index in the pCourses array
* returns -1 if the course is not found
*/
int searchCourses( Course* pCourses, int iNumCourses, int iCourseID ){
int i;
for( i=0; i<iNumCourses; i++ ){
if( pCourses[i].iCourseNumber==iCourseID )
return i;
}
return -1;
}
/* provided code - DO NOT CHANGE
* search the given course's iStudentIDs for an enrolled student.
* If the student is found it returns their index in the iStudentIDs array
* returns -1 if the iStudentID is not found
*/
int findStudent( Course* pCourse, int iStudentID ){
int i;
for( i=0; i<pCourse->iNumEnrolled; i++ ){
if( pCourse->iStudentIDs[i]==iStudentID )
return i;
}
return -1;
}
/*
* addSeats increases the maximum enrollment of the course by NumAdded.
* Use realloc to increase the number of student IDs which can be storexd in pCourse.
* dequeue students from the waitlist call enrollStudent on them to add them to the
* course until the course is full or the waitlist is empty.
*
* precondition: NumAdded > 0
*/
void addSeats( Course* pCourse, int NumAdded ){
WaitlistEntry wl;
/* increase the maximum enrollment of pCourse */
pCourse->iMaxEnrolled += NumAdded;
/* Print that seats have been added to the course (no changes needed to this line) */
printf("Added Seats: %d seats added to the course %d ", NumAdded, pCourse->iCourseNumber );
/* add students to the course until it is full or the waitlist is empty */
pCourse->iStudentIDs = realloc(pCourse->iStudentIDs, pCourse->iMaxEnrolled *sizeof(int) );
while(pCourse->pFront != NULL && pCourse->iNumEnrolled < pCourse->iMaxEnrolled)
{
wl = dequeue(&pCourse->pFront);
enrollStudent(pCourse, wl.iStudentID);
}
}
/*
* attemptEnrollment attempts to enroll the given student in the course pCourse.
* If there is room left in the course call enrollStudent to add the student.
* Otherwise call waitlistStudent to add the student to the course's waitlist.
*/
void attemptEnrollment( Course* pCourse, int iStudentID, int iPriority ){
printf("attempt: %d in %d ", iStudentID, pCourse->iCourseNumber );
if(pCourse->iNumEnrolled < pCourse->iMaxEnrolled)
{
enrollStudent(pCourse, iStudentID);
}
else
{
WaitlistEntry wl;
wl.iStudentID = iStudentID;
wl.iPriority = iPriority;
waitlistStudent(pCourse, wl);
}
}
/* provided code - DO NOT CHANGE
* enrolls the given student in the given course
*
* precondition: the course has room left in it to enroll the student
*/
void enrollStudent( Course* pCourse, int iStudentID ){
if( pCourse->iMaxEnrolled <= pCourse->iNumEnrolled ){
printf("ERROR - enrollStudent called with a full course %d ", pCourse->iCourseNumber );
return;
}
pCourse->iStudentIDs[pCourse->iNumEnrolled] = iStudentID;
pCourse->iNumEnrolled++;
printf("Enrolled: %d in %d ", iStudentID, pCourse->iCourseNumber );
}
/* provided code - DO NOT CHANGE
* adds the given student to the courses waitlist
*
* precondition: the course is full
*/
void waitlistStudent( Course* pCourse, WaitlistEntry wl ){
if( pCourse->iMaxEnrolled > pCourse->iNumEnrolled ){
printf("ERROR - waitlistStudent called with a non-full course %d ", pCourse->iCourseNumber );
return;
}
enqueue( &pCourse->pFront, wl );
printf("Waitlisted: %d in %d ", wl.iStudentID, pCourse->iCourseNumber );
printf("Current waitlist: " );
printQueue( pCourse->pFront );
}
/*
* dropStudent drops the given student from the course.
* If the waitlist is not empty you should dequeue the first student and enroll them in the now non-full course.
* It should print an error if the student to be dropped is not enrolled in the course.
*/
void dropStudent( Course* pCourse, int iStudentID ){
/* Use findStudent to determine where student is in iStudentIDs array */
WaitlistEntry wl;
int index = findStudent(pCourse, iStudentID);
int i;
if(index == -1 ){
printf("ERROR - dropStudent called to drop non-enrolled student %d from %d ", iStudentID, pCourse->iCourseNumber );
return;
}
/* Use a loop to shift down students in iStudentIDs array and fill gap from the dropped student */
for(i = index; i < pCourse->iNumEnrolled - 1; i++)
{
pCourse->iStudentIDs[i] = pCourse->iStudentIDs[i+1];
}
pCourse->iNumEnrolled--;
/* Print that student has been dropped from the course (no changes needed to this line) */
printf("Dropped: %d from %d ", iStudentID, pCourse->iCourseNumber );
/* Add student if the waitlist is not empty */
if(pCourse->pFront != NULL)
{
wl = dequeue(&pCourse->pFront);
enrollStudent(pCourse, wl.iStudentID);
}
}
/*
* insert a new node which contains info into the priority queue contained in the linked list pointed to by ppFront
*/
void enqueue( PQNode** ppFront, WaitlistEntry info ){
/* create a new node to store the info */
PQNode* node = (PQNode*)malloc(sizeof(PQNode));
PQNode *curr;
node->info = info;
node->pNext = NULL;
node->pPrev = NULL;
/* check if the LL is empty and add the new node to the front if it is */
if(*ppFront == NULL)
{
*ppFront = node;
return;
}
/* check if the new node should come before the first node in the LL */
if(node->info.iPriority > (*ppFront)->info.iPriority)
{
(*ppFront)->pNext = node;
node->pPrev = *ppFront;
*ppFront = node;
}
else
{
/* walk back through the previous nodes in the LL until the correct insertion point is found */
/* remember to also check whether the previous node is NULL */
curr = *ppFront;
while(curr->info.iPriority >= node->info.iPriority)
{
if(curr->pPrev == NULL) //should insert node in end
{
node->pNext = curr;
curr->pPrev = node;
return;
}
curr = curr->pPrev;
}
/* insert the new node into the place you found with your loop */
/* note you may need a special case for when the previous node is NULL */
node->pNext = curr->pNext;
curr->pNext = node;
node->pPrev = curr;
node->pNext->pPrev = node;
}
}
/*
* remove the node at the front of the priority queue and return its info
*
* precondition: the queue is not empty
*/
WaitlistEntry dequeue( PQNode** ppFront ){
WaitlistEntry ret;
if(*ppFront != NULL)
{
ret = (*ppFront)->info;
*ppFront = (*ppFront)->pPrev;
}
return ret;
}
/* provided code - DO NOT CHANGE
* print the contents of the priority queue contained in the linked list pointed to by ppFront
*/
void printQueue( PQNode* pFront ){
while( pFront!=NULL ){
printf("%d ", pFront->info.iStudentID);
pFront = pFront->pPrev;
}
printf(" ");
}
input file : a3_CourseData.txt (*** NOTE the 1st line has number of courses)
4
2123 5
2233 5
3333 5
3343 0
input file : a3_EnrollData.txt
enroll 2123 100 1
enroll 2123 101 4
enroll 2123 102 2
enroll 2123 103 3
enroll 2123 104 1
enroll 2123 109 1
enroll 2123 105 4
enroll 2123 108 2
enroll 2123 106 4
enroll 2123 107 3
addSeats 2123 1
addSeats 2123 2
drop 2123 101
drop 2123 100
drop 2123 103
enroll 3343 100 1
enroll 3343 101 4
enroll 3343 102 2
addSeats 3343 5
enroll 3343 103 3
addSeats 3343 2
output
CS 2123 Assignment 3
attempt: 100 in 2123
Enrolled: 100 in 2123
attempt: 101 in 2123
Enrolled: 101 in 2123
attempt: 102 in 2123
Enrolled: 102 in 2123
attempt: 103 in 2123
Enrolled: 103 in 2123
attempt: 104 in 2123
Enrolled: 104 in 2123
attempt: 109 in 2123
Waitlisted: 109 in 2123
Current waitlist: 109
attempt: 105 in 2123
Waitlisted: 105 in 2123
Current waitlist: 105 109
attempt: 108 in 2123
Waitlisted: 108 in 2123
Current waitlist: 105 108 109
attempt: 106 in 2123
Waitlisted: 106 in 2123
Current waitlist: 105 106 108 109
attempt: 107 in 2123
Waitlisted: 107 in 2123
Current waitlist: 105 106 107 108 109
Added Seats: 1 seats added to the course 2123
Enrolled: 105 in 2123
Added Seats: 2 seats added to the course 2123
Enrolled: 106 in 2123
Enrolled: 107 in 2123
Dropped: 101 from 2123
Enrolled: 108 in 2123
Dropped: 100 from 2123
Enrolled: 109 in 2123
Dropped: 103 from 2123
attempt: 100 in 3343
Waitlisted: 100 in 3343
Current waitlist: 100
attempt: 101 in 3343
Waitlisted: 101 in 3343
Current waitlist: 101 100
attempt: 102 in 3343
Waitlisted: 102 in 3343
Current waitlist: 101 102 100
Added Seats: 5 seats added to the course 3343
Enrolled: 101 in 3343
Enrolled: 102 in 3343
Enrolled: 100 in 3343
attempt: 103 in 3343
Enrolled: 103 in 3343
Added Seats: 2 seats added to the course 3343