Library Management System
Problem
Simulate a small library. Commands: add TITLE, borrow TITLE USER, return TITLE and status TITLE (titles and users are single words). add prints added or exists. borrow prints borrowed, already borrowed or not found. return prints returned, not borrowed or not found. status prints available, borrowed by USER or not found.
Constraints
- 1 <= lines <= 10^4
Examples
Input
add java borrow java ravi status java
Output
added borrowed borrowed by ravi
Solutions
Each class has one job: Book knows if it is lent, Library finds books and checks the rules. The order of the checks matters: first does the book exist, then is it available.
/*
* Problem : Process commands line by line.
* Input : Several lines of commands.
* Output : One answer per command.
* Approach: Book and Library classes.
* Time : O(n)
* Space : O(n)
* Java : 8 or newer.
*/
import java.util.Scanner;
public class Main {
// Step 1: A Book keeps its own state. borrower is null when the book is on the shelf.
static class Book {
private String borrower = null;
boolean isAvailable() {
return borrower == null;
}
void lendTo(String user) {
borrower = user;
}
void giveBack() {
borrower = null;
}
String getBorrower() {
return borrower;
}
}
// Step 2: The Library keeps all books in a map from the title to the Book object.
static class Library {
private final java.util.Map<String, Book> books = new java.util.HashMap<>();
String process(String[] parts) {
String command = parts[0];
Book book = books.get(parts[1]);
if (command.equals("add")) {
if (book != null) {
return "exists";
}
books.put(parts[1], new Book());
return "added";
}
// Step 3: All other commands need an existing book.
if (book == null) {
return "not found";
}
if (command.equals("borrow")) {
if (!book.isAvailable()) {
return "already borrowed";
}
book.lendTo(parts[2]);
return "borrowed";
}
if (command.equals("return")) {
if (book.isAvailable()) {
return "not borrowed";
}
book.giveBack();
return "returned";
}
return book.isAvailable() ? "available" : "borrowed by " + book.getBorrower();
}
}
// This method solves the task. It receives the input and returns the answer.
static String[] solve(String[] lines) {
Library library = new Library();
String[] output = new String[lines.length];
for (int i = 0; i < lines.length; i++) {
// Step 4: Send every command line to the library and keep its answer.
output[i] = library.process(lines[i].split(" "));
}
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 (1)
- Which check must come first in borrow?