Reputation: 1057
I have two arrays vehicles
and routes
, given below
const vehicles = [{ name: 'TukTuk', maxSpeed: 12 },
{ name: 'Bike', maxSpeed: 10 },
{ name: 'Car', maxSpeed: 20 }];
const routes = [{ name: 'routeOne' , distance: 18, allowedSpeed: 12 }
, {name: 'routeTwo', distance: 20, allowedSpeed: 10 }];
There is this rule, the vehicle would travel in the route's allowed speed even it can ride faster
That is covered written in this function
const getTravelTime = (vehicle, route) => {
return route.allowedSpeed < vehicle.maxSpeed ? (route.distance / route.allowedSpeed) : (route.distance / vehicle.maxSpeed);
};
The objective is to find the fastest route and vehicle for the Journey
I have a implementation which is not functional
const getFastestJourney = (vehicles,routes) => {
let fastestTime = Infinity;
let fastestRoute,fastestVehicle;
for(let i =0;i < vehicles.length; i++){
for(let j=0;j< routes.length;j++){
let travelTime = getTravelTime(vehicles[i],routes[j]);
if(travelTime < fastestTime){
fastestVehicle = vehicles[i];
fastestRoute = routes[j];
fastestTime = travelTime;
}
}
}
return {
route: fastestRoute,
vehicle: fastestVehicle,
};
};
how do I achieve that in the functional way?
Upvotes: 1
Views: 78
Reputation: 159
const vehicles = [{ name: 'TukTuk', maxSpeed: 12 },
{ name: 'Bike', maxSpeed: 10 },
{ name: 'Car', maxSpeed: 20 }];
const routes = [{ name: 'routeOne' , distance: 18, allowedSpeed: 12 }
, {name: 'routeTwo', distance: 20, allowedSpeed: 10 }];
function fast(cars, roads){
let maxSpeed = -1, speedIndex=0;
for(let i in cars)
if(maxSpeed < cars[i].maxSpeed){
maxSpeed = cars[i].maxSpeed;
speedIndex = i;
}
let minTime = Infinity, roadIndex=0;
for(let i in roads)
if(minTime > roads[i].distance/Math.min(roads[i].allowedSpeed, maxSpeed)){
minTime=roads[i].distance/Math.min(roads[i].allowedSpeed, maxSpeed);
roadIndex=i;
}
return [cars[speedIndex].name, roads[roadIndex].name]
}
console.log(fast(vehicles, routes))
const vehicles = [{ name: 'TukTuk', maxSpeed: 12 },
{ name: 'Bike', maxSpeed: 10 },
{ name: 'Car', maxSpeed: 20 }];
const routes = [{ name: 'routeOne' , distance: 18, allowedSpeed: 12 },
{name: 'routeTwo', distance: 20, allowedSpeed: 10 }];
function fast(cars, roads){
const maxSpeed = Math.max(...cars.map(e => e.maxSpeed))
const times = roads.map(e => e.distance/Math.min(e.allowedSpeed, maxSpeed));
const minTime = Math.min(...times)
const carIndex = cars.findIndex(e => e.maxSpeed==maxSpeed)
const roadIndex = times.findIndex(e => e==minTime)
return [cars[carIndex], roads[roadIndex]]
}
console.log(fast(vehicles, routes))
Upvotes: 1
Reputation: 386654
You could get an array of all combinations of vehicles
and routes
and their travel time and reduce this array by looking for shorter time and faster vehicle.
const
vehicles = [{ name: 'TukTuk', maxSpeed: 12 }, { name: 'Bike', maxSpeed: 10 }, { name: 'Car', maxSpeed: 20 }],
routes = [{ name: 'routeOne' , distance: 18, allowedSpeed: 12 }, {name: 'routeTwo', distance: 20, allowedSpeed: 10 }],
getTravelTime = (vehicle, route) => route.distance / (route.allowedSpeed < vehicle.maxSpeed ? route.allowedSpeed : vehicle.maxSpeed),
result = vehicles
.flatMap(v => routes.map(r => ({
vehicle: v.name,
maxSpeed: v.maxSpeed,
route: r.name,
time: getTravelTime (v, r)
})))
.reduce((a, b) =>
a.time === b.time && a.maxSpeed > b.maxSpeed ||
a.time < b.time
? a
: b
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1
Reputation: 2287
Here is one way to find the fastest vehicle/route:
const vehicles = [
{name: 'TukTuk',maxSpeed: 12},
{name: 'Bike', maxSpeed: 10},
{name: 'Car', maxSpeed: 20}
]
const routes = [
{name: 'routeOne', distance: 18, allowedSpeed: 12},
{name: 'routeTwo', distance: 20, allowedSpeed: 10}
]
function getFastestRoute(vehicles, routes) {
let times = []
// Calculate times for each route/vehicle combo
routes.forEach(r => {
vehicles.forEach(v => {
times.push({
route: r.name,
vehicle: v.name,
time: r.distance / Math.min(r.allowedSpeed, v.maxSpeed)
})
})
})
// Find fastest time and route
let fastest = times.reduce((prev, curr) => prev.time < curr.time ? prev : curr)
return fastest
}
console.log(getFastestRoute(vehicles, routes))
If you need all fastest vehicles and routes, you can use this instead:
let fastest = times.filter(f => f.time === Math.min(...times.map(t => t.time)))
Upvotes: 1