Last active
December 30, 2017 02:01
-
-
Save ColinTheRobot/3b1a8cfeaf217293e0764d04972b3bf5 to your computer and use it in GitHub Desktop.
zipcar code challenge
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
var buildingsByIndex = { A: 0, B: 1, C: 2, D: 3, E: 4, F: 5, G: 6 }; | |
function turn(vehicles, peoples, buildings) { | |
var DATA = buildData(vehicles, peoples, buildings); | |
vehicles.forEach(function(vehicle, index) { | |
// TODO: needs some refactoring. fair bit of duplicate logic. | |
if (!vehicle.state.arrivedAtFirstBuilding) { | |
vehicle.moveTo(buildings[index]); | |
if (atBuilding(vehicle, buildings[index])) { | |
var people = peopleByDistance(vehicle, DATA[buildings[index].name], buildings); | |
var shortestTrip; | |
var sameDest; | |
vehicle.state.arrivedAtFirstBuilding = true; | |
if (!people.length) return | |
shortestTrip = people[0]; | |
sameDest = people.filter(function(a) { | |
return a.destination == shortestTrip.destination; | |
}) | |
vehicle.state.destination = shortestTrip.destination | |
sameDest.forEach(function(el) { | |
vehicle.pick(el) | |
}) | |
} | |
} else if (vehicle.peoples.length) { | |
var destination = buildings[buildingsByIndex[vehicle.state.destination]] | |
vehicle.moveTo(destination) | |
if (atBuilding(vehicle, destination)) { | |
var people = peopleByDistance(vehicle, DATA[vehicle.state.destination], buildings); | |
var shortestTrip; | |
var sameDest; | |
if (!people.length) { | |
assignNextClosestBuilding(vehicle, buildings, DATA); | |
return; | |
} | |
shortestTrip = people[0]; | |
sameDest = people.filter(function(a) { | |
return a.destination == shortestTrip.destination; | |
}) | |
vehicle.state.destination = shortestTrip.destination | |
vehicle.state.searching = false; | |
sameDest.forEach(function(el) { | |
vehicle.pick(el); | |
}); | |
} | |
} else { | |
if (!vehicle.state.searching) { | |
assignNextClosestBuilding(vehicle, buildings, DATA); | |
} | |
var destination = buildings[buildingsByIndex[vehicle.state.destination]] | |
vehicle.moveTo(destination) | |
if (atBuilding(vehicle, destination)) { | |
var people = peopleByDistance(vehicle, DATA[vehicle.state.destination], buildings); | |
var shortestTrip; | |
var sameDest; | |
if (!people.length) { | |
vehicle.state.searching = false; | |
return; | |
} | |
shortestTrip = people[0]; | |
sameDest = people.filter(function(a) { | |
return a.destination == shortestTrip.destination; | |
}) | |
vehicle.state.destination = shortestTrip.destination | |
vehicle.state.searching = false; | |
sameDest.forEach(function(el) { | |
vehicle.pick(el); | |
}); | |
}; | |
}; | |
}); | |
}; | |
function buildData(vehicles, peoples, buildings) { | |
var data = { A: [], B: [], C: [], D: [], E: [], F: [], G: [] }; | |
peoples.forEach(function(el) { | |
data[el['origin']].push(el); | |
data[el['origin']] = data[el['origin']].filter(unique); | |
}); | |
vehicles.forEach(function(el) { | |
if (!el.state) { | |
el.state = {}; | |
el.state.arrivedAtFirstBuilding = false; | |
el.state.searching = false | |
} | |
}) | |
function unique(value, index, self) { | |
return self.indexOf(value) === index; | |
}; | |
return data; | |
}; | |
function goToBuilding(buildings, vehicles, DATA) { | |
vehicles.forEach(function(vehicle, index) { | |
if (vehicle.state.arrivedAtFirstBuilding) return | |
vehicle.moveTo(buildings[index]); | |
if (atBuilding(vehicle, buildings[index])) { | |
vehicle.state.arrivedAtFirstBuilding = true; | |
var people = peopleByDistance(vehicle, DATA[buildings[index].name], buildings); | |
if (!people.length) return | |
var shortestTrip = people[0]; | |
var sameDest = people.filter(function(a) { | |
return a.destination == shortestTrip.destination; | |
}) | |
vehicle.state.destination = shortestTrip.destination | |
// pick up all the people | |
sameDest.forEach(function(el) { | |
vehicle.pick(el) | |
}) | |
}; | |
}); | |
}; | |
function assignNextClosestBuilding(vehicle, buildings, DATA) { | |
vehicle.state.destination = findClosestBuilding(vehicle, buildings, DATA).name; | |
vehicle.state.searching = true; | |
}; | |
function atBuilding(vehicle, building) { | |
if (vehicle.x === building.x && vehicle.y === building.y) { | |
return true; | |
} else { | |
return false; | |
}; | |
}; | |
function peopleByDistance(vehicle, peopleAtBuilding, buildings) { | |
peopleAtBuilding.forEach(function(el) { | |
distanceFromDest(vehicle, el, buildings) | |
}); | |
return sortByDistanceFromDest(peopleAtBuilding); | |
}; | |
function sortByDistanceFromDest(people) { | |
people.sort(function(a, b) { | |
return a['distanceFromDest'] - b['distanceFromDest']; | |
}); | |
return people; | |
}; | |
function findClosestBuilding(vehicle, buildings, DATA) { | |
var buildings = injectDistanceFromVehicle(buildings, vehicle); | |
buildings = sortByDistanceFromVehicle(buildings); | |
return fetchClosestBuildingWithPeople(buildings, DATA); | |
}; | |
function fetchClosestBuildingWithPeople(buildings, DATA) { | |
var closestBuilding; | |
for (var i = 1; i < buildings.length; i++) { | |
if (DATA[buildings[i]['name']].length !== 0) { | |
closestBuilding = buildings[i]; | |
break; | |
}; | |
}; | |
return closestBuilding; | |
}; | |
function injectDistanceFromVehicle(buildings, vehicle) { | |
return buildings.map(function(el) { | |
return distanceFromVehicle(vehicle, el); | |
}); | |
}; | |
function sortByDistanceFromVehicle(buildings) { | |
return buildings.sort(function(a, b) { | |
return a['distanceFromVehicle'] - b['distanceFromVehicle']; | |
}); | |
}; | |
function distanceFromVehicle(vehicle, building) { | |
var a = vehicle.x - building.x; | |
var b = vehicle.y - building.y; | |
building.distanceFromVehicle = Math.sqrt(a*a + b*b); | |
return building; | |
}; | |
function distanceFromDest(vehicle, person, buildings) { | |
var destCoords = destinationCoord(person, buildings); | |
var a = vehicle.x - destCoords.x; | |
var b = vehicle.y - destCoords.y; | |
person.distanceFromDest = Math.sqrt(a*a + b*b); | |
}; | |
function destinationCoord(person, buildings) { | |
return { | |
x: buildings[buildingsByIndex[person.destination]].x, | |
y: buildings[buildingsByIndex[person.destination]].y | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment