CS249-Projects/PA04-0927/PA04_Main.c
cdez 000ba2fb13 GUR Prettify
+- PA04_Main.c
2023-09-27 13:17:08 -07:00

262 lines
8.8 KiB
C

// header files
#include <string.h>
#include "StandardConstants.h"
#include "File_Input_Utility.h"
#include "BasicUtilities.h"
#include "CourseUtilities.h"
#include "RoomUtilities.h"
// local constants
const int MAX_NUM_ROOMS = 25;
const int MAX_NUM_COURSES = 25;
const int NO_CLASS = -1;
// local prototypes
bool fitClassRooms( CourseArrayType *courseData,
RoomArrayType *roomData, int initialRoomLevel, bool verboseFlag );
bool uploadData( const char *fileName,
CourseArrayType *courseData, RoomArrayType *roomData );
// main function
int main( int argc, char **argv )
{
int initialRoomLevel = 0;
RoomArrayType *rooms;
CourseArrayType *courses;
bool verboseSetting = true;
printf( "\nCourse/Classroom Fit Program\n" );
printf( "============================\n" );
rooms = createRoomArray( MAX_NUM_ROOMS );
courses = createCourseArray( MAX_NUM_COURSES );
if( uploadData( "InputFiles/in_6.txt", courses, rooms ) )
{
printf( "Start Solution Search\n" );
if( fitClassRooms( courses, rooms, initialRoomLevel, verboseSetting ) )
{
printf( "\nFit Classroom Success: Solution Found.\n");
displayList( courses, rooms );
}
else
{
printf( "\nFit Classroom Failure: Solution not found.\n");
}
}
else
{
printf( "Upload failure\n" );
}
// end program
// clear data
rooms = clearRoomArray( rooms );
courses = clearCourseArray( courses );
// show program end
printf( "\nEnd Course/Classroom Fit Program\n" );
// return success
return 0;
}
/*
Name: fitClassRooms
Process: implements brute force recursive backtracking strategy
to fit specified courses with their specified student size
into classrooms with their specified capacity
Function input/parameters: pointer to a courses array type (CourseArrayType *),
pointer to a room array type (RoomArrayType *),
room level shows which room is seeking a course
and indicates the recursion level (int),
verbose flag that specifies whether
to display the recursive backtracking process (bool)
Function output/parameters: updated courses file (CourseArrayType *),
updated rooms file (RoomArrayType *)
Function output/returned: Boolean result of the process (bool)
Device input/---: none
Device output/---: none
Dependencies: available tools as needed
*/
bool fitClassRooms( CourseArrayType *courses,
RoomArrayType *rooms, int roomLevel, bool verboseFlag )
{
int arrayIterator;
RoomDataType tempClassRoom;
CourseDataType tempCourse;
char buildingString[STD_STR_LEN];
char courseString[STD_STR_LEN];
// If all courses have been placed
// return true
if(roomLevel == rooms->size)
{
return true;
}
// setup for current classroom
deepCopyRoom(&tempClassRoom, rooms->array[roomLevel]);
deepCopyCourse(&tempCourse, courses->array[roomLevel]);
setRoomDataString(buildingString, tempClassRoom);
if(verboseFlag)
{
printf("\nRecursion Level %d: Seeking a fit for %s\n",
roomLevel, buildingString);
}
for(arrayIterator = 0; arrayIterator < courses->size; arrayIterator++)
{
if(verboseFlag)
{
printSpaces(2);
}
// For Loop (Increments through courses)
if(courses->array[arrayIterator].available &&
tempClassRoom.roomCapacity > courses->array[arrayIterator].size)
{
// Test to find classroom
// If open and less than course size
// Set classroom associated index to course
rooms->array[roomLevel].associatedIndex = arrayIterator;
// Set course as unavailable
courses->array[arrayIterator].available = false;
setCourseDataString(courseString, courses->array[arrayIterator]);
if(verboseFlag)
{
printSpaces(2);
printf("Trying Course Name: %s, Course Size: %d - Success!\n",
courses->array[arrayIterator].courseName,
courses->array[arrayIterator].size);
printSpaces(6);
printf("Course Name: %s, Course Size: %d will fit in %s\n",
tempCourse.courseName, tempCourse.size, buildingString);
}
// Call and check next recursion
if(fitClassRooms(courses, rooms, roomLevel + 1, verboseFlag))
{
return true;
}
// Unset classroom associated index to course
tempClassRoom.associatedIndex = NO_CLASS;
// Set course as available
courses->array[arrayIterator].available = true;
}
if(verboseFlag)
{
printf(" Trying Course Name: %s, Course Size: %d - Failed!\n",
courses->array[arrayIterator].courseName,
courses->array[arrayIterator].size);
}
// end for loop
}
if(verboseFlag)
{
printf("\nCourse Name: %s, Course Size: %d - recursion fell back to Recursion Level %d\n",
tempCourse.courseName, tempCourse.size, roomLevel - 1);
printSpaces(2);
}
return false;
}
/*
Name: uploadData
Process: uploads data file containing rooms available and courses to be fitted,
has internal flag to show uploaded data or not
Function input/parameters: file name (const char *),
pointer to course array type (CourseArrayType*),
pointer to room array type (RoomArrayType *)
Function output/parameters: updated courses file (CourseArrayType *),
updated rooms file (RoomArrayType *)
Function output/returned: Boolean result of the process (bool)
Device input/---: none
Device output/---: none
Dependencies: as needed, including File Input Utilities, and strcmp
*/
bool uploadData( const char *fileName,
CourseArrayType *courseData, RoomArrayType *roomData )
{
char tempStr[ STD_STR_LEN ];
int tempRoomNum, tempRoomCapacity, tempRoomAssociation = NO_CLASS;
int tempClassSize, tempClassAvailable = true;
bool verboseFlag = true;
roomData->size = 0;
if( openInputFile( fileName ) )
{
if( verboseFlag )
{
printf( "\n==========Upload start\n" );
}
// ignore first line
readStringToLineEndFromFile( tempStr );
// capture first room line - prime loop
readStringToDelimiterFromFile( COMMA, tempStr );
// loop to end of room data
while( strcmp( tempStr, "End Room Data" ) != 0
&& roomData->size < roomData->capacity )
{
tempRoomNum = readIntegerFromFile();
readCharacterFromFile();
tempRoomCapacity = readIntegerFromFile();
if( verboseFlag )
{
printf( "Nm: %s, Num: %d, cap: %d\n",
tempStr, tempRoomNum, tempRoomCapacity );
}
addRoomWithData( roomData, tempStr,
tempRoomNum, tempRoomCapacity, tempRoomAssociation );
// reprime - capture next building name, or end of data string
readStringToDelimiterFromFile( COMMA, tempStr );
}
// initialize class size
courseData->size = 0;
// ignore first line
readStringToLineEndFromFile( tempStr );
// capture first course line - prime loop
readStringToDelimiterFromFile( COMMA, tempStr );
// loop to end of course data
while( strcmp( tempStr, "End Class Data" ) != 0
&& courseData->size < courseData->capacity )
{
// get class size
tempClassSize = readIntegerFromFile();
if( verboseFlag )
{
printf( "Nm: %s, sz: %d\n", tempStr, tempClassSize );
}
addCourseWithData( courseData,
tempStr, tempClassSize, tempClassAvailable );
// reprime - get next building name, or end of data string
readStringToDelimiterFromFile( COMMA, tempStr );
}
if( verboseFlag )
{
printf( "==========Upload end\n\n" );
}
return true;
}
return false;
}