#include #include // Data structures and helper functions typedef struct DiskRequest { int position; int time; } DiskRequest; typedef struct DiskQueue { DiskRequest *requests; int size; } DiskQueue; DiskQueue *createDiskQueue() { DiskQueue *queue = malloc(sizeof(DiskQueue)); if (queue == NULL) { printf("Error allocating memory for queue\n"); exit(EXIT_FAILURE); } queue->requests = malloc(sizeof(DiskRequest)); if (queue->requests == NULL) { printf("Error allocating memory for queue requests\n"); exit(EXIT_FAILURE); } queue->size = 0; return queue; } DiskRequest diskRequest(int position, int time) { DiskRequest request; request.position = position; request.time = time; return request; } void enqueue(DiskQueue *queue, DiskRequest request) { queue->requests = realloc(queue->requests, sizeof(DiskRequest) * (queue->size + 1)); if (queue->requests == NULL) { printf("Error reallocating memory for queue requests\n"); exit(EXIT_FAILURE); } queue->requests[queue->size] = request; queue->size++; } DiskRequest delete(DiskQueue *queue, DiskRequest request) { // Find the index of the request int index = -1; for (int i = 0; i < queue->size; i++) { if (queue->requests[i].position == request.position && queue->requests[i].time == request.time) { index = i; break; } } if (index == -1) { printf("Error: Request not found in queue\n"); exit(EXIT_FAILURE); } // Shift all the elements after the index down one for (int i = index; i < queue->size - 1; i++) { queue->requests[i] = queue->requests[i + 1]; } // Resize the queue queue->requests = realloc(queue->requests, sizeof(DiskRequest) * (queue->size - 1)); if (queue->requests == NULL) { printf("Error reallocating memory for queue requests\n"); exit(EXIT_FAILURE); } queue->size--; return request; } DiskQueue* clone(DiskQueue *queue) { DiskQueue *clone = createDiskQueue(); for (int i = 0; i < queue->size; i++) { enqueue(clone, queue->requests[i]); } return clone; } DiskRequest peek(DiskQueue *queue) { return queue->requests[0]; } DiskRequest dequeue(DiskQueue *queue) { return delete(queue, peek(queue)); } DiskQueue *queueOfLesserTime(DiskQueue *queue, double time) { DiskQueue *sameTimeQueue = createDiskQueue(); for (int i = 0; i < queue->size; i++) { if (queue->requests[i].time <= time) { enqueue(sameTimeQueue, queue->requests[i]); } } return sameTimeQueue; } // Compare function for disk requests by position int compareDiskRequestsByPosition(const void *a, const void *b) { DiskRequest *requestA = (DiskRequest *) a; DiskRequest *requestB = (DiskRequest *) b; return requestA->position - requestB->position; } // Sorts the queue by position, in place DiskQueue *sortQueueByPosition(DiskQueue *queue) { qsort(queue->requests, queue->size, sizeof(DiskRequest), compareDiskRequestsByPosition); return queue; } void destroyDiskQueue(DiskQueue *queue) { free(queue->requests); free(queue); } typedef enum DiskDirection { UP, DOWN } DiskDirection; // Global tracking variables DiskDirection currentDirection = UP; int movement = 0; double seekTime = 0; // Array for storing the requests DiskQueue *queue; double timeToProcessRequest(int position, int destination) { //The time (a floating point number) required to process a request is computed by distance the head travels divided by 5 //Plus additional 15 milliseconds penalty if the direction has to change (for FCFS) double time = 0; // Calculated this way so that positive means up and negative means down int distance = destination - position; DiskDirection direction = (distance > 0) ? UP : DOWN; time += abs(distance) / 5.0; if (direction != currentDirection) { time += 15; currentDirection = direction; } return time; } // Your simulated disk is of size 10000, numbered from 0 to 9999. // In first come first the time the request comes in is irrelevant void fcfs(int start) { int position = start; int size = queue->size; for (int i = 0; i < size; i++) { DiskRequest request = dequeue(queue); while (seekTime < request.time) { seekTime++; } seekTime += timeToProcessRequest(position, request.position); movement += abs(position - request.position); position = request.position; } } void cscan(int start) { int position = start; DiskQueue *workingQueue = clone(queue); while (workingQueue->size > 0) { DiskQueue *candidates = queueOfLesserTime(workingQueue, seekTime); if (candidates->size == 0) { while (seekTime < peek(workingQueue).time) { seekTime++; } continue; } sortQueueByPosition(candidates); DiskRequest request = dequeue(candidates); if (request.position < position) { // Go to end of disk and back to 0 seekTime += timeToProcessRequest(position, 9999); seekTime += timeToProcessRequest(9999, 0); movement += abs(position - 9999); movement += abs(9999 - 0); position = 0; } seekTime += timeToProcessRequest(position, request.position); movement += abs(position - request.position); position = request.position; delete(workingQueue, request); destroyDiskQueue(candidates); } destroyDiskQueue(workingQueue); } int main(int argc, char **argv) { int position, time; char algorithm = argv[1][0]; int start = 0; queue = createDiskQueue(); while (EOF != (scanf("%i %i\n", &position, &time))) { enqueue(queue, diskRequest(position, time)); // printf("Delete me: position %i, Delete me: time %i\n", position, time); } if (algorithm == 'F') { fcfs(start); printf("Movement:%i Time:%.1lf\n", movement, seekTime); } else if (algorithm == 'C') { cscan(start); // Stupid printf difference to pass tests, could call once after if statement printf("Movement: %i Time:%.1lf\n", movement, seekTime); } destroyDiskQueue(queue); return 0; }