 ## to Book Store in the Java Track

Published at Aug 18 2019 · 0 comments
Instructions
Test suite
Solution

To try and encourage more sales of different books from a popular 5 book series, a bookshop has decided to offer discounts on multiple book purchases.

One copy of any of the five books costs \$8.

If, however, you buy two different books, you get a 5% discount on those two books.

If you buy 3 different books, you get a 10% discount.

If you buy 4 different books, you get a 20% discount.

If you buy all 5, you get a 25% discount.

Note: that if you buy four books, of which 3 are different titles, you get a 10% discount on the 3 that form part of a set, but the fourth book still costs \$8.

Your mission is to write a piece of code to calculate the price of any conceivable shopping basket (containing only books of the same series), giving as big a discount as possible.

For example, how much does this basket of books cost?

• 2 copies of the first book
• 2 copies of the second book
• 2 copies of the third book
• 1 copy of the fourth book
• 1 copy of the fifth book

One way of grouping these 8 books is:

• 1 group of 5 --> 25% discount (1st,2nd,3rd,4th,5th)
• +1 group of 3 --> 10% discount (1st,2nd,3rd)

This would give a total of:

• 5 books at a 25% discount
• +3 books at a 10% discount

Resulting in:

• 5 x (8 - 2.00) == 5 x 6.00 == \$30.00
• +3 x (8 - 0.80) == 3 x 7.20 == \$21.60

For a total of \$51.60

However, a different way to group these 8 books is:

• 1 group of 4 books --> 20% discount (1st,2nd,3rd,4th)
• +1 group of 4 books --> 20% discount (1st,2nd,3rd,5th)

This would give a total of:

• 4 books at a 20% discount
• +4 books at a 20% discount

Resulting in:

• 4 x (8 - 1.60) == 4 x 6.40 == \$25.60
• +4 x (8 - 1.60) == 4 x 6.40 == \$25.60

For a total of \$51.20

And \$51.20 is the price with the biggest discount.

## Setup

Go through the setup instructions for Java to install the necessary dependencies:

https://exercism.io/tracks/java/installation

# Running the tests

You can run all the tests for an exercise by entering the following in your terminal:

``````\$ gradle test
``````

Use `gradlew.bat` if you're on Windows

In the test suites all tests but the first have been skipped.

Once you get a test passing, you can enable the next one by removing the `@Ignore("Remove to run test")` annotation.

## Source

Inspired by the harry potter kata from Cyber-Dojo. http://cyber-dojo.org

## Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

### BookStoreTest.java

``````import static org.junit.Assert.assertEquals;

import java.util.Collections;
import java.util.List;
import java.util.Arrays;

import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;

public class BookStoreTest {

// This is sufficient accuracy since we're handling currency values, which should be equal
// to within 2 decimal places.
private static final double EQUALITY_TOLERANCE = 0.001;

private BookStore bookStore;

@Before
public void setUp() {
bookStore = new BookStore();
}

@Test
public void onlyASingleBook() {
List<Integer> books = Collections.singletonList(1);
}

@Ignore("Remove to run test")
@Test
public void twoOfSameBook() {
List<Integer> books = Arrays.asList(2, 2);
}

@Ignore("Remove to run test")
@Test
List<Integer> books = Collections.emptyList();
}

@Ignore("Remove to run test")
@Test
public void twoDifferentBooks() {
List<Integer> books = Arrays.asList(1, 2);
}

@Ignore("Remove to run test")
@Test
public void threeDifferentBooks() {
List<Integer> books = Arrays.asList(1, 2, 3);
}

@Ignore("Remove to run test")
@Test
public void fourDifferentBooks() {
List<Integer> books = Arrays.asList(1, 2, 3, 4);
}

@Ignore("Remove to run test")
@Test
public void fiveDifferentBooks() {
List<Integer> books = Arrays.asList(1, 2, 3, 4, 5);
}

@Ignore("Remove to run test")
@Test
public void twoGroupsOfFourIsCheaperThanGroupOfFivePlusGroupOfThree() {
List<Integer> books = Arrays.asList(1, 1, 2, 2, 3, 3, 4, 5);
}

@Ignore("Remove to run test")
@Test
public void twoGroupsOfFourIsCheaperThanGroupsOfFiveAndThree() {
List<Integer> books = Arrays.asList(1, 1, 2, 3, 4, 4, 5, 5);
}

@Ignore("Remove to run test")
@Test
public void groupOfFourPlusGroupOfTwoIsCheaperThanTwoGroupsOfThree() {
List<Integer> books = Arrays.asList(1, 1, 2, 2, 3, 4);
}

