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
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.
/*
* 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)
- Why check the seat before reading the grid?
- Why is FIRST row by row?