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.
Table of Contents
Question: Toll Payment Processing System
Application Description:
- There are ’n’ points on a highway. Some of these points are toll gates.
- Each toll gate has a unique charging scheme based on vehicle type (Car, Bike, Truck) and whether the user is VIP.
- VIP users receive a 20% discount on toll charges.
- A vehicle passing through multiple tolls must pay at each toll according to its respective scheme.
- The highway is considered circular, allowing vehicles to travel in both directions.
Modules:
- Process Journey
Calculate the toll charges for a journey, including discounts if applicable. - Display Toll Details
Display details of vehicles passing each toll and the total revenue collected. - Display Vehicle Details
Show journeys taken by each vehicle, tolls passed, and total toll charges paid. - Find Shortest Route and Calculate Toll
Identify the shortest path between two points and calculate the toll. - Exit
Terminate the program.
Solution Design
To solve this, I used object-oriented programming (OOP) principles and broke down the problem into six classes:
Toll
Vehicle
Journey
VehiclePayment
Highway
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
- Initialize Tolls: The system initializes a list of tolls with predefined charges for different vehicle types.
- 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.
- Display Toll Details: This displays information about the vehicles that passed through each toll and the revenue collected.
- Display Vehicle Details: This shows the journey history of a specific vehicle, including tolls passed and total charges paid.
- 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
- Object-Oriented Design: Each component of the system has a dedicated class, making the code modular and scalable.
- Customizable: Toll charges and discount rates can be easily adjusted.
- 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! 🚀