Toll Payment process zoho round 3

Zoho Round 3: Toll Payment Processing System — A Complete Guide

If you’re preparing for technical interviews, you may have encountered challenging rounds where you’re tasked with designing and developing complete applications.

In my Zoho Round 3 experience, the task was to create a Toll Payment Processing System using an object-oriented programming language. This article will walk you through the problem, my thought process, and the solution.

Question: Toll Payment Processing System

Application Description:

  1. There are ’n’ points on a highway. Some of these points are toll gates.
  2. Each toll gate has a unique charging scheme based on vehicle type (Car, Bike, Truck) and whether the user is VIP.
  3. VIP users receive a 20% discount on toll charges.
  4. A vehicle passing through multiple tolls must pay at each toll according to its respective scheme.
  5. The highway is considered circular, allowing vehicles to travel in both directions.

Modules:

  1. Process Journey
    Calculate the toll charges for a journey, including discounts if applicable.
  2. Display Toll Details
    Display details of vehicles passing each toll and the total revenue collected.
  3. Display Vehicle Details
    Show journeys taken by each vehicle, tolls passed, and total toll charges paid.
  4. Find Shortest Route and Calculate Toll
    Identify the shortest path between two points and calculate the toll.
  5. Exit
    Terminate the program.

Solution Design

To solve this, I used object-oriented programming (OOP) principles and broke down the problem into six classes:

  1. Toll
  2. Vehicle
  3. Journey
  4. VehiclePayment
  5. Highway
  6. TollPaymentSystem

Implementation

Below are the complete class definitions.

1. Toll.java

This class represents a toll gate and maintains details such as the toll ID, charges for each vehicle type, vehicles that passed through, and total revenue collected.

import java.util.*;

class Toll {
    int tollId;  // Unique ID for the toll
    Map<String, Integer> chargesPerVehicleType;  // Charges for each vehicle type
    List<VehiclePayment> vehiclesPassed;  // Vehicles that passed through this toll
    int totalRevenue;  // Total revenue collected by the toll
    public Toll(int tollId, Map<String, Integer> chargesPerVehicleType) {
        this.tollId = tollId;
        this.chargesPerVehicleType = chargesPerVehicleType;
        this.vehiclesPassed = new ArrayList<>();
        this.totalRevenue = 0;
    }
    // Calculate toll charge based on vehicle type and VIP status
    public int calculateToll(String vehicleType, boolean isVIP) {
        int charge = chargesPerVehicleType.getOrDefault(vehicleType, 0);
        if (isVIP) {
            charge -= (charge * 20) / 100;  // Apply 20% discount
        }
        return charge;
    }
    // Record vehicle details and update total revenue
    public void recordVehicle(Vehicle vehicle, int charge) {
        vehiclesPassed.add(new VehiclePayment(vehicle.vehicleNumber, charge));
        totalRevenue += charge;
    }
    // Display toll details
    public void displayDetails() {
        System.out.println("Toll ID: " + tollId);
        System.out.println("Vehicles Passed:");
        for (VehiclePayment vp : vehiclesPassed) {
            System.out.println("Vehicle: " + vp.vehicleNumber + ", Paid: ₹" + vp.amountPaid);
        }
        System.out.println("Total Revenue: ₹" + totalRevenue);
    }
}

2. Vehicle.java

This class maintains details about a vehicle, including its number, type, VIP status, and journeys.

import java.util.*;

class Vehicle {
    String vehicleNumber;  // Unique vehicle number
    String vehicleType;  // Type of vehicle (Car, Bike, Truck)
    boolean isVIP;  // Whether the vehicle belongs to a VIP user
    List<Journey> journeys;  // List of journeys taken by the vehicle
    public Vehicle(String vehicleNumber, String vehicleType, boolean isVIP) {
        this.vehicleNumber = vehicleNumber;
        this.vehicleType = vehicleType;
        this.isVIP = isVIP;
        this.journeys = new ArrayList<>();
    }
    // Add a journey to the vehicle's record
    public void addJourney(Journey journey) {
        journeys.add(journey);
    }
    // Display vehicle details
    public void displayDetails() {
        System.out.println("Vehicle Number: " + vehicleNumber);
        System.out.println("Type: " + vehicleType + ", VIP: " + isVIP);
        for (Journey journey : journeys) {
            System.out.println("Journey: " + journey.startPoint + " -> " + journey.endPoint);
            System.out.println("Tolls Passed: " + journey.tollsPassed);
            System.out.println("Amount Paid: " + journey.amountPaid);
        }
        int totalPaid = journeys.stream().mapToInt(j -> j.amountPaid).sum();
        System.out.println("Total Amount Paid: ₹" + totalPaid);
    }
}

3. Journey.java

This class represents a single journey, including the start and end points, tolls passed, and the total amount paid.

import java.util.*;

class Journey {
    String startPoint;
    String endPoint;
    List<Integer> tollsPassed;  // Tolls passed during the journey
    int amountPaid;  // Total toll charges paid

