PHP ZCE mock test, interview preparation, daily lessons under chalk talk

Monday, September 24, 2012

Classes and Basic Program to operate an elevator


Logical problem :


Write Classes and logic to operate an elevator in a building which has 20 floors. The classes and logic should cover all possible scenarios. Following points must be taken care of while making any assumptions:
·         There is only one elevator
·         There can be a maximum of 8 people at a time in the elevator
·         There are 20 buttons inside the elevator for each floor and 1 button for emergency alarm
·         Any number of these buttons could be pressed at any point of time
·         At each floor outside there are 2 buttons to instruct the elevator to either go up or down
·         At any point of time requests from outside (using 2 buttons) can come from any floor
·         The elevator processes requests in the order in which they are made but of course it stops at a floor which comes in between in its direction of motion even if the request was made later
·         When power goes off, the elevator reaches the nearest floor in its direction of motion


Below is solution that I wrote for this problem. If you find any correction required, please do comment.
I would be happy to know if this solution is helping you anywhere.



Class Diagram :




Basic Logic Program :

/**
Person Class Depicts person at various floors who may request Elavator by pressing Button;
@atFloor - Floor where person is
@requestDirection - Direction where he wants to go
**/

Class Person
{
atFloor;
requestDirection;
function pressButton(direction,floor)
{
this->requestDirection = direction;
this->atFloor = floor;
ElevatorController.requestElevator(person); //pass or call?
}

}




/**
ElevatorController class handles all the manipulations required to operate the elevator
@currentFloor - currentFloor of elevator
@currentDirection - direction where elevator is moving
@stopFloors - array of Floors keeping track of at what all floors does the elevator need to stop
@pendingQueue - array of Person Objects that are put in queue because they are out of way of elevator's current direction
**/


Class ElevatorController
{
const MAX_FLOORS = 20;
const MAX_PASSENGERS = 8;
const MAX_QUEUE = 20;
currentFloor;
currentDirection;
stopFloors[MAX_FLOORS];
pendingQueue[MAX_QUEUE];

function ElevatorController() //Constructor
{
this->currentFloor = 0;
this->currentDirection = 'NONE';
Person PendingQueue[MAX_QUEUE];
for(i = 0; i<MAX_FLOORS;i++)
{
stopFloors[i] = false;
}
}


/**
if elevator is idle or if request from floor is on the way, stop at the given floor
otherwise add it to queue
**/
function requestElevator(request)
{
if(this->currentDirection == 'NONE')
{
addtoStopFloors(request);
}
elseif(inBetweenWay(request) && sufficientPeople())
{
addtoStopFloors(request);
}
else
{
addtoQueue(request);
}
}

/**
if there are more stops in the current direction, move there and serve requests
else pick next requests fromt the pending queue
if other requests from the queue fall on the way, stop at those floors too
**/
function serveRequests()
{
if(next = getNextStopFloor)
{
moveTo(next);
}
else
{
request = getNextFromQueue();
addToStopFloors();
onTheWay = pickOnTheWayFromQueue();
foreach(onTheWay)
{
addToStopFloors();
}
}
}


/**
Add floor to stop floor array
**/
function addToStopFloors(request)
{
stopFloor[request.atFloor] = true;
}


/**
Depending on current direction, get next floor to stop at
**/
function getNextStopFloor()
{
if(this->currentDirection == 'UP')
{
for(i=this->currentFloor;i<=MAX_FLOOR;i++)
{
if(stopFloor[i])
return i;
}
}
elseif(this->currentDirection == 'DOWN')
{
for(i=this->currentFloor;i>=0;i--)
{
if(stopFloor[i])
return i;
}
}
else
return false;
}

/**
Check if request is in between the way of current direction
**/
function inBetweenWay(request)
{
if($this->currentDirection == request->requestDirection)
{
if($this->currentDirection  == 'UP' && request->atFloor > $this->currentFloor)
{
return yes;
}
elseif($this->currentDirection == 'DOWN' && request->atFloor < $this->currentFloor)
{
return yes;
}
else return false;
}
else return false;
}


/**
append Person to pending queue
**/
function addToQueue(request)
{
for(i=0;i<MAX_QUEUE;i++)
{
if(!pendingQueue[i])
pendingQueue[i] = request;
}
}


/**
get the next person from the pending queue to be served
shift the queue after fetching it
**/
function getNextFromQueue()
{
returnVal = pendingQueue[0];
sizeOfQueue = arrayCount(pedingQueue);
for(i=1;i<sizeOfQueue;i++)
{
pedingQueue[i-1] = pedingQueue[i];
}
unset(pendingQueue[sizeOfQueue-1]);
return returnVal;
}

/**
Pick persons from the queue that will fall on the way of current direction
and remove pits generated alongwith
**/
function PickOntheWayFromQueue()
{
sizeOfQueue = arrayCount(pedingQueue);
for(i=0;i<sizeOfQueue;i++)
{
if(inBetweenWay(pendingQueue[i].request))
{
returnVal[] = pendingQueue[i].request;
for(j=i+1;j<sizeOfQueue;j++)
{
pedingQueue[j-1] = pedingQueue[j];
}
unset(pending[i].request);
}
}
return returnVal;
}


/**
Check if passengers limit has been crossed
**/
function sufficientPeople()
{
if(this->noOfPeople > MAX_PASSENGERS)
return false;
else
return true;
}

/**
move the elevator to next floor in the direction of motion
**/
function moveToDefaultFloor()
{
Elevator->moveTo(this->currentFloor-1, this->currentFloor)
}


/**
removes all the pending requests and stop destinations
**/
function vanishAllRequests();
{
unsetStopFloors();
unsetPendingQueue();
}


/**
Destructor - execute when power go off to make the lift move to the floor in direction of motion
**/
~ElevatorController()
{
moveToDefaultFloor();
}
}


class Elevator
{
/**Move to the given floor given the current floor
operate the doors of elevator
keep a count of people in and out
**/
moveTo(floor,currentFloor)
{
if(floor >= currentFloor)
{
ElevatorController.currentDirection = 'UP';
for(i=currentFloor;i<=floor;i++)
}
elseif(floor < currentFloor)
{
ElevatorController.currentDirection = 'DOWN';
for(i=currentFloor;i>=floor;i--)
}
ElevatorController.currentFloor = i;
door->open();
door->countPeopleIn();
door->countPeopleOut();
door->close();
}

}

class StopButton
{
stopFloor;
pressButton(buttonNo)
{
this->stopFloor = buttonNo;
elevatorController->addToStopFloor(this->stopFloor);
}
}

class EmergencyButton
{
pressButton()
{
ElevatorController->moveToDefaultFloor();
ElevatorController->vanishAllRequests();
}
}