Build a Railway Reservation System

Difficulty: Hard · Category: Booking System · Languages: Java 17, Python 3.11, Go 1.22, Node.js 20, TypeScript 5.x

Railway Reservation System

1. Objective

Build a railway reservation system that supports:

The system simulates basic Indian railway booking logic. The kv-store provides an in-memory key-value API for managing bookings and seat state — no external database server required.

Recommended infrastructure: kv-store — an in-memory key-value store for managing bookings and seat state, but you may use pure Java collections if you prefer.

How It Works

The platform injects your chosen infrastructure SDK(s) via constructor. For example, if you use the kv-store:

public class MyReservationSystem implements TrainTicketBookingContract {
    private final KVStoreClient kvStore;

    public MyReservationSystem(KVStoreClient kvStore) {
        this.kvStore = kvStore;
    }

    // ... implement methods using kvStore.put(), kvStore.get(), etc.
}

See the SDK Docs tab for the full API reference of your chosen system.

2. Scope

In Scope:

Out of Scope:

3. System Constraints

Train capacity is fixed. Example configuration:

TypeCount
Confirmed Berths63
RAC Seats18
Waiting List10
Total potential tickets91

4. Berth Types

Supported berth types: LOWER, MIDDLE, UPPER, SIDE_LOWER, SIDE_UPPER

Example distribution:

BerthCount
LOWER21
MIDDLE21
UPPER21
SIDE_LOWER10
SIDE_UPPER10

The initialize() method sets total confirmed berths. Distribute berth types as you see fit, ensuring all five types exist.

5. Core Entity

Passenger
---------
passengerId
name
age
gender
berthPreference
allocatedBerth
seatNumber
status

Status values: CONFIRMED, RAC, WAITING, CANCELLED

6. Recommended Data Structures

Map<String, Passenger> allPassengers     // keyed by passengerId
Map<Integer, Passenger> confirmedSeats    // keyed by seatNumber
Queue<Passenger>        racQueue          // FIFO
Queue<Passenger>        waitingList       // FIFO

Seat tracking:

Map<Integer, String>  berthMap    // seatNumber → berthType
Map<Integer, Boolean> seatStatus  // seatNumber → occupied?

7. Seat Allocation Rules

Rule 1 — Confirmed Seats

If confirmed seats are available: assign the passenger a berth based on preference if possible. If the preferred berth is unavailable, assign any available berth. Status = CONFIRMED.

Rule 2 — RAC

If confirmed seats are full: passenger goes to the RAC queue. RAC passengers share side-lower berths (2 RAC passengers per berth). Status = RAC.

Rule 3 — Waiting List

If RAC is also full: passenger goes to the waiting list. No berth or seat is assigned. Status = WAITING.

Rule 4 — Booking Rejection

If all lists are full: reject the booking (return null).

8. Booking Flow

IF confirmed seat available
    allocate seat with berth preference
    status = CONFIRMED
ELSE IF RAC available
    push to RAC queue
    status = RAC
ELSE IF waiting list available
    push to waiting queue
    status = WAITING
ELSE
    reject booking (return null)

9. Cancellation & Promotion Logic

When a booking is cancelled:

Cancel the passenger

IF cancelled passenger was CONFIRMED
    free the berth
    IF RAC not empty
        move first RAC → CONFIRMED (assign freed berth)
    IF waiting list not empty
        move first WAITING → RAC

ELSE IF cancelled passenger was RAC
    remove from RAC queue
    IF waiting list not empty
        move first WAITING → RAC

ELSE IF cancelled passenger was WAITING
    simply remove from waiting list

This simulates real railway promotion logic.

10. Promotion Flow Example

Initial state: Confirmed = 63, RAC = 10, Waiting = 5

One confirmed passenger cancels:

1. Free the confirmed berth
2. RAC[0] → CONFIRMED (assign the berth)
3. WL[0] → RAC

Final state: Confirmed = 63, RAC = 10, Waiting = 4

11. Seat Tracking Example

Example seat map:

Seat 1 → LOWER
Seat 2 → MIDDLE
Seat 3 → UPPER
Seat 4 → LOWER
Seat 5 → MIDDLE
Seat 6 → UPPER

Allocation example:

Passenger preference: LOWER

Check available LOWER seats
IF available → assign that seat
IF not available → allocate next free seat of any type

12. Interface

public interface TrainTicketBookingContract {
    void initialize(int confirmedBerths, int racCapacity, int waitingListCapacity);
    String bookPassenger(String name, int age, String gender, String berthPreference);
    boolean cancelBooking(String passengerId);
    Map<String, Object> getBookingDetails(String passengerId);
    Map<String, Integer> getAvailableCounts();
    List<Map<String, Object>> getConfirmedPassengers();
    List<Map<String, Object>> getRACQueue();
    List<Map<String, Object>> getWaitingList();
    Map<String, Integer> getBookedCount();
}

13. Method Details

MethodDescription
initializeSet up the system with capacities. Resets all state.
bookPassengerBook a single passenger. Returns unique ID, or null if all lists full.
cancelBookingCancel a passenger and trigger promotion chain. Returns false if not found or already cancelled.
getBookingDetailsReturns a map with keys: passengerId, name, age, gender, berthPreference, allocatedBerth, seatNumber, status.
getAvailableCountsReturns {"confirmed": N, "rac": N, "waitingList": N}.
getConfirmedPassengersAll confirmed passengers with berth/seat info.
getRACQueueRAC queue in FIFO order.
getWaitingListWaiting list in FIFO order.
getBookedCount{"CONFIRMED": N, "RAC": N, "WAITING": N} (excludes cancelled).

14. Error Handling

ScenarioBehaviour
Invalid / unknown passenger IDReturn null or false
Cancel already cancelled bookingReturn false
Waiting list fullReject booking (return null)
Invalid berth preferenceTreat as "NONE" — default allocation

15. Example Booking Scenario

initialize(63, 18, 10)

// Confirmed booking with preference
id1 = bookPassenger("Arun", 32, "M", "LOWER")
getBookingDetails(id1)
→ {status=CONFIRMED, allocatedBerth=LOWER, seatNumber=1, ...}

// Fill all 63 confirmed berths...
// Next passenger goes to RAC
id64 = bookPassenger("Ravi", 28, "M", "UPPER")
getBookingDetails(id64)
→ {status=RAC, allocatedBerth=null, seatNumber=-1, ...}

// Fill all 18 RAC slots...
// Next passenger goes to Waiting List
id82 = bookPassenger("Priya", 25, "F", "LOWER")
getBookingDetails(id82)
→ {status=WAITING, allocatedBerth=null, seatNumber=-1, ...}

// All 91 slots full — booking rejected
id92 = bookPassenger("TooLate", 30, "M", "NONE")  → null

// Cancellation triggers promotion chain
cancelBooking(id1)  → true
// RAC[0] promoted to CONFIRMED (gets a berth)
// WL[0] promoted to RAC

16. Core Algorithms Required

AlgorithmMethod
Seat allocation with preferencebookPassenger(...)
RAC queue managementbookPassenger(...) / promotion
Waiting list managementbookPassenger(...) / promotion
Promotion chaincancelBooking(...)

17. Constraints

18. Hints

Infrastructure your code runs against

How your solution is graded

Your score combines functional correctness (50%), performance (30%) and code quality (20%).

Practice this problem

Related LLD problems