Crash Code Part-6 (Event Reservation System!)

Trying to solve old coding questions, because reasons: The Theater Booking Service

BLZR

CodePython

Crash Code

1544 Words [Mind Tax: 7:01m]

20 August 2026, 6:30:00 PM


Problem Description

You are tasked with implementing a ShowBooking service for a theater with multiple auditoriums. Each auditorium has a fixed seating capacity and can host a single event per day.

The service needs to:

  • Store which event will take place in an auditorium of the theater.
  • Avoid conflicts when multiple customers are concurrently booking tickets for the same event by utilizing an “under booking” state.

You must implement two classes:

  1. Repo (implementing the IRepo interface): Handles all state and storage—mapping events to auditoriums, tracking active “under booking” requests, and storing successfully confirmed bookings.
  2. BookingService (implementing the IBookingService interface): Validates capacity constraints and processes booking transitions.

Constraints

  • 1 <= totalNumberOfRequests <= 100,000
  • 1 <= userId <= 100,000
  • 1 <= eventId <= 100,000
  • 1 <= auditoriumNumber <= 100,000

Input

  • The first line contains an integer n, the total number of auditoriums.
  • The second line contains n space-separated integers representing the eventId assigned to each auditorium. (The index i of the element is its auditoriumNumber).
  • The third line contains n space-separated integers representing the capacity of each auditorium.
  • The fourth line contains the number of incoming booking requests q.
  • The next q lines contain queries structured as:
  • startBookingProcess <eventId> <userId>
  • confirmBookingStatus <eventId> <userId> <true/false>

Output

  • For startBookingProcess, output true if initiated successfully (capacity allowed), otherwise false.
  • For confirmBookingStatus, output successful <auditoriumNumber> if the booking succeeded, or failed <auditoriumNumber> if it did not. (Note: The driver code handles this printing based on your returned objects).

Examples

Example

Input:

6
4 5 7 1 2 3
2 2 2 2 2 2
5
startBookingProcess 7 1
startBookingProcess 7 2
startBookingProcess 7 3
confirmBookingStatus 7 1 true
startBookingProcess 7 4

Output:

true
true
false
successful 2
false

Explanation:

n = 6 auditoriums.
Event 7 is mapped to auditorium index 2, with a capacity of 2.

Query 1: User 1 starts booking Event 7. Capacity is 0/2. Result: true. (1 seat under booking).
Query 2: User 2 starts booking Event 7. Capacity is 1/2. Result: true. (2 seats under booking).
Query 3: User 3 starts booking Event 7. Capacity is 2/2. Result: false. (Rejected).
Query 4: User 1 confirms booking. User 1 moves from "under booking" to "successful". Output: successful 2.
Query 5: User 4 starts booking Event 7. Currently 1 successful + 1 under booking = 2/2 capacity. Result: false. 

The Concepts Under the Hood

Instead of looping over complex lists of reservations every time a user makes a request, we leverage Python’s Dictionaries and Sets for O(1) time complexity lookups. This allows the application to handle massive inputs efficiently.

Here is the logical flow:

  1. Lightweight Data Classes: We use Python’s NamedTuple to quickly define Auditorium and BookingConclusion data structures. They are immutable and highly readable.
  2. State Management via Dictionaries: Inside the Repo class, we maintain three dictionaries.
    • events_auditorium maps an event_id to its Auditorium object.
    • under_booking maps an event_id to a set() of user_ids who are in the middle of a transaction. (Sets natively prevent accidental duplicate bookings from the same user).
    • successful_booking maps an event_id to a set() of user_ids with finalized tickets.
  3. Safe Removals: When a booking is finalized or fails, we must remove the user from the under_booking set. Using Python’s set.discard() instead of set.remove() is a great trick to avoid unexpected KeyError crashes in case of bad inputs or misaligned states.

Visualizing the Memory State

Let’s look at how the memory states look inside our Repo during the critical steps of the example test case.

Step 1: Initialization After reading the inputs, Event 7 is registered in Auditorium 2 with a capacity of 2.

events_auditorium[7] = Auditorium(auditorium_number=2, event_id=7, capacity=2)
under_booking[7] = set()
successful_booking[7] = set()

Step 2: Processing startBookingProcess Users 1 and 2 start booking. We check len(under_booking) + len(successful_booking). It’s 0 < 2, then 1 < 2. Both users are added to the set.

under_booking[7] = {1, 2}

When User 3 tries, 2 < 2 is false. They are rejected.

Step 3: Processing confirmBookingStatus User 1 confirms successfully. We discard(1) from under_booking and add(1) to successful_booking.

under_booking[7] = {2}
successful_booking[7] = {1}

When User 4 tries to start a booking, we check lengths again: 1 (under) + 1 (successful) = 2. Since 2 < 2 is false, User 4 is instantly rejected!

Solve

Here is the fully combined, runnable code including the driver boilerplate and the original documentation strings. You can run this directly in your Python terminal.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
from abc import ABC, abstractmethod
from typing import NamedTuple

# --- Interfaces and Data Structures ---

class IBookingService(ABC):
    @abstractmethod
    def start_booking_process(self, event_id: int, user_id: int) -> bool:
        pass

    @abstractmethod
    def confirm_booking_status(self, event_id: int, user_id: int, booking_successful: bool) -> 'BookingConclusion':
        pass