    public Journey(String startPoint, String endPoint, List<Integer> tollsPassed, int amountPaid) {
        this.startPoint = startPoint;
        this.endPoint = endPoint;
        this.tollsPassed = tollsPassed;
        this.amountPaid = amountPaid;
    }
}

4. VehiclePayment.java

This class stores details about a vehicle’s payment at a specific toll.

import java.util.*;

class VehiclePayment {
    String vehicleNumber;
    int amountPaid;
    public VehiclePayment(String vehicleNumber, int amountPaid) {
        this.vehicleNumber = vehicleNumber;
        this.amountPaid = amountPaid;
    }
}

5. Highway.java

This is the core class that manages the highway, toll points, and vehicles.

import java.util.*;

class Highway {
  // 0: Toll A - Fee: 25
    List<Toll> tollPoints;
    //vehicleRecords.put("TN02CD5678", bike);
    Map<String, Vehicle> vehicleRecords;

    public Highway(List<Toll> tollPoints) {
        this.tollPoints = tollPoints;
        this.vehicleRecords = new HashMap<>();
    }

    // Process the journey for the regular path between start and end
    public void processJourney(String vehicleNumber, String vehicleType, boolean isVIP, String start, String end, List<Integer> tollRoute) {
    //If vehicle not present in vehicleRecords, then create new 
        Vehicle vehicle = vehicleRecords.computeIfAbsent(vehicleNumber, vn -> new Vehicle(vn, vehicleType, isVIP));
        int totalAmount = 0;
    //show screenshot
        for (int tollId : tollRoute) {
          //show 2 screenshot
          tollPoints = List.of(
          new Toll(0, "Toll A"),
          new Toll(1, "Toll B"),
          new Toll(2, "Toll C")
      );
            Toll toll = tollPoints.get(tollId);
            
            int charge = toll.calculateToll(vehicleType, isVIP);
            //recordVehicle is present in Toll.java class
            toll.recordVehicle(vehicle, charge);
            totalAmount += charge;
        }
    //Creating journey object
        Journey journey = new Journey(start, end, tollRoute, totalAmount);
        vehicle.addJourney(journey);

        System.out.println("Journey completed! Total Toll Paid: " + totalAmount);
    }

    public void displayTollDetails() {
        for (Toll toll : tollPoints) {
            toll.displayDetails();
        }
    }

    public void displayVehicleDetails() {
    //show the screeshot of vehicle records
        for (Vehicle vehicle : vehicleRecords.values()) {
            vehicle.displayDetails();
        }
    }

    // Find shortest route considering circular path
    public List<Integer> findCircularRoute(int start, int end) {
        List<Integer> forwardRoute = new ArrayList<>();
        List<Integer> backwardRoute = new ArrayList<>();
        int totalTolls = tollPoints.size();

        // Forward route
        for (int i = start; i != end; i = (i + 1) % totalTolls) {
            forwardRoute.add(i);   // [0, 1, 2]
        }
        forwardRoute.add(end);

        // Backward route
        //The line i = (i - 1 + totalTolls) % totalTolls ensures that when i goes below 0, it wraps around back to totalTolls - 1 (circular route in reverse direction).
        for (int i = start; i != end; i = (i - 1 + totalTolls) % totalTolls) {
            backwardRoute.add(i);
        }
        backwardRoute.add(end);

        return forwardRoute.size() <= backwardRoute.size() ? forwardRoute : backwardRoute;
    }

    // Calculate toll for regular route between start and end
    public int calculateRegularTollForRoute(int start, int end, String vehicleType, boolean isVIP) {
        int totalCost = 0;
        if (start <= end) {
            for (int i = start; i <= end; i++) {
                Toll toll = tollPoints.get(i);
                totalCost += toll.calculateToll(vehicleType, isVIP);
            }
        } else {
      // [0, 1, 2]    
            for (int i = start; i < tollPoints.size(); i++) {
                Toll toll = tollPoints.get(i);
                totalCost += toll.calculateToll(vehicleType, isVIP);
            }
            for (int i = 0; i <= end; i++) {
                Toll toll = tollPoints.get(i);
                totalCost += toll.calculateToll(vehicleType, isVIP);
            }
        }
        return totalCost;
    }

    // Calculate toll for a specific route
    public int calculateTollForRoute(List<Integer> tollRoute, String vehicleType, boolean isVIP) {
        int totalCost = 0;
        for (int tollId : tollRoute) {
            Toll toll = tollPoints.get(tollId);
            totalCost += toll.calculateToll(vehicleType, isVIP);
        }
        return totalCost;
    }
}

6. TollPaymentSystem.java

This is the main driver class for the system.

import java.util.*;

