@@ -15,21 +15,20 @@ func NewElevatorManager(building *Building) *ElevatorManager {
1515
1616func (em * ElevatorManager ) OperateAllElevators () {
1717 for _ , elevator := range em .Building .Elevators {
18- go em .OperateElevator (elevator )
18+ elevator .PrintState ()
19+ go em .OperateElevator (elevator ) // go thread for each elevator
1920 }
2021}
2122
2223func (em * ElevatorManager ) OperateElevator (elevator * Elevator ) {
23- for {
24- elevator . Lock ()
24+ for { // infinte loop to keep elevator operating(real world scenario -> event can come any time)
25+
2526 if len (elevator .Destinations ) == 0 {
2627 elevator .CurrentDirection = Still
27- elevator .Unlock ()
2828 continue
2929 }
3030
3131 sort .Ints (elevator .Destinations )
32- fmt .Printf ("Elevator %d is starting from %d and going to %s\n " , elevator .ID , elevator .CurrentFloor , elevator .CurrentDirection )
3332
3433 if elevator .CurrentDirection == Up {
3534 em .MoveElevatorUp (elevator )
@@ -38,16 +37,17 @@ func (em *ElevatorManager) OperateElevator(elevator *Elevator) {
3837 } else {
3938 em .DecideDirection (elevator )
4039 }
41- elevator . Unlock ()
40+
4241 }
4342}
4443
44+ // move to nearest request
4545func (em * ElevatorManager ) DecideDirection (elevator * Elevator ) {
46- currentFloor := elevator .CurrentFloor
4746 if len (elevator .Destinations ) == 0 {
4847 return
4948 }
5049
50+ currentFloor := elevator .CurrentFloor
5151 nearestDestination := elevator .Destinations [0 ]
5252 if nearestDestination > currentFloor {
5353 elevator .UpdateCurrentDirection (Up )
@@ -62,10 +62,11 @@ func (em *ElevatorManager) MoveElevatorUp(elevator *Elevator) {
6262 for i := 0 ; i < len (elevator .Destinations ); i ++ {
6363 destination := elevator .Destinations [i ]
6464 if destination >= elevator .CurrentFloor {
65- fmt .Printf ("Elevator %d moving up to floor %d\n " , elevator .ID , destination )
6665 elevator .UpdateCurrentFloor (destination )
6766 elevator .RemoveDestination (destination )
68- i --
67+ i -- // because we have removed an element from the slice
68+ } else {
69+ // skip destinations below current floor
6970 }
7071 }
7172
@@ -80,9 +81,10 @@ func (em *ElevatorManager) MoveElevatorDown(elevator *Elevator) {
8081 for i := len (elevator .Destinations ) - 1 ; i >= 0 ; i -- {
8182 destination := elevator .Destinations [i ]
8283 if destination <= elevator .CurrentFloor {
83- fmt .Printf ("Elevator %d moving down to floor %d\n " , elevator .ID , destination )
8484 elevator .UpdateCurrentFloor (destination )
8585 elevator .RemoveDestination (destination )
86+ } else {
87+ // skip destinations above current floor
8688 }
8789 }
8890
@@ -93,7 +95,8 @@ func (em *ElevatorManager) MoveElevatorDown(elevator *Elevator) {
9395 }
9496}
9597
96- func (em * ElevatorManager ) AssignElevator (floor int , direction Directions ) (bestElevator * Elevator ) {
98+ // manager will assign the best elevator for the hall call request
99+ func (em * ElevatorManager ) AssignElevator (floor int , direction Direction ) (bestElevator * Elevator ) {
97100 bestElevator = em .FindClosestElevator (floor , direction )
98101 if bestElevator != nil {
99102 bestElevator .AddDestination (floor )
@@ -102,41 +105,66 @@ func (em *ElevatorManager) AssignElevator(floor int, direction Directions) (best
102105 return bestElevator
103106}
104107
105- func (em * ElevatorManager ) FindClosestElevator (floor int , direction Directions ) * Elevator {
108+ // mamnager will find best elevator for the hall call request
109+ func (em * ElevatorManager ) FindClosestElevator (floor int , direction Direction ) * Elevator {
106110 var closestElevator * Elevator
107111 minDistance := int (1e9 )
108112
109113 for _ , elevator := range em .Building .Elevators {
110114 elevator .Lock ()
111115 distance := em .calculateDistance (elevator , floor , direction )
116+ elevator .Unlock ()
112117
113118 if distance < minDistance {
114119 minDistance = distance
115120 closestElevator = elevator
116121 }
117-
118- elevator .Unlock ()
119122 }
123+
120124 return closestElevator
121125}
122126
123- func (em * ElevatorManager ) calculateDistance (elevator * Elevator , floor int , direction Directions ) int {
127+ func (em * ElevatorManager ) calculateDistance (elevator * Elevator , floor int , direction Direction ) int {
124128 currentFloor := elevator .CurrentFloor
125129 currentDirection := elevator .CurrentDirection
126130
127- if currentDirection == Still || (currentDirection == direction && ((direction == Up && floor > currentFloor ) || (direction == Down && floor < currentFloor ))) {
131+ fmt .Println ("Calculating distance for Elevator" , elevator .ID , "at floor" , currentFloor , "going" , currentDirection , "to floor" , floor , "going" , direction )
132+
133+ // Case 1: Elevator is idle
134+ if currentDirection == Still || len (elevator .Destinations ) == 0 {
128135 return abs (floor - currentFloor )
129136 }
130137
138+ // Case 2: Elevator moving in same direction
139+ if currentDirection == direction {
140+ if (direction == Up && floor >= currentFloor ) || (direction == Down && floor <= currentFloor ) {
141+ // Request is ahead in same direction → pick up immediately
142+ return abs (floor - currentFloor )
143+ } else {
144+ // Request is behind → calculate distance after finishing current sweep
145+ if direction == Up {
146+ farthest := elevator .FarthestDestination ()
147+ return abs (farthest - currentFloor ) + abs (farthest - floor )
148+ } else { // Down
149+ nearest := elevator .NearestDestination ()
150+ return abs (currentFloor - nearest ) + abs (floor - nearest )
151+ }
152+ }
153+ }
154+
155+ // Case 3: Elevator moving in opposite direction
131156 if (currentDirection == Up && direction == Down ) || (currentDirection == Down && direction == Up ) {
132157 if currentDirection == Up {
133- return abs (elevator .FarthestDestination ()- currentFloor ) + abs (elevator .FarthestDestination ()- floor )
134- } else {
135- return abs (elevator .NearestDestination ()- currentFloor ) + abs (elevator .NearestDestination ()- floor )
158+ farthest := elevator .FarthestDestination ()
159+ return abs (farthest - currentFloor ) + abs (farthest - floor )
160+ } else { // Down
161+ nearest := elevator .NearestDestination ()
162+ return abs (currentFloor - nearest ) + abs (floor - nearest )
136163 }
137164 }
138165
139- return 100
166+ // Fallback: very far / unlikely elevator
167+ return 1000
140168}
141169
142170func abs (x int ) int {
0 commit comments