class IRepo(ABC):
    @abstractmethod
    def register_event_in_auditorium(self, auditorium_number: int, event_id: int, capacity: int) -> None:
        pass
    
    @abstractmethod
    def get_auditorium_details_for_event(self, event_id: int) -> 'Auditorium':
        pass
    
    @abstractmethod
    def get_number_of_seats_books_or_under_booking_for_event(self, event_id: int) -> int:
        pass
    
    @abstractmethod
    def add_under_booking(self, event_id: int, user_id: int) -> None:
        pass
    
    @abstractmethod
    def remove_under_booking(self, event_id: int, user_id: int) -> None:
        pass
    
    @abstractmethod
    def add_successful_booking(self, event_id: int, user_id: int) -> None:
        pass

class BookingConclusion(NamedTuple):
    is_successful: bool
    auditorium_number: int

class Auditorium(NamedTuple):
    auditorium_number: int
    event_id: int
    capacity: int


# --- Implementation ---

class BookingService(IBookingService):
    def __init__(self, repo: IRepo) -> None:
        self.repo = repo

    def start_booking_process(self, event_id: int, user_id: int) -> bool:
        """
        Initiates the booking process for a given event and user.

        :param event_id: Identifier of the event.
        :param user_id: Identifier of the user.
        :return: True if the booking process is initiated successfully, False otherwise.
        """
        auditorium = self.repo.get_auditorium_details_for_event(event_id)
        if not auditorium:
            return False
            
        current_bookings = self.repo.get_number_of_seats_books_or_under_booking_for_event(event_id)
        
        if current_bookings < auditorium.capacity:
            self.repo.add_under_booking(event_id, user_id)
            return True
            
        return False

    def confirm_booking_status(self, event_id: int, user_id: int, booking_successful: bool) -> 'BookingConclusion':
        """
        Confirms the booking status for a given event and user.

        :param event_id: Identifier of the event.
        :param user_id: Identifier of the user.
        :param booking_successful: True if the booking is successful, False otherwise.
        :return: An instance of BookingConclusion indicating the result of the booking.
        """
        self.repo.remove_under_booking(event_id, user_id)
        
        if booking_successful:
            self.repo.add_successful_booking(event_id, user_id)
            
        auditorium = self.repo.get_auditorium_details_for_event(event_id)
        auditorium_number = auditorium.auditorium_number if auditorium else -1
        
        return BookingConclusion(booking_successful, auditorium_number)


class Repo(IRepo):
    def __init__(self) -> None:
        self.events_auditorium = {}
        self.under_booking = {}
        self.successful_booking = {}

    def register_event_in_auditorium(self, auditorium_number: int, event_id: int, capacity: int) -> None:
        """
        Registers an event in an auditorium with specified details.

        :param auditorium_number: Identifier of the auditorium.
        :param event_id: Identifier of the event.
        :param capacity: Capacity of the auditorium.
        """
        self.events_auditorium[event_id] = Auditorium(auditorium_number, event_id, capacity)
        self.under_booking[event_id] = set()
        self.successful_booking[event_id] = set()

    def get_number_of_seats_books_or_under_booking_for_event(self, event_id: int) -> int:
        """
        Gets the number of seats booked or under booking for a given event.

        :param event_id: Identifier of the event.
        :return: The total number of seats booked or under booking.
        """
        active_under = len(self.under_booking.get(event_id, set()))
        active_booked = len(self.successful_booking.get(event_id, set()))
        return active_under + active_booked

    def add_under_booking(self, event_id: int, user_id: int) -> None:
        """
        Adds a user under booking for a given event.

        :param event_id: Identifier of the event.
        :param user_id: Identifier of the user.
        """
        if event_id in self.under_booking:
            self.under_booking[event_id].add(user_id)

    def remove_under_booking(self, event_id: int, user_id: int) -> None:
        """
        Removes a user from under booking for a given event.

        :param event_id: Identifier of the event.
        :param user_id: Identifier of the user.
        """
        if event_id in self.under_booking:
            self.under_booking[event_id].discard(user_id)

    def add_successful_booking(self, event_id: int, user_id: int) -> None:
        """
        Adds a user to successful bookings for a given event.

        :param event_id: Identifier of the event.
        :param user_id: Identifier of the user.
        """
        if event_id in self.successful_booking:
            self.successful_booking[event_id].add(user_id)
            
    def get_auditorium_details_for_event(self, event_id: int) -> 'Auditorium':
        """
        Gets the details of the auditorium for a given event.

        :param event_id: Identifier of the event.
        :return: An instance of Auditorium containing details of the auditorium.
        """
        return self.events_auditorium.get(event_id)

# --- Driver Code ---

if __name__ == "__main__":
    total_number_of_auditoriums = int(input().strip())
    event_id_in_auditorium = list(map(int, input().split()))
    capacity_of_auditorium = list(map(int, input().split()))

    repo = Repo()
    for i in range(total_number_of_auditoriums):
        repo.register_event_in_auditorium(i, event_id_in_auditorium[i], capacity_of_auditorium[i])

    booking_service = BookingService(repo)

    total_number_of_requests = int(input().strip())
    for request_number in range(1, total_number_of_requests + 1):
        query, *inp = input().split()
        even_id, user_id = map(int, inp[0:2])
        
        if query == "startBookingProcess":
            did_start_booking_process = booking_service.start_booking_process(even_id, user_id)
            if did_start_booking_process:
                print("true")
            else:
                print("false")
                
        elif query == "confirmBookingStatus":
            is_successful_booking = inp[2].lower() == "true"
            booking_conclusion = booking_service.confirm_booking_status(even_id, user_id, is_successful_booking)
            if booking_conclusion is None:
                print("Booking not initiated")
            else:
                print(f"{'successful' if booking_conclusion.is_successful else 'failed'} {booking_conclusion.auditorium_number}")