Seat Booking System

Problem

A cinema has R rows and C seats in each row (numbered from 1). The first line is R and C. Commands: BOOK r c prints ok, taken (already booked) or invalid (outside the room). CANCEL r c prints ok, free (it was not booked) or invalid. FREE prints the number of free seats. FIRST prints the first free seat as r c (row by row from the front, left to right) or full when no seat is free.

Constraints

  • 1 <= R, C <= 100
  • 1 <= commands <= 10^4

Examples

Input

2 2
BOOK 1 1
FIRST
BOOK 1 1
FREE

Output

ok
1 2
taken
3

Solutions

Best approachTime O(n * R * C)Space O(R * C)

The grid is hidden inside the class. Every public method first checks that the seat is inside the room, so wrong seat numbers can never break the data.

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Process lines.
 * Input   : Several command lines.
 * Output  : One result per command.
 * Approach: Theater class with a grid.
 * Time    : O(n * R * C)
 * Space   : O(R * C)
 * Java    : 8 or newer.
 */
import java.util.Scanner;

public class Main {
        // Step 1: The theater owns a grid of booked flags. The outside world only uses book(), cancel(), free() and first().
        static class Theater {
            private final boolean[][] booked;
            private final int rows;
            private final int columns;

            Theater(int rows, int columns) {
                this.rows = rows;
                this.columns = columns;
                this.booked = new boolean[rows][columns];
            }

            private boolean inside(int r, int c) {
                return r >= 1 && r <= rows && c >= 1 && c <= columns;
            }

            // Step 2: Each method checks that the seat exists before it looks at the flag.
            String book(int r, int c) {
                if (!inside(r, c)) {
                    return "invalid";
                }
                if (booked[r - 1][c - 1]) {
                    return "taken";
                }
                booked[r - 1][c - 1] = true;
                return "ok";
            }

            String cancel(int r, int c) {
                if (!inside(r, c)) {
                    return "invalid";
                }
                if (!booked[r - 1][c - 1]) {
                    return "free";
                }
                booked[r - 1][c - 1] = false;
                return "ok";
            }

            int free() {
                int count = 0;
                for (boolean[] row : booked) {
                    for (boolean flag : row) {
                        if (!flag) {
                            count++;
                        }
                    }
                }
                return count;
            }

            String first() {
                for (int r = 0; r < rows; r++) {
                    for (int c = 0; c < columns; c++) {
                        if (!booked[r][c]) {
                            return (r + 1) + " " + (c + 1);
                        }
                    }
                }
                return "full";
            }
        }

    // This method solves the task. It receives the input and returns the answer.
    static String[] solve(String[] lines) {
        String[] size = lines[0].split(" ");
        Theater theater = new Theater(Integer.parseInt(size[0]), Integer.parseInt(size[1]));
        String[] output = new String[lines.length - 1];
        for (int i = 1; i < lines.length; i++) {
            String[] part = lines[i].split(" ");
            if (part[0].equals("BOOK")) {
                output[i - 1] = theater.book(Integer.parseInt(part[1]), Integer.parseInt(part[2]));
            } else if (part[0].equals("CANCEL")) {
                output[i - 1] = theater.cancel(Integer.parseInt(part[1]), Integer.parseInt(part[2]));
            } else if (part[0].equals("FREE")) {
                output[i - 1] = String.valueOf(theater.free());
            } else {
                output[i - 1] = theater.first();
            }
        }
        return output;
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        java.util.List<String> all = new java.util.ArrayList<>();
        while (scanner.hasNextLine()) {
            String line = scanner.nextLine().trim();
            if (!line.isEmpty()) {
                all.add(line);
            }
        }
        String[] lines = all.toArray(new String[0]);
        System.out.println(String.join("\n", solve(lines)));
    }
}
Hints (2)
  1. Why check the seat before reading the grid?
  2. Why is FIRST row by row?