top of page

Airplane Problem


Question:

The question asks you to find the most effective way to accommodate family members in an aircraft such that no one sits alone i.e. at least 2 members sit together.

In computational terms:

  • Your input consists of the number of rows in an aircraft, number of seats per row in the aircraft, the list of seats that have been occupied prior to booking the seats for the family members and the number of family members you need to accommodate.

  • Let each row be numbered from 1 to num_of_rows and each seat from left to right be labelled as A, B, C……

  • We need to find the seats allocated to the family members such that, at least 2 of them sit alone, all of them sit as close as possible and if the number of seats available is less than the number of family members then try to accommodate the maximum number of members if not all.

Input:


rows = 3
seats_per_row = 6
num_passengers = 7 # Number of passengers in the family
pre_booked_seats = [(1, 'B'), (1, 'C'), (2, 'B'), (2, 'D'), (3, 'A'), (3, 'C'), (3, 'F')]

Approach:

As we can clearly see, there is a lot of information provided to us about the airplane, hence it would be wise to create an Airplane class that helps us manage and access this information easily.

class Airplane:
    def __init__(self, rows, seats_per_row):
        self.rows = rows
        self.seats_per_row = seats_per_row
        self.seat_map = self._generate_seat_map()

In order to make it easier to visualise the seats, we can define the airplane as a 2-D array.

Row 1 :  O B B X X X
Row 2 :  O B O B X X
Row 3 :  B O B X X B

In this representation, let

  • 0 -> available

  • B -> occupied

  • X -> Seats allocated to family members.

This approach allows us to easily check a seats availability by indexing in the 2-D array instead of iterating each time and finding the seat.This 2-D array generation is done by the generate_seat_map() method in the airplane class:

    def _generate_seat_map(self):
        return [['O'] * self.seats_per_row for _ in range(self.rows)]

Lets now define the methods to mark the seats accordingly and also define a method to check the seats status:

    def _check_available(self, row, seat):  #checks if seat is available
        return self.seat_map[row][seat] == 'O'

    def book_seats(self, seats):     #books seats for family
        for seat in seats:
            row, seat_char = seat
            self.seat_map[row - 1][ord(seat_char) - 65] = 'X'

    def pre_book_seats(self, seats):  #blocks the seats in the list of occupied seats
        for seat in seats:
            row, seat_char = seat
            self.seat_map[row - 1][ord(seat_char) - 65] = 'B'

    def print_seat_map(self):
        print('         ', end = '')
        for i in range(self.seats_per_row):
            print(chr(65 + i), end = ' ')
        print('\n', '----------------------------')
        for row_num, row in enumerate(self.seat_map, start=1):
            print("Row", row_num, ": ", " ".join(row))

Now of course, lets come to how to find the seats.Our best case scenario is that we find seats for all members together (either in the same row or in the next consecuitive seat fot eh next row). So lets define that function:

def allocate_seats(self, num_passengers):
    allocated_seats = []
    # Try to allocate seats together for the whole family
    for row in range(self.rows):
        for seat in range(self.seats_per_row - num_passengers + 1):
            if all(self._check_available(row, seat + i) for i inrange(num_passengers)):
                for i in range(num_passengers):
                    allocated_seats.append((row + 1, chr(65 + seat + i)))
                return allocated_seats

This function takes in the number of passengers to be seated together, and find that many consexutive seats.

Of course not alwasy will we find cosecutive seats. So your logic to implement the function could be

  • if there are k family members. Try to seat k family members together.

  • If cannot, we know that at least two must sit togther, so try to accomodate (k-2) members in consecutive seats and the other 2 sit together elsewhere.

  • If you cannot accomodate (k-2) either, then try (k-4) and try to accomoadate the second detached pair else where.

  • With this method, there will be cases where lets say you have 3 seats consecutively available somewhere. While trying to accomodate the 2 people (the ones seperated from the k), you make them sit on 2 of the 3 seats. However, you may have people left with no seat at the end of the algorithm. In this case, you search the plane again to find another family member and make them sit with them.

def main():
    airplane = Airplane(rows=3, seats_per_row=6)  # Example airplane configuration
    rows, col = airplane.rows, airplane.seats_per_row
    num_passengers = 7# Number of passengers in the family
    pre_booked_seats = [(1, 'B'), (1, 'C'), (2, 'B'), (2, 'D'), (3, 'A'), (3, 'C'), (3, 'F')]
    airplane.pre_book_seats(pre_booked_seats)

    # Allocate seats for the family
    a = num_passengers
    k = 0
    count = 0
    seated = 0
    seat_array = []
    while a > 2: 
        a = num_passengers - (2*k)
        #print(a, k , seated)
        seats = airplane.allocate_seats(a)

        if seats and a >= 2:    #give consecutive seats to max people possible
           
            for allocated_seat in seats:
                seat_array.append(allocated_seat)
                count +=1
            airplane.book_seats(seats)
    
        rem_seats = airplane.allocate_seats(2*k - seated)

        if rem_seats:       #allocate seats to the detached pair
            for allocated_seat in rem_seats:
                seat_array.append(allocated_seat)
                count +=1
            airplane.book_seats((rem_seats))
        k+=1
        seated = count
        if count == num_passengers:
            break
            
    #find seats next to their family members for the people left out in the end
    def find_seats(rows, cols, blocked_seats, booked_seats, k):
        available_seats = []

        for row_num in range(1, rows + 1):
            for col_label in range(ord('A'), ord('A') + cols):
                seat = (row_num, chr(col_label))
                if seat not in blocked_seats and seat not in booked_seats:
                    col_idx = col_label - ord('A')
                    if (col_idx > 0 and (row_num, chr(col_label - 1)) in booked_seats) or \
                            (col_idx < cols - 1 and (row_num, chr(col_label + 1)) in booked_seats):
                        available_seats.append(seat)
                        k -= 1
                        if k == 0:
                            return available_seats

        return available_seats
        
    if seated < num_passengers:
        left_seats = find_seats(rows, col, pre_booked_seats, seat_array, num_passengers - seated)
        for i in left_seats:
            seat_array.append(i)
        airplane.book_seats(left_seats)
        seated += len(left_seats)
        
    if seated != num_passengers:
        print('could only accmomodate', seated, 'people')
        
    print('List of seats:' , seat_array, '\n')
    airplane.print_seat_map()

Output:

List of seats: [(1, 'D'), (1, 'E'), (2, 'E'), (2, 'F'), (3, 'D'), (3, 'E'), (1, 'F')] 

         A B C D E F 
 ----------------------------
Row 1 :  O B B X X X
Row 2 :  O B O B X X
Row 3 :  B O B X X B

21 views0 comments

Recent Posts

See All

Navigating the Interview Process: A Comprehensive Guide

Introduction: In the competitive landscape of tech hiring, employers are constantly seeking candidates who not only possess technical prowess, but also exhibit problem-solving abilities and critical t

bottom of page