4
\$\begingroup\$

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

    1. Sunny - craters reduce by 10%. Car, bike, and tuk-tuk can be used in this weather.
    2. Rainy - craters increase by 20%. Car and tuk-tuk can be used in this weather.
    3. 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:

  1. BIKE - 10 megamiles/hour, time taken in craters 2 minutes, travel in Sunny/Windy
  2. TUKTUK - 12 megamiles/hour, time taken in craters 1 minute, travel in Sunny/Rainy
  3. 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>

\$\endgroup\$

    0

    Start asking to get answers

    Find the answer to your question by asking.

    Ask question

    Explore related questions

    See similar questions with these tags.