Skip to content

Instantly share code, notes, and snippets.

@ColinTheRobot
Last active December 30, 2017 02:01
Show Gist options
  • Save ColinTheRobot/3b1a8cfeaf217293e0764d04972b3bf5 to your computer and use it in GitHub Desktop.
Save ColinTheRobot/3b1a8cfeaf217293e0764d04972b3bf5 to your computer and use it in GitHub Desktop.
zipcar code challenge
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