0% found this document useful (0 votes)
14 views11 pages

files

The document contains C code for a simulation of an elevator system that manages passenger requests and elevator movements. It includes data structures for passenger requests, elevator states, and shared memory management, along with functions for initializing the simulation, processing requests, and updating elevator states. The main function orchestrates the reading of input data, initializing inter-process communication, and running the elevator loop until all requests are processed.

Uploaded by

f20212004
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views11 pages

files

The document contains C code for a simulation of an elevator system that manages passenger requests and elevator movements. It includes data structures for passenger requests, elevator states, and shared memory management, along with functions for initializing the simulation, processing requests, and updating elevator states. The main function orchestrates the reading of input data, initializing inter-process communication, and running the elevator loop until all requests are processed.

Uploaded by

f20212004
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 11

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;
}

You might also like