| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758 |
- import java.util.ArrayList;
- import java.util.List;
- import java.util.stream.Collectors;
-
- class Bookstore {
-
- private static final int BOOK_PRICE = 8, MAX_GROUP_SIZE = 5;
-
- private static double[] DISCOUNT_TIERS = {0, 5, 10, 20, 25};
-
- private List<Integer> books;
-
- Bookstore(List<Integer> books) {
- this.books = books;
- }
-
- double calculateTotalCost() {
- return calculateTotalCost(this.books, 0);
- }
-
- private double calculateTotalCost(List<Integer> books, double priceSoFar) {
- if (books.size() == 0) {
- return priceSoFar;
- }
-
- List<Integer> availableBookNumbers = books.stream()
- .distinct()
- .collect(Collectors.toList());
-
- double minPrice = Double.MAX_VALUE;
-
- for (int i = 0; i < availableBookNumbers.size(); i++) {
- List<Integer> newGroupBooks = new ArrayList<>(availableBookNumbers.subList(0, i + 1));
- List<Integer> remainingBooks = new ArrayList<>(books);
-
- for (final Integer newGroupBook : newGroupBooks) {
- //noinspection UseBulkOperation - we want to remove _one_ of each book number, not _all_ of each book number.
- remainingBooks.remove(newGroupBook);
- }
-
- double price = calculateTotalCost(remainingBooks, priceSoFar + costOfGroupSize(newGroupBooks.size()));
-
- minPrice = Math.min(minPrice, price);
- }
-
- return minPrice;
- }
-
- private double costOfGroupSize(int groupSize) {
- if (groupSize < 1 || groupSize > MAX_GROUP_SIZE) {
- throw new IllegalStateException("Invalid group size : " + groupSize);
- }
-
- return BOOK_PRICE * groupSize * (100 - DISCOUNT_TIERS[groupSize - 1]) / 100;
- }
-
- }
|