This is a design round. You write the classes, and the interviewer checks that they behave.
Here you build Library. It lends books to members and takes them back.
Each book has a number, its id. The library can own several copies of the same book.
Implement the class:
Library::new()makes a library with no books.add_book(book_id, copies)puts that many more copies of the book on the shelf.checkout(member, book_id)lends the member one copy. It returnstrueif it worked.give_back(member, book_id)takes the member's copy back. It returnstrueif it worked.available(book_id)returns how many copies are on the shelf.borrowed(member)returns the ids of the books the member holds, from smallest to largest.
Rust has no classes. Library is a struct, and its methods sit in an impl block. Its new function makes one.
A member holds at most 3 books at a time. A member never holds two copies of the same book.
checkout returns false when no copy is on the shelf. It also returns false when the loan would break a member rule.
give_back returns false when the member doesn't hold that book.
A call that returns false changes nothing.
A book the library never got has 0 copies. A member who never borrowed holds no books.
The calls run in order on one new Library. Every call except add_book writes one line of output. Booleans are written as True and False. A list of ids is written with spaces between them. An empty list is an empty line.
Example 1:
Input:
Library::new()
1. add_book(7, 2)
2. checkout("Ana", 7)
3. checkout("Ana", 7)
4. checkout("Ben", 7)
5. available(7)
6. checkout("Cy", 7)
7. give_back("Ana", 7)
8. checkout("Cy", 7)
9. borrowed("Cy")
Output:
True
False
True
0
False
True
True
7
Explanation:
Call 2 lends Ana one of the two copies.
Call 3 fails, because Ana already holds book 7.
Call 4 lends Ben the other copy. So call 5 returns 0.
Call 6 fails, because no copy is on the shelf.
Ana brings her copy back in call 7, and Cy gets it in call 8.
Example 2:
Input:
Library::new()
1. add_book(30, 1)
2. add_book(10, 1)
3. add_book(20, 1)
4. add_book(40, 1)
5. checkout("Dev", 30)
6. checkout("Dev", 10)
7. checkout("Dev", 20)
8. checkout("Dev", 40)
9. borrowed("Dev")
10. give_back("Dev", 40)
11. give_back("Dev", 10)
12. checkout("Dev", 40)
13. borrowed("Dev")
Output:
True
True
True
False
10 20 30
False
True
True
20 30 40
Explanation:
Dev borrows three books in calls 5, 6 and 7.
Call 8 fails, because Dev already holds 3 books.
Call 9 lists the ids from smallest to largest.
Call 10 fails, because Dev never got book 40.
Call 11 gives book 10 back. Now Dev can borrow book 40.
Example 3:
Input:
Library::new()
1. borrowed("Eve")
2. available(5)
3. checkout("Eve", 5)
4. add_book(5, 1)
5. add_book(5, 2)
6. available(5)
7. checkout("Eve", 5)
8. give_back("Eve", 5)
9. available(5)
Output:
0
False
3
True
True
3
Explanation:
The first output line is empty, because Eve holds no books yet.
The library has no book 5 at first.
So call 2 returns 0, and call 3 fails.
Calls 4 and 5 add 1 copy, then 2 more.
Eve borrows one copy and gives it back. So 3 copies are on the shelf again.
Constraints:
- Each book id is a whole number from 1 to 1,000,000.
copiesis a whole number from 1 to 100.- A member's name has 1 to 10 English letters.
- Names are case-sensitive: Ana and ANA are two members.
- At most 100,000 calls follow the constructor.
Note:
Each call should run in O(1) time. Sorting the ids in borrowed is quick too, because a member holds at most 3.
Free plan: 30 tutor messages. Premium is unlimited.
