Assignment2FinalSubmissions/Birla_Shubham_907_20212965/2024-11-20-23-52-56/
>>>> file: solution.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/shm.h>
#include <errno.h>
#include <math.h>
#define MAX_ELEVATORS 100
#define MAX_FLOORS 500
#define MAX_SOLVERS 100
#define MAX_TURNS 100
#define MAX_NEW_REQUESTS 30
#define ELEVATOR_MAX_CAP 20
#define MAX_PASSENGERS 1000
#define AUTH_CHAR_SET "abcdef"
#define AUTH_CHAR_SET_SIZE 6
other
typedef struct PassengerRequest {
int requestId;
int startFloor;
int requestedFloor;
} PassengerRequest;
typedef struct MainSharedMemory {
char authStrings[MAX_ELEVATORS][ELEVATOR_MAX_CAP + 1];
char elevatorMovementInstructions[MAX_ELEVATORS];
PassengerRequest newPassengerRequests[MAX_NEW_REQUESTS];
int elevatorFloors[MAX_ELEVATORS];
int droppedPassengers[MAX_PASSENGERS];
int pickedUpPassengers[MAX_PASSENGERS][2];
} MainSharedMemory;
typedef struct TurnChangeResponse {
long mtype;
int turnNumber;
int newPassengerRequestCount;
int errorOccurred;
int finished;
} TurnChangeResponse;
typedef struct TurnChangeRequest {
long mtype;
int droppedPassengersCount;
int pickedUpPassengersCount;
} TurnChangeRequest;
typedef struct SolverRequest {
long mtype;
int elevatorNumber;
char authStringGuess[ELEVATOR_MAX_CAP + 1];
} SolverRequest;
typedef struct SolverResponse {
long mtype;
int guessIsCorrect;
} SolverResponse;
void initializePassengerCounters(int *pickedUpCount, int *droppedCount) {
*pickedUpCount = 0;
*droppedCount = 0;
}
TurnChangeRequest createTurnChangeRequest(int droppedPassengersCount, int
pickedUpPassengersCount) {
TurnChangeRequest request;
request.mtype = 1;
request.droppedPassengersCount = droppedPassengersCount;
request.pickedUpPassengersCount = pickedUpPassengersCount;
return request;
void Movements(void *a, void *b, size_t size) {
char temp[size];
memcpy(temp, a, size);
memcpy(a, b, size);
memcpy(b, temp, size);
}
typedef struct ElevatorState {
int currentFloor;
char direction;
int passengersInElevator[ELEVATOR_MAX_CAP];
int passengerDestinations[ELEVATOR_MAX_CAP];
int passengerCount;
} ElevatorState;
typedef struct PassengerState {
int requestId;
int startFloor;
int requestedFloor;
int inElevator;
int isServed;
} PassengerState;
void updateElevatorFloors(MainSharedMemory *sharedMem, ElevatorState elevators[],
int numElevators) {
for (int i = 0; i < numElevators; ++i) {
if (sharedMem->elevatorMovementInstructions[i] == 'u') {
elevators[i].currentFloor++;
}
else if (sharedMem->elevatorMovementInstructions[i] == 'd') {
elevators[i].currentFloor--;
}
}
}
int calculateDynamicCapacity(ElevatorState elevators[], int numElevators, int
elevatorMaxCapacity) {
int overloadedElevators = 0;
for (int i = 0; i < numElevators; ++i) {
if (elevators[i].passengerCount > 3) {
overloadedElevators++;
}
}
if (overloadedElevators == numElevators) {
return elevatorMaxCapacity / 2;
}
other
return elevatorMaxCapacity;
}
int N, K, M, T;
key_t shmKey, mainQueueKey, solverQueueKeys[MAX_SOLVERS];
int shmId, mainQueueId, solverQueueIds[MAX_SOLVERS];
MainSharedMemory *sharedMem;
ElevatorState elevators[MAX_ELEVATORS];
PassengerState passengers[MAX_PASSENGERS];
int totalPassengers = 0;
void readInputFile();
void initializeIPC();
void cleanup();
void elevatorLoop();
void obtainAuthString(int elevatorNumber, int passengerCount, char *authString);
int generateAuthString(int length, char *authString, int solverId);
int intPow(int base, int exponent) {
int result = 1;
for (int i = 0; i < exponent; ++i) {
result *= base;
}
return result;
}
void initializeSimulation(int *finished, int *turnNumber) {
*finished = 0;
*turnNumber = 0;
}
void readInputFile() {
FILE *file = fopen("input.txt", "r");
if (!file) {
perror("Failed to open input.txt");
exit(1);
}
fscanf(file, "%d", &N);
fscanf(file, "%d", &K);
fscanf(file, "%d", &M);
fscanf(file, "%d", &T);
int temp;
fscanf(file, "%d", &temp);
shmKey = (key_t)temp;
fscanf(file, "%d", &temp);
mainQueueKey = (key_t)temp;
for (int i = 0; i < M; ++i) {
fscanf(file, "%d", &temp);
solverQueueKeys[i] = (key_t)temp;
}
fclose(file);
//printf("Floors: %d\nSolvers: %d\nElevatros: %d\nTurn no of last req: %d\n",
K,M,N,T);
}
void initializeIPC() {
shmId = shmget(shmKey, sizeof(MainSharedMemory), 0666);
if (shmId < 0) {
perror("Failed to get shared memory");
exit(1);
}
sharedMem = (MainSharedMemory *)shmat(shmId, NULL, 0);
if (sharedMem == (void *) -1) {
perror("Failed to attach shared memory");
exit(1);
}
mainQueueId = msgget(mainQueueKey, 0666);
if (mainQueueId < 0) {
perror("Failed to get main message queue");
exit(1);
}
for (int i = 0; i < M; ++i) {
solverQueueIds[i] = msgget(solverQueueKeys[i], 0666);
if (solverQueueIds[i] < 0) {
perror("Failed to get solver message queue");
exit(1);
}
}
}
void resetElevatorState(MainSharedMemory *sharedMem, int numElevators) {
for (int i = 0; i < numElevators; ++i) {
sharedMem->elevatorMovementInstructions[i] = 's';
sharedMem->authStrings[i][0] = '\0';
}
void cleanup() {
if (shmdt(sharedMem) == -1) {
perror("Failed to detach shared memory");
}
other
void obtainAuthString(int elevatorNumber, int passengerCount, char *authString) {
static int solverIndex = 0;
int solverId = solverQueueIds[solverIndex % M];
solverIndex++;
SolverRequest setTarget;
setTarget.mtype = 2;
setTarget.elevatorNumber = elevatorNumber;
setTarget.authStringGuess[0] = '\0';
if (msgsnd(solverId, &setTarget, sizeof(SolverRequest) - sizeof(long), 0) == -
1) {
perror("Failed to send set target to solver");
exit(1);
char authGuess[ELEVATOR_MAX_CAP + 1];
if (generateAuthString(passengerCount, authGuess, solverId)) {
strcpy(authString, authGuess);
}
else {
fprintf(stderr, "Failed to obtain auth string for elevator %d\n",
elevatorNumber);
exit(1);
}
int generateAuthString(int length, char *authString, int solverId) {
int totalCombinations = intPow(AUTH_CHAR_SET_SIZE, length);
char currentString[ELEVATOR_MAX_CAP + 1];
for (int i = 0; i < totalCombinations; ++i) {
other
int temp = i;
for (int j = 0; j < length; ++j) {
currentString[j] = AUTH_CHAR_SET[temp % AUTH_CHAR_SET_SIZE];
temp /= AUTH_CHAR_SET_SIZE;
}
currentString[length] = '\0';
SolverRequest guess;
guess.mtype = 3;
guess.elevatorNumber = 0;
strcpy(guess.authStringGuess, currentString);
if (msgsnd(solverId, &guess, sizeof(SolverRequest) - sizeof(long), 0) == -
1) {
perror("Failed to send guess to solver");
exit(1);
}
SolverResponse response;
if (msgrcv(solverId, &response, sizeof(SolverResponse) - sizeof(long), 4,
0) == -1) {
perror("Failed to receive from solver");
exit(1);
}
if (response.guessIsCorrect) {
strcpy(authString, currentString);
return 1;
}
}
return 0;
}
void generateAndUpdateAuthStrings(MainSharedMemory *sharedMem, ElevatorState
elevators[], int numElevators) {
for (int i = 0; i < numElevators; ++i) {
other
if (sharedMem->elevatorMovementInstructions[i] != 's' &&
elevators[i].passengerCount > 0) {
char authString[ELEVATOR_MAX_CAP + 1];
obtainAuthString(i, elevators[i].passengerCount, authString);
strcpy(sharedMem->authStrings[i], authString);
}
}
}
void elevatorLoop() {
int finished, turnNumber;
initializeSimulation(&finished, &turnNumber);
while (!finished) {
TurnChangeResponse response;
if (msgrcv(mainQueueId, &response, sizeof(TurnChangeResponse) -
sizeof(long), 2, 0) == -1) {
perror("Failed to receive from helper");
exit(1);
}
if (response.finished) {
finished = 1;
break;
}
turnNumber = response.turnNumber;
int pickedUpPassengersCount, droppedPassengersCount;
initializePassengerCounters(&pickedUpPassengersCount,
&droppedPassengersCount);
int newRequests = response.newPassengerRequestCount;
for (int i = 0; i < newRequests; ++i) {
other
PassengerRequest pr = sharedMem->newPassengerRequests[i];
passengers[totalPassengers].requestId = pr.requestId;
passengers[totalPassengers].startFloor = pr.startFloor;
passengers[totalPassengers].requestedFloor = pr.requestedFloor;
passengers[totalPassengers].inElevator = -1;
passengers[totalPassengers].isServed = 0;
totalPassengers++;
}
resetElevatorState(sharedMem, N);
memset(sharedMem->pickedUpPassengers, 0, sizeof(sharedMem-
>pickedUpPassengers));
memset(sharedMem->droppedPassengers, 0, sizeof(sharedMem-
>droppedPassengers));
int waitingPassengers[MAX_PASSENGERS];
int waitingCount = 0;
for (int i = 0; i < totalPassengers; ++i) {
if (!passengers[i].isServed && passengers[i].inElevator == -1) {
waitingPassengers[waitingCount++] = i;
}
int dynamicCapacity = calculateDynamicCapacity(elevators, N,
ELEVATOR_MAX_CAP);
for (int i = 0; i < N; ++i) {
ElevatorState *elevator = &elevators[i];
if (elevator->passengerCount == 0 && waitingCount > 0) {
int minDistance = K + 1;
int passengerIndex = -1;
for (int j = 0; j < waitingCount; ++j) {
int pIndex = waitingPassengers[j];
int distance = abs(elevator->currentFloor -
passengers[pIndex].startFloor);
if (distance < minDistance) {
minDistance = distance;
passengerIndex = pIndex;
}
}
if (passengerIndex != -1) {
PassengerState *passenger = &passengers[passengerIndex];
if (elevator->currentFloor < passenger->startFloor) {
sharedMem->elevatorMovementInstructions[i] = 'u';
elevator->direction = 'u';
}
else if (elevator->currentFloor > passenger->startFloor) {
sharedMem->elevatorMovementInstructions[i] = 'd';
elevator->direction = 'd';
}
else {
sharedMem->elevatorMovementInstructions[i] = 's';
if (elevator->passengerCount < dynamicCapacity &&
passenger->inElevator == -1) {
sharedMem->pickedUpPassengers[pickedUpPassengersCount]
[0] = passenger->requestId;
sharedMem->pickedUpPassengers[pickedUpPassengersCount]
[1] = i;
pickedUpPassengersCount++;
passenger->inElevator = i;
elevator->passengersInElevator[elevator-
>passengerCount] = passenger->requestId;
elevator->passengerDestinations[elevator-
>passengerCount] = passenger->requestedFloor;
elevator->passengerCount++;
}
}
}
}
else if (elevator->passengerCount > 0) {
int minDistance = K + 1;
int targetFloor = elevator->currentFloor;
for (int j = 0; j < elevator->passengerCount; ++j) {
int destination = elevator->passengerDestinations[j];
int distance = abs(elevator->currentFloor - destination);
if (distance < minDistance) {
minDistance = distance;
targetFloor = destination;
}
if (elevator->currentFloor < targetFloor) {
sharedMem->elevatorMovementInstructions[i] = 'u';
elevator->direction = 'u';
else if (elevator->currentFloor > targetFloor) {
sharedMem->elevatorMovementInstructions[i] = 'd';
elevator->direction = 'd';
}
else {
sharedMem->elevatorMovementInstructions[i] = 's';
for (int j = 0; j < elevator->passengerCount;) {
if (elevator->passengerDestinations[j] == elevator-
>currentFloor) {
int requestId = elevator->passengersInElevator[j];
sharedMem->droppedPassengers[droppedPassengersCount++]
= requestId;
for (int p = 0; p < totalPassengers; ++p) {
if (passengers[p].requestId == requestId) {
passengers[p].isServed = 1;
passengers[p].inElevator = -1;
break;
}
int x = 5, y = 10;
Movements(&x, &y, sizeof(int));
for (int k = j; k < elevator->passengerCount - 1; ++k)
{
elevator->passengersInElevator[k] = elevator-
>passengersInElevator[k + 1];
elevator->passengerDestinations[k] = elevator-
>passengerDestinations[k + 1];
}
elevator->passengerCount--;
}
else {
j++;
}
}
}
}
}
generateAndUpdateAuthStrings(sharedMem, elevators, N);
TurnChangeRequest request;
request = createTurnChangeRequest(droppedPassengersCount,
pickedUpPassengersCount);
if (msgsnd(mainQueueId, &request, sizeof(TurnChangeRequest) - sizeof(long),
0) == -1) {
perror("Failed to send to helper");
exit(1);
}
updateElevatorFloors(sharedMem, elevators, N);
}
}
int main() {
readInputFile();
initializeIPC();
for (int i = 0; i < N; ++i) {
elevators[i].currentFloor = 0;
elevators[i].direction = 's';
elevators[i].passengerCount = 0;
}
elevatorLoop();
cleanup();
return 0;
}