@Ignore("Remove to run test")
@Test
public void twoEachOfFirst4BooksAnd1CopyEachOfRest() {
List<Integer> books = Arrays.asList(1, 1, 2, 2, 3, 3, 4, 4, 5);
}

@Ignore("Remove to run test")
@Test
public void twoCopiesOfEachBook() {
List<Integer> books = Arrays.asList(1, 1, 2, 2, 3, 3, 4, 4, 5, 5);
}

@Ignore("Remove to run test")
@Test
public void threeCopiesOfFirstBookAnd2EachOfRemaining() {
List<Integer> books = Arrays.asList(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 1);
}

@Ignore("Remove to run test")
@Test
public void threeEachOFirst2BooksAnd2EachOfRemainingBooks() {
List<Integer> books = Arrays.asList(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 1, 2);
}

@Ignore("Remove to run test")
@Test
public void fourGroupsOfFourAreCheaperThanTwoGroupsEachOfFiveAndThree() {
List<Integer> books = Arrays.asList(1, 1, 2, 2, 3, 3, 4, 5, 1, 1, 2, 2, 3, 3, 4, 5);
}
}``````

### src/test/java/Bookstore.java

``````// books will be instantiated into this class as objects
// calculations will be made in this class

import java.util.ArrayList;

class Bookstore {

// instance variables
String bookList;
String book1, book2, book3, book4, book5;

// int instance variable that counts the amount of books
// use this to fifure out which discount to give
int count,amount;

// constructor
Bookstore(String bookList) {
this.bookList = bookList;

}

// split the String book list into each seperate book
void eachBook(String myList) {
System.out.println(bookList);
String[] myBooks = bookList.split(", ");

// count amount of books here, then use that in the discount
// need to check if any books are the same
count = myBooks.length;

if (count!=5) {
System.exit(0);
}

// check what myBooks looks like after split
// to tell if any books are the same, create an if statement
// if myBook=myBook and so on, so forth
book1 = myBooks;
book2 = myBooks;
book3 = myBooks;
book4 = myBooks;
book5 = myBooks;

// check if any books are same here
if (book1.equals(book2)) {count=count-1;}
else if (book1.equals(book3)) {count=count-1;}
else if (book1.equals(book4)) {count=count-1;}
else if (book1.equals(book5)) {count=count-1;}

if (book2.equals(book3)) {count=count-1;}
else if (book2.equals(book4)) {count=count-1;}
else if (book2.equals(book5)) {count=count-1;}

if (book3.equals(book4)) {count=count-1;}
else if (book3.equals(book5)) {count=count-1;}

if (book4.equals(book5)) {count=count-1;}

amount=count;

}

// use this method to give discount
// use count the amount of books to decide on what discount to give
public double discount(double total) {

double sameBook=0;

if (amount>count) {
if (amount==count+1) {
sameBook=8;
count=count-1;
System.out.println("check");
}
else if (amount==count+2) {
sameBook=16;
count=count-2;
}
else if (amount==count+3) {
sameBook=24;
count=count-3;
}
else if (amount==count+4) {
sameBook=32;
count=count-4;
}

}

if (count == 1.0) {
total = 8 + sameBook;
}
else if (count == 2) {
total = 16 * .95 + sameBook;
}
else if (count == 3) {
total = 24 * .9 + sameBook;
}
else if (count == 4) {
total = 32 * .8 + sameBook;
}
else {
total = 40 * .75 + sameBook;
}

}

// need a toString method
public String toString() {
return bookList;
}

}``````

### src/test/java/main.java

``````// use this class to call the objects
import java.util.Scanner;

// program isn't complete but don't feel like working on it anymore

class main {

public static void main(String[] args) {

Scanner myScanner = new Scanner(System.in);

// while statement the user will
// contiue to add books to the list until they hit q or
// the list maxes out at 5 books
// write this program, then try to figure out how to give
// discount if books are not from the same series
// see instructions

System.out.println("What book would you like to purchase?");
String book = myScanner.next();
double count=0;

String allBooks = book + ", ";

// why does this not work, if nothing else could put a while
// statement withan another while statement
while (count!=5 && !book.equals("q")) {
System.out.println("What book would you like to purchase?");
book = myScanner.next();

// if statement to end while statement when q is entered
if (book.equals("q")) {
break;
}
allBooks = allBooks + book + ", ";
count=count+1;
}

Bookstore myBook = new Bookstore(allBooks);

myBook.eachBook(allBooks);

System.out.println(myBook.discount(count));

myScanner.close();

}

}``````