The Zoho Round 3 Question tasked candidates with designing a Railway Ticket Booking Application with four main functionalities:
- Book
- Cancel
- Print booked tickets (details with summary)
- Print available tickets (details with summary)
This article walks you through the problem, the conditions, and the solution code with inline comments to help you understand the implementation step by step.
Table of Contents
Understanding the Problem
The application requires handling different ticket categories:
- Confirmed Tickets: 63 berths (Lower, Upper, Middle).
- RAC Tickets: 9 berths (18 passengers).
- Waiting List Tickets: 10 tickets max.
Conditions for Booking:
- If the passenger is a senior citizen (>60 years) or a female, a lower berth should be allocated if available.
- If all berths are full, assign RAC.
- If RAC is full, assign Waiting List.
- If Waiting List exceeds 10 passengers, display “No tickets available”.
Conditions for Cancellation:
- On canceling a confirmed ticket, an RAC ticket should move to confirmed, and a waiting-list ticket should move to RAC.
Conditions for Printing Tickets:
- Booked Tickets: Display all confirmed passengers with details.
- Available Tickets: Show available berths, RAC slots, and Waiting List slots.
Solution Structure
The solution involves three classes:
- Passenger: Stores passenger details and ticket information.
- TicketSystem: Handles the core logic for booking, canceling, and printing tickets.
- TicketBooking: Provides the user interface to interact with the system.
Code Walkthrough
Passenger Class
This class represents a passenger. It holds information such as name, age, gender, berth preference, and the allotted berth.
public class Passenger {
String name; // Passenger name
int age; // Passenger age
String gender; // Gender of the passenger
String berthPreference; // Lower, Upper, or Middle
String allottedBerth; // The berth allotted to the passenger
String ticketId; // Unique ticket ID for each booking
// Constructor to initialize passenger details
public Passenger(String name, int age, String gender, String berthPreference, String allottedBerth, String ticketId) {
this.name = name;
this.age = age;
this.gender = gender;
this.berthPreference = berthPreference;
this.allottedBerth = allottedBerth;
this.ticketId = ticketId;
}
// Override toString to display ticket details when printed
@Override
public String toString() {
return "Ticket ID: " + ticketId + ", Name: " + name + ", Age: " + age +
", Gender: " + gender + ", Berth: " + allottedBerth;
}
}
TicketSystem Class
This class implements the core functionality: booking, canceling, and printing tickets.
import java.util.*; // Importing utilities for ArrayList, Queue, etc.
public class TicketSystem {
private final List<String> availableBerths = new ArrayList<>(Arrays.asList("L", "U", "M")); // Available confirmed berths
private final Queue<Passenger> racQueue = new LinkedList<>(); // Queue for RAC passengers
private final Queue<Passenger> waitingListQueue = new LinkedList<>(); // Queue for waiting list passengers
private final List<Passenger> confirmedPassengers = new ArrayList<>(); // List of confirmed passengers
private int ticketCounter = 1; // Counter for generating unique ticket IDs
// Booking tickets
public void bookTicket(String name, int age, String gender, String berthPreference) {
String ticketId = "T" + ticketCounter++; // Generate unique ticket ID
Passenger passenger;
// Check for available confirmed tickets
if (!availableBerths.isEmpty()) {
String allocatedBerth = allocateBerth(age, gender, berthPreference);
passenger = new Passenger(name, age, gender, berthPreference, allocatedBerth, ticketId);
confirmedPassengers.add(passenger); // Add to confirmed list
availableBerths.remove(allocatedBerth); // Remove allocated berth
System.out.println("Ticket confirmed: " + passenger);
}
// Check for RAC availability
else if (racQueue.size() < 1) {
passenger = new Passenger(name, age, gender, berthPreference, "RAC", ticketId);
racQueue.offer(passenger); // Add to RAC queue
System.out.println("Ticket in RAC: " + passenger);
}
// Check for Waiting List availability
else if (waitingListQueue.size() < 1) {
passenger = new Passenger(name, age, gender, berthPreference, "Waiting List", ticketId);
waitingListQueue.offer(passenger); // Add to Waiting List
System.out.println("Ticket in Waiting List: " + passenger);
}
// No tickets available
else {
System.out.println("No tickets available");
}
}
// Allocating berth based on conditions
private String allocateBerth(int age, String gender, String preference) {
if (age > 60 || gender.equalsIgnoreCase("female") && availableBerths.contains("L")) {
return "L"; // Prioritize lower berth
}
if (availableBerths.contains(preference)) {
return preference; // Allocate preferred berth
}
return availableBerths.get(0); // Allocate first available berth
}
// Canceling tickets
public void cancelTicket(String ticketId) {
Optional<Passenger> passengerOpt = confirmedPassengers.stream()
.filter(p -> p.ticketId.equals(ticketId))
.findFirst();
if (passengerOpt.isPresent()) {
Passenger passenger = passengerOpt.get();
confirmedPassengers.remove(passenger);
availableBerths.add(passenger.allottedBerth);
// Move RAC to confirmed
if (!racQueue.isEmpty()) {
Passenger racPassenger = racQueue.poll();
String allocatedBerth = allocateBerth(racPassenger.age, racPassenger.gender, racPassenger.berthPreference);
racPassenger.allottedBerth = allocatedBerth;
confirmedPassengers.add(racPassenger);
availableBerths.remove(allocatedBerth);
System.out.println("RAC ticket moved to confirmed: " + racPassenger);
}
// Move Waiting List to RAC
if (!waitingListQueue.isEmpty()) {
Passenger waitingPassenger = waitingListQueue.poll();
racQueue.offer(waitingPassenger);
waitingPassenger.allottedBerth = "RAC";
System.out.println("Waiting list ticket moved to RAC: " + waitingPassenger);
}
System.out.println("Ticket cancelled successfully for ID: " + ticketId);
} else {
System.out.println("No ticket found with ID: " + ticketId);
}
}
// Printing confirmed tickets
public void printBookedTickets() {
if (confirmedPassengers.isEmpty()) {
System.out.println("No confirmed tickets.");
} else {
System.out.println("Confirmed Tickets:");
for (Passenger passenger : confirmedPassengers) {
System.out.println(passenger);
}
}
}
// Printing available tickets
public void printAvailableTickets() {
System.out.println("Available Berths: " + availableBerths.size());
System.out.println("Available RAC Tickets: " + (1 - racQueue.size()));
System.out.println("Available Waiting List Tickets: " + (1 - waitingListQueue.size()));
}
}
TicketBooking Class
The main class provides a menu-driven interface for the user.
import java.util.Scanner;
public class TicketBooking {
public static void main(String[] args) {
TicketSystem ticketSystem = new TicketSystem();
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.println("\nRailway Booking System:");
System.out.println("1. Book Ticket");
System.out.println("2. Cancel Ticket");
System.out.println("3. View Confirmed Tickets");
System.out.println("4. View Available Tickets");
System.out.println("5. Exit");
System.out.print("Enter your choice: ");
int choice = scanner.nextInt();
scanner.nextLine();
switch (choice) {
case 1:
System.out.print("Enter Name: ");
String name = scanner.nextLine();
System.out.print("Enter Age: ");
int age = scanner.nextInt();
scanner.nextLine();
System.out.print("Enter Gender (Male/Female): ");
String gender = scanner.nextLine();
System.out.print("Enter Berth Preference (L/U/M): ");
String berthPreference = scanner.nextLine();
ticketSystem.bookTicket(name, age, gender, berthPreference);
break;
case 2:
System.out.print("Enter Ticket ID to Cancel: ");
String ticketId = scanner.nextLine();
ticketSystem.cancelTicket(ticketId);
break;
case 3:
ticketSystem.printBookedTickets();
break;
case 4:
ticketSystem.printAvailableTickets();
break;
case 5:
System.out.println("Exiting...");
System.exit(0);
default:
System.out.println("Invalid choice. Try again.");
}
}
}
}
How It Works
- Run the application.
- Use the menu to book, cancel, or view tickets.
- The application handles RAC and Waiting List dynamically during cancellation.
This solution ensures proper handling of railway ticket bookings with clear logic for each functionality.