public class TollPaymentSystem {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        // Initialize tolls
        List<Toll> tollPoints = new ArrayList<>();
        tollPoints.add(new Toll(0, Map.of("Car", 50, "Bike", 20, "Truck", 100)));
        tollPoints.add(new Toll(1, Map.of("Car", 60, "Bike", 25, "Truck", 120)));
        tollPoints.add(new Toll(2, Map.of("Car", 70, "Bike", 30, "Truck", 150)));

        Highway highway = new Highway(tollPoints);

        // Main Menu
        while (true) {
            System.out.println("1. Process Journey");
            System.out.println("2. Display Toll Details");
            System.out.println("3. Display Vehicle Details");
            System.out.println("4. Find Shortest Route and Calculate Toll");
            System.out.println("5. Exit");
            System.out.print("Enter your choice: ");
            int choice = scanner.nextInt();

            switch (choice) {
                case 1:
                    System.out.print("Enter Vehicle Number: ");
                    String vehicleNumber = scanner.next();
                    System.out.print("Enter Vehicle Type (e.g., Car, Bike, Truck): ");
                    String vehicleType = scanner.next();
                    System.out.print("Are you a VIP? (true/false): ");
                    boolean isVIP = scanner.nextBoolean();
                    System.out.print("Enter Start Point: ");
                    int start = scanner.nextInt();
                    System.out.print("Enter End Point: ");
                    int end = scanner.nextInt();

                    // Calculate toll for regular route between start and end
                    int regularToll = highway.calculateRegularTollForRoute(start, end, vehicleType, isVIP);
                    System.out.println("Total Toll Paid: " + regularToll);

                    // Process the journey
                    List<Integer> tollRoute = new ArrayList<>();
                    for (int i = start; i <= end; i++) {
                        tollRoute.add(i);  //[0,1,2]
                    }
                    highway.processJourney(vehicleNumber, vehicleType, isVIP, String.valueOf(start), String.valueOf(end), tollRoute);
                    break;

                case 2:
                    highway.displayTollDetails();
                    break;
                case 3:
                    highway.displayVehicleDetails();
                    break;
                case 4:
                    System.out.print("Enter Start and End Points: ");
                    start = scanner.nextInt();
                    end = scanner.nextInt();

                    // Ensure that the start is always less than or equal to the end
                    if (start > end) {
                        int temp = start;
                        start = end;
                        end = temp;
                    }

                    // Find the shortest route (either forward or backward)
                    List<Integer> tollRouteCircular = highway.findCircularRoute(start, end);
                    System.out.println("Shortest Route Tolls: " + tollRouteCircular);

                    // Calculate and print toll cost for the shortest route
                    System.out.print("Enter Vehicle Type (e.g., Car, Bike, Truck): ");
                    vehicleType = scanner.next();
                    System.out.print("Are you a VIP? (true/false): ");
                    isVIP = scanner.nextBoolean();

                    int totalCostCircular = highway.calculateTollForRoute(tollRouteCircular, vehicleType, isVIP);
                    System.out.println("Total Toll Cost for Circular Route: " + totalCostCircular);
                    break;
                case 5:
                    System.out.println("Exiting...");
                    return;
                default:
                    System.out.println("Invalid choice!");
            }
        }
    }
}

How It Works

  1. Initialize Tolls: The system initializes a list of tolls with predefined charges for different vehicle types.
  2. Process Journey: A user can enter details of a vehicle’s journey, including the toll points traversed. The system calculates charges, applies discounts (if applicable), and stores the data.
  3. Display Toll Details: This displays information about the vehicles that passed through each toll and the revenue collected.
  4. Display Vehicle Details: This shows the journey history of a specific vehicle, including tolls passed and total charges paid.
  5. Exit: The program terminates.

Sample Output

Here’s an example of interaction with the program:

--- Toll Payment System ---
1. Process Journey
2. Display Toll Details
3. Display Vehicle Details
4. Exit

Enter your choice: 1
Enter vehicle number: TN01AB1234
Enter vehicle type (Car/Bike/Truck): Car
Is VIP (true/false): true
Enter start point: Chennai
Enter end point: Bangalore
Enter tolls passed (comma-separated IDs): 0,1,2
Journey completed! Total Toll Paid: ₹144

--- Toll Payment System ---
Enter your choice: 2
--- Toll Details ---
Toll ID: 0
Vehicles Passed:
Vehicle: TN01AB1234, Paid: ₹40
Total Revenue: ₹40
...

Key Features

  1. Object-Oriented Design: Each component of the system has a dedicated class, making the code modular and scalable.
  2. Customizable: Toll charges and discount rates can be easily adjusted.
  3. Flexible: The highway is circular, and journeys in both directions are supported.

Conclusion

This solution demonstrates the use of OOP principles like encapsulation, abstraction, and modularity. It effectively handles the problem requirements while remaining flexible for future enhancements.

Let me know if you have any questions or feedback! 🚀

Picture of aravind16101800@gmail.com

aravind16101800@gmail.com

Leave a Reply

Your email address will not be published. Required fields are marked *