Last active
November 24, 2019 03:21
-
-
Save curzonj/b449f7b1ebdf024f597c352cbdac70a3 to your computer and use it in GitHub Desktop.
http://play.elevatorsaga.com/ solutions
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
{ | |
init: function(elevators, floors) { | |
var elevator = elevators[0]; // Let's use the first elevator | |
function addFloorRequest(requestedDirection, floorNumber) { | |
if (elevator.destinationQueue.indexOf(floorNumber) > -1) return; | |
if (elevator.destinationQueue.length === 0) { | |
elevator.goToFloor(floorNumber); | |
return; | |
} | |
elevator.destinationQueue.push(floorNumber); | |
var currentFloor = elevator.currentFloor(); | |
var direction = elevator.destinationDirection(); | |
if (direction === "stopped") { | |
direction = elevator.destinationQueue[0] > currentFloor ? "up" : "down"; | |
} | |
var first = elevator.destinationQueue.filter(function(dqfn) { | |
return direction === "up" ? dqfn > currentFloor : dqfn < currentFloor; | |
}).sort(); | |
var after = elevator.destinationQueue.filter(function(dqfn) { | |
return first.indexOf(dqfn) === -1; | |
}).sort(); | |
if (direction === "up") { | |
after.reverse(); | |
} else { | |
first.reverse(); | |
} | |
elevator.destinationQueue = [ first, after ].flat(); | |
elevator.checkDestinationQueue(); | |
} | |
floors.forEach(function (floor) { | |
floor.on("up_button_pressed", function() { | |
addFloorRequest("up", floor.floorNum()) | |
}) | |
floor.on("down_button_pressed", function() { | |
addFloorRequest("down", floor.floorNum()) | |
}) | |
}) | |
elevator.on("floor_button_pressed ", function(floorNumber) { | |
addFloorRequest(undefined, floorNumber); | |
}); | |
}, | |
update: function(dt, elevators, floors) { | |
// We normally don't need to do anything here | |
} | |
} |
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
{ | |
init: function(elevators, floors) { | |
elevators.forEach(function (e) { | |
e.goingUpIndicator(true); | |
e.goingDownIndicator(false); | |
e.on("floor_button_pressed ", function(floorNumber) { | |
addFloorRequest(e, floorNumber); | |
}); | |
e.on("stopped_at_floor", function(floorNumber) { | |
const direction = currentDirection(e); | |
e.goingUpIndicator(direction === "up" || direction === "stopped") | |
e.goingDownIndicator(direction === "down" || direction === "stopped") | |
}) | |
}); | |
function currentDirection(elevator) { | |
let direction = elevator.destinationDirection(); | |
if (direction === "stopped" && elevator.destinationQueue.length > 0) { | |
direction = elevator.destinationQueue[0] > elevator.currentFloor() ? "up" : "down"; | |
} | |
return direction; | |
} | |
function distance(elevator, floorNumber) { | |
return Math.abs(elevator.currentFloor() - floorNumber); | |
} | |
function filterLoadFactor(n) { | |
return function(e) { | |
return e.loadFactor() <= n; | |
} | |
} | |
function selectClosestFromList(floorNumber, list) { | |
if (list.length === 0) return; | |
return list.reduce(function(acc, e) { | |
if (distance(e, floorNumber) < distance(acc, floorNumber)) { | |
return e; | |
} else { | |
return acc; | |
} | |
}); | |
} | |
function selectClosestSameDirection(loadFactor, requestedDirection, floorNumber) { | |
selectClosestFromList(floorNumber, elevators. | |
filter(filterLoadFactor(loadFactor)). | |
filter(function(e) { | |
const direction = currentDirection(e); | |
const currentFloor = e.currentFloor(); | |
if (requestedDirection !== direction) return false; | |
if (direction === "up" && floorNumber > currentFloor) return true; | |
if (direction === "down" && floorNumber < currentFloor) return true; | |
return false; | |
})) | |
} | |
function selectClosestEmpty(floorNumber) { | |
selectClosestFromList(floorNumber, elevators. | |
filter(function(e) { return e.destinationQueue.length === 0; })); | |
} | |
function selectSoonestAvailable(loadFactor) { | |
return elevators. | |
filter(filterLoadFactor(loadFactor)). | |
reduce(function(acc, e) { | |
if (acc === undefined || e === undefined) return acc; | |
if (e.destinationQueue.length < acc.destinationQueue.length) { | |
return e; | |
} else { | |
return acc; | |
} | |
}) | |
} | |
function selectBestElevator(requestedDirection, floorNumber) { | |
const ret = | |
selectClosestEmpty(floorNumber) || | |
selectClosestSameDirection(0.8, requestedDirection, floorNumber) || | |
selectSoonestAvailable(0.4) || | |
selectSoonestAvailable(0.8) || | |
selectClosestSameDirection(1, requestedDirection, floorNumber) || | |
selectSoonestAvailable(1); | |
if (ret === undefined) { | |
console.dir({ requestedDirection, floorNumber, warning: "undefined best elevator" }) | |
} | |
return ret; | |
} | |
function addFloorRequest(elevator, floorNumber) { | |
if (elevator.destinationQueue.indexOf(floorNumber) > -1) return; | |
if (elevator.destinationQueue.length === 0) { | |
elevator.goToFloor(floorNumber); | |
return; | |
} | |
elevator.destinationQueue.push(floorNumber); | |
const currentFloor = elevator.currentFloor(); | |
const direction = currentDirection(elevator); | |
const first = elevator.destinationQueue.filter(function(dqfn) { | |
return direction === "up" ? dqfn > currentFloor : dqfn < currentFloor; | |
}).sort(); | |
const after = elevator.destinationQueue.filter(function(dqfn) { | |
return first.indexOf(dqfn) === -1; | |
}).sort(); | |
if (direction === "up") { | |
after.reverse(); | |
} else { | |
first.reverse(); | |
} | |
elevator.destinationQueue = [ first, after ].flat(); | |
elevator.checkDestinationQueue(); | |
elevator.goingUpIndicator(direction === "up") | |
elevator.goingDownIndicator(direction === "down") | |
} | |
floors.forEach(function (floor) { | |
floor.on("up_button_pressed", function() { | |
addFloorRequest(selectBestElevator("up", floor.floorNum()), floor.floorNum()) | |
}) | |
floor.on("down_button_pressed", function() { | |
addFloorRequest(selectBestElevator("down", floor.floorNum()), floor.floorNum()) | |
}) | |
}) | |
}, | |
update: function(dt, elevators, floors) { | |
// We normally don't need to do anything here | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment