First attempt to write functional programming, been following OO paradigm all through my programming journey
Please review the code and let me know if any comments and violations of functional programming?
King Shan wants to visit the suburb of A and has 2 possible orbits and 3 possible vehicles to choose from. Your coding challenge is to determine which orbit and vehicle King Shan should take to reach A the fastest
Rules:
Orbits have distance, craters, traffic speed, A vehicle cannot travel faster than the traffic speed for an orbit.
(for example) So even though a car’s max speed is 20 megamiles/ hour, it can only go at 10 megamiles/hour if that is the traffic speed for that orbit.Vehicles have speed in megamiles/hour, minutes to travel in a single craters
Weather conditions (affects the number of craters in an orbit):
There are three types of weathers- Sunny - craters reduce by 10%. Car, bike, and tuk-tuk can be used in this weather.
- Rainy - craters increase by 20%. Car and tuk-tuk can be used in this weather.
- Windy - no change to the number of craters. Car and bike can be used in this weather.
if there is a tie in which vehicle to choose, use bike, tuk-tuk, car in that order.
Vehicle Options:
- BIKE - 10 megamiles/hour, time taken in craters 2 minutes, travel in Sunny/Windy
- TUKTUK - 12 megamiles/hour, time taken in craters 1 minute, travel in Sunny/Rainy
- CAR - 20 megamiles/hour, time taken in craters 3 minutes, travel in Sunny/Windy/Rainy
Orbit options:
- Orbit 1 - 18 mega miles & 20 craters to cross
- Orbit 2 - 20 mega miles & 10 craters to cross
Sample I/O
Input: Weather is Sunny
Input: Orbit1 traffic speed is 12 megamiles/hour
Input: Orbit2 traffic speed is 10 megamiles/hour
Expected Output: Vehicle TukTuk on Orbit1
Solution
Data
const weathers = { SUNNY: { craterImpactingPercentage: -10 }, RAINY: { craterImpactingPercentage: 20 }, WINDY: { craterImpactingPercentage: 0 } }; const vehicles = [{ name: 'TukTuk', ridableWeathers: [weathers.SUNNY, weathers.RAINY], speedInMmph: 12, minsTakenInCrater: 1 }, { name: 'Bike', ridableWeathers: [weathers.SUNNY, weathers.WINDY], speedInMmph: 10, minsTakenInCrater: 2 }, { name: 'Car', ridableWeathers: [weathers.SUNNY, weathers.RAINY, weathers.WINDY], speedInMmph: 20, minsTakenInCrater: 3 } ]; let orbits = [{ name: 'Orbit1', distanceInMm: 18, trafficSpeed: 12, craters: 20 }, { name: 'Orbit2', distanceInMm: 20, trafficSpeed: 10, craters: 10 }];
getRidableVehicles
filters the ridable vehicle for the given weather
const getRidableVehicles = (vehicles, weather) => { return vehicles.filter(vehicle => vehicle.ridableWeathers.includes(weather)); };
getTravelTime
calculates the travel time for the given vehicle
on given orbit
with craters in it
const MINUTES_IN_HOUR = 60; const getTravelTime = (vehicle, orbit, noOfCraters) => { return (orbit.trafficSpeed < vehicle.speedInMmph ? (orbit.distanceInMm / orbit.trafficSpeed) : (orbit.distanceInMm / vehicle.speedInMmph)) * MINUTES_IN_HOUR + noOfCraters * vehicle.minsTakenInCrater; };
getNoOfCraters
calculates the number of craters from the orbit
for the given weather
const PERCENTAGE = 100; const getNoOfCraters = (orbit, weather) => { return parseInt(orbit.craters + (orbit.craters * weather.craterImpactingPercentage / PERCENTAGE)); }
getFastestJourney
calls getRidableVehicles
and gets ridable vehicles then calculates the travelTime on each orbit
and reduces to the shortest travel time journey
, in case of tie
considers minimum speed vehicle among tied journey
const getFastestJourney = (vehicles, orbits, weather) => { return getRidableVehicles(vehicles, weather) .flatMap(vehicle => orbits.map(orbit => ({ vehicle: vehicle.name, orbit: orbit.name, travelTime: getTravelTime(vehicle, orbit, getNoOfCraters(orbit, weather)), vehicleSpeed: vehicle.speedInMmph, }))) .reduce((journey, otherJourney) => reduceToFastestJourney(journey, otherJourney)); }; const reduceToFastestJourney = (journey, otherJourney) => { return journey.travelTime === otherJourney.travelTime && journey.vehicleSpeed < otherJourney.vehicleSpeed || journey.travelTime < otherJourney.travelTime ? journey : otherJourney; }
function initialLoad() { console.log( getTravelPlan(vehicles, orbits, weathers.SUNNY)) document.getElementById("outcome").innerHTML = getTravelPlan(vehicles, orbits, weathers.SUNNY); } const weathers = { SUNNY: { craterImpactingPercentage: -10 }, RAINY: { craterImpactingPercentage: 20 }, WINDY: { craterImpactingPercentage: 0 } }; const vehicles = [{ name: 'TukTuk', ridableWeathers: [weathers.SUNNY, weathers.RAINY], speedInMmph: 12, minsTakenInCrater: 1 }, { name: 'Bike', ridableWeathers: [weathers.SUNNY, weathers.WINDY], speedInMmph: 10, minsTakenInCrater: 2 }, { name: 'Car', ridableWeathers: [weathers.SUNNY, weathers.RAINY, weathers.WINDY], speedInMmph: 20, minsTakenInCrater: 3 } ]; let orbits = [{ name: 'Orbit1', distanceInMm: 18, trafficSpeed: 12, craters: 20 }, { name: 'Orbit2', distanceInMm: 20, trafficSpeed: 10, craters: 10 }]; const MINUTES_IN_HOUR = 60, PERCENTAGE = 100; const getRidableVehicles = (vehicles, weather) => { return vehicles.filter(vehicle => vehicle.ridableWeathers.includes(weather)); }; const getTravelTime = (vehicle, orbit, noOfCraters) => { return (orbit.trafficSpeed < vehicle.speedInMmph ? (orbit.distanceInMm / orbit.trafficSpeed) : (orbit.distanceInMm / vehicle.speedInMmph)) * MINUTES_IN_HOUR + noOfCraters * vehicle.minsTakenInCrater; }; const getNoOfCraters = (orbit, weather) => { return parseInt(orbit.craters + (orbit.craters * weather.craterImpactingPercentage / PERCENTAGE)); } const getFastestJourney = (vehicles, orbits, weather) => { return getRidableVehicles(vehicles, weather) .flatMap(vehicle => orbits.map(orbit => ({ vehicle: vehicle.name, orbit: orbit.name, travelTime: getTravelTime(vehicle, orbit, getNoOfCraters(orbit, weather)), vehicleSpeed: vehicle.speedInMmph, }))) .reduce((journey, otherJourney) => reduceToFastestJourney(journey, otherJourney)); }; const reduceToFastestJourney = (journey, otherJourney) => { return journey.travelTime === otherJourney.travelTime && journey.vehicleSpeed < otherJourney.vehicleSpeed || journey.travelTime < otherJourney.travelTime ? journey : otherJourney; } const getTravelPlan = (vehicles, orbits, weather) => { console.log("Input: Weather is SUNNY"); orbits.forEach(orbit => console.log(`${orbit.name} traffic speed is ${orbit.trafficSpeed}`)); return parseOutcome(getFastestJourney(vehicles, orbits, weather)); } const parseOutcome = (outcome) => `Expected Output: Vehicle ${outcome.vehicle} on ${outcome.orbit}`;
<!DOCTYPE html> <HTML> <HEAD> </HEAD> <BODY id="outcome" onload=initialLoad()> <h1> TEST </h1> </BODY> </HTML>