Last active
March 30, 2023 23:08
-
-
Save tcotav/5c2758838c94ea7ef272d670fe0bab50 to your computer and use it in GitHub Desktop.
Designing an elevator car call control system
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"fmt" | |
"sort" | |
) | |
/* | |
Designing an elevator car call control system | |
Specifically, the algo for finding what is the next floor to go to. | |
- if there are no calls, go to the ground floor | |
- if there are calls, go to the closest call in the same direction already in progress | |
- else go to the closest call in the opposite direction and change direction | |
*/ | |
// when direction change, we reverse the order of the calls | |
type CallList struct { | |
UpList []int | |
DownList []int | |
Direction int | |
CurrentFloor int | |
MaxFloor int | |
} | |
func NewCallList() *CallList { | |
return &CallList{ | |
Direction: 0, | |
CurrentFloor: 2, | |
MaxFloor: 10, | |
UpList: make([]int, 0), | |
DownList: make([]int, 0), | |
} | |
} | |
func isDupe(x int, list []int) bool { | |
for _, v := range list { | |
if v == x { | |
return true | |
} | |
} | |
return false | |
} | |
func (c *CallList) AddStop(floor int) { | |
if floor > c.CurrentFloor { | |
if c.Direction == 0 { | |
c.Direction = 1 | |
} | |
if !isDupe(floor, c.UpList) { | |
fmt.Printf("adding floor %d\n", floor) | |
c.UpList = append(c.UpList, floor) | |
sort.Ints(c.UpList) | |
} | |
} else { | |
if c.Direction == 0 { | |
c.Direction = -1 | |
} | |
if !isDupe(floor, c.DownList) { | |
fmt.Printf("adding floor %d\n", floor) | |
c.DownList = append(c.DownList, floor) | |
// reverse order sort | |
sort.Sort(sort.Reverse(sort.IntSlice(c.DownList))) | |
} | |
} | |
} | |
func (c *CallList) GetStops() []int { | |
if c.Direction == 1 { | |
return append(c.UpList, c.DownList...) | |
} else { | |
return append(c.DownList, c.UpList...) | |
} | |
} | |
func (c *CallList) move() { | |
if len(c.UpList) == 0 && len(c.DownList) == 0 { | |
c.Direction = 0 | |
fmt.Println("no more stops") | |
return | |
} else if len(c.UpList) == 0 && c.Direction == 1 { | |
c.Direction = -1 | |
} else if len(c.DownList) == 0 && c.Direction == -1 { | |
c.Direction = 1 | |
} | |
// move in the same direction as we're already going until we've emptied that list | |
if c.Direction == 1 { | |
if len(c.UpList) > 0 { | |
c.CurrentFloor = c.UpList[0] | |
c.UpList = c.UpList[1:] | |
} else { | |
c.CurrentFloor = c.DownList[0] | |
c.DownList = c.DownList[1:] | |
c.Direction = -1 | |
} | |
} else { | |
if len(c.DownList) > 0 { | |
c.CurrentFloor = c.DownList[0] | |
c.DownList = c.DownList[1:] | |
} else { | |
c.CurrentFloor = c.UpList[0] | |
c.UpList = c.UpList[1:] | |
c.Direction = 1 | |
} | |
} | |
fmt.Println("moving to floor", c.CurrentFloor) | |
} | |
func main() { | |
c := NewCallList() | |
c.AddStop(3) | |
c.AddStop(5) | |
fmt.Println(c.GetStops()) | |
c.move() | |
c.AddStop(2) | |
c.AddStop(4) | |
fmt.Println(c.GetStops()) | |
c.move() | |
c.AddStop(5) | |
c.AddStop(1) | |
fmt.Println(c.GetStops()) | |
c.move() | |
c.move() | |
c.move() | |
c.move() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment