Library Lending with Classes
Problem
A library has books. Commands: add TITLE (print added, or exists if the title is already there), borrow TITLE USER (print borrowed, or not available if somebody has it), return TITLE (print returned, or not borrowed if it is on the shelf), who TITLE (print the user who has the book, or shelf). If the title is unknown, every command except add prints no such book.
Constraints
- 1 <= commands <= 100
- TITLE and USER have no spaces
Examples
Input
add java borrow java amit who java
Output
added borrowed amit
Solutions
Each class owns its rules: the Book knows if it can be lent, the Library knows which books exist. The commands only call methods and never touch the fields of a book directly.
/*
* Problem : Run the library.
* Input : Command lines.
* Output : One answer line 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 knows its own state: who has it (null means it is on the shelf).
static class Book {
final String title;
String holder;
Book(String title) {
this.title = title;
}
// Step 2: The book guards its own rules.
boolean lend(String user) {
if (holder != null) {
return false;
}
holder = user;
return true;
}
boolean giveBack() {
if (holder == null) {
return false;
}
holder = null;
return true;
}
}
// Step 3: The Library owns the books and answers the commands.
static class Library {
private final java.util.Map<String, Book> books = new java.util.HashMap<>();
String run(String[] part) {
if (part[0].equals("add")) {
if (books.containsKey(part[1])) {
return "exists";
}
books.put(part[1], new Book(part[1]));
return "added";
}
Book book = books.get(part[1]);
if (book == null) {
return "no such book";
}
if (part[0].equals("borrow")) {
return book.lend(part[2]) ? "borrowed" : "not available";
}
if (part[0].equals("return")) {
return book.giveBack() ? "returned" : "not borrowed";
}
return book.holder == null ? "shelf" : book.holder;
}
}
// This method solves the task. It receives the input and returns the answer.
static String[] solve(String[] lines) {
Library library = new Library();
String[] out = new String[lines.length];
for (int i = 0; i < lines.length; i++) {
out[i] = library.run(lines[i].split(" "));
}
return out;
}
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 class decides if a book can be lent?