Skip to content

Commit 76330b5

Browse files
committed
Add pizza party exercise
Add the Pizza Party exercise as a standalone Gradle module with console I/O adapters and tests for the purchase planner and prompt flow. This gives the repository a runnable solution for exercise 8 while keeping input validation and output formatting covered by tests.
1 parent 00cb777 commit 76330b5

16 files changed

+646
-2
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,5 @@ build/
1111
out/
1212
!**/src/main/**/out/
1313
!**/src/test/**/out/
14+
15+
.DS_Store

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Exercises for Programmers: 57 Challenges to Develop Your Coding Skills by Brian
2020

2121
**Calculations**
2222
- Exercise 7. [Area of a Rectangular Room](https://github.com/durimkryeziu/exercises-for-programmers-java/tree/main/area-rectangular-room)
23-
- Exercise 8. Pizza Party
23+
- Exercise 8. [Pizza Party](https://github.com/durimkryeziu/exercises-for-programmers-java/tree/main/pizza-party)
2424
- Exercise 9. Paint Calculator
2525
- Exercise 10. Self-Checkout
2626
- Exercise 11. Currency Conversion

pizza-party/build.gradle

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
plugins {
2+
id 'dev.delivercraft.common-conventions'
3+
}
4+
5+
dependencies {
6+
testImplementation(libs.assertj.core)
7+
testImplementation(libs.junit.jupiter)
8+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package dev.delivercraft.pizza;
2+
3+
import java.io.BufferedReader;
4+
import java.io.IOException;
5+
import java.io.InputStream;
6+
import java.io.InputStreamReader;
7+
import java.io.UncheckedIOException;
8+
9+
final class InputStreamLineReader implements LineReader {
10+
11+
private final BufferedReader bufferedReader;
12+
13+
InputStreamLineReader(InputStream inputStream) {
14+
this.bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
15+
}
16+
17+
@Override
18+
public String readLine() {
19+
try {
20+
return this.bufferedReader.readLine();
21+
} catch (IOException e) {
22+
throw new UncheckedIOException(e);
23+
}
24+
}
25+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package dev.delivercraft.pizza;
2+
3+
public interface LineReader {
4+
5+
String readLine();
6+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package dev.delivercraft.pizza;
2+
3+
public interface LineWriter {
4+
5+
void write(String text);
6+
7+
void writeLine(String line);
8+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package dev.delivercraft.pizza;
2+
3+
public final class Main {
4+
5+
void main() {
6+
LineReader lineReader = new InputStreamLineReader(System.in);
7+
LineWriter lineWriter = new OutputStreamLineWriter(System.out);
8+
PizzaParty pizzaParty = new PizzaParty(lineReader, lineWriter);
9+
pizzaParty.displayPizzaParty();
10+
}
11+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package dev.delivercraft.pizza;
2+
3+
import java.io.OutputStream;
4+
import java.io.PrintWriter;
5+
6+
final class OutputStreamLineWriter implements LineWriter {
7+
8+
private final PrintWriter printWriter;
9+
10+
OutputStreamLineWriter(OutputStream outputStream) {
11+
this.printWriter = new PrintWriter(outputStream, true);
12+
}
13+
14+
@Override
15+
public void write(String text) {
16+
this.printWriter.print(text);
17+
this.printWriter.flush();
18+
}
19+
20+
@Override
21+
public void writeLine(String line) {
22+
this.printWriter.println(line);
23+
}
24+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package dev.delivercraft.pizza;
2+
3+
import java.util.Objects;
4+
5+
final class PizzaParty {
6+
7+
private final LineReader lineReader;
8+
9+
private final LineWriter lineWriter;
10+
11+
PizzaParty(LineReader lineReader, LineWriter lineWriter) {
12+
Objects.requireNonNull(lineReader, "lineReader must not be null");
13+
Objects.requireNonNull(lineWriter, "lineWriter must not be null");
14+
this.lineReader = lineReader;
15+
this.lineWriter = lineWriter;
16+
}
17+
18+
void displayPizzaParty() {
19+
int people = toPeopleCount(readRequiredInput("How many people? "));
20+
int pizzas = toNumber(readRequiredInput("How many pizzas do you have? "));
21+
int slicesPerPizza = toNumber(readRequiredInput("How many slices per pizza? "));
22+
23+
int totalSlices = pizzas * slicesPerPizza;
24+
int piecesPerPerson = totalSlices / people;
25+
int leftoverPieces = totalSlices % people;
26+
27+
this.lineWriter.writeLine("");
28+
this.lineWriter.writeLine("%d people with %d %s".formatted(people, pizzas,
29+
pluralize(pizzas, "pizza", "pizzas")));
30+
this.lineWriter.writeLine("Each person gets %d %s of pizza.".formatted(piecesPerPerson,
31+
pluralize(piecesPerPerson, "piece", "pieces")));
32+
this.lineWriter.writeLine("There %s %d %s.".formatted(verbForLeftover(leftoverPieces), leftoverPieces,
33+
pluralize(leftoverPieces, "leftover piece", "leftover pieces")));
34+
}
35+
36+
private String readRequiredInput(String prompt) {
37+
this.lineWriter.write(prompt);
38+
String input = this.lineReader.readLine();
39+
if (input == null || input.isBlank()) {
40+
throw new IllegalArgumentException("Input must not be empty!");
41+
}
42+
return input;
43+
}
44+
45+
private static int toPeopleCount(String value) {
46+
int people = toNumber(value);
47+
if (people == 0) {
48+
throw new IllegalArgumentException("Number of people must be greater than zero!");
49+
}
50+
return people;
51+
}
52+
53+
private static int toNumber(String value) {
54+
try {
55+
int number = Integer.parseInt(value);
56+
if (number < 0) {
57+
throw new IllegalArgumentException("Please enter a positive number! Input: %d".formatted(number));
58+
}
59+
return number;
60+
} catch (NumberFormatException e) {
61+
throw new IllegalArgumentException("Please enter a valid number! Input: %s".formatted(value), e);
62+
}
63+
}
64+
65+
private static String pluralize(int value, String singular, String plural) {
66+
return value == 1 ? singular : plural;
67+
}
68+
69+
private static String verbForLeftover(int leftoverPieces) {
70+
return leftoverPieces == 1 ? "is" : "are";
71+
}
72+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package dev.delivercraft.pizza;
2+
3+
import java.util.Objects;
4+
5+
final class PizzaPurchasePlanner {
6+
7+
private static final int SLICES_PER_PIZZA = 8;
8+
9+
private final LineReader lineReader;
10+
11+
private final LineWriter lineWriter;
12+
13+
PizzaPurchasePlanner(LineReader lineReader, LineWriter lineWriter) {
14+
Objects.requireNonNull(lineReader, "lineReader must not be null");
15+
Objects.requireNonNull(lineWriter, "lineWriter must not be null");
16+
this.lineReader = lineReader;
17+
this.lineWriter = lineWriter;
18+
}
19+
20+
void displayPizzaPurchasePlan() {
21+
int people = toPeopleCount(readRequiredInput("How many people? "));
22+
int piecesPerPerson = toNumber(readRequiredInput("How many pieces does each person want? "));
23+
24+
int requiredPieces = people * piecesPerPerson;
25+
int requiredPizzas = divideRoundingUp(requiredPieces, SLICES_PER_PIZZA);
26+
27+
this.lineWriter.writeLine("");
28+
this.lineWriter.writeLine("You will need to purchase %d %s.".formatted(
29+
requiredPizzas, pluralize(requiredPizzas, "pizza", "pizzas")));
30+
}
31+
32+
private String readRequiredInput(String prompt) {
33+
this.lineWriter.write(prompt);
34+
String input = this.lineReader.readLine();
35+
if (input == null || input.isBlank()) {
36+
throw new IllegalArgumentException("Input must not be empty!");
37+
}
38+
return input;
39+
}
40+
41+
private static int toPeopleCount(String value) {
42+
int people = toNumber(value);
43+
if (people == 0) {
44+
throw new IllegalArgumentException("Number of people must be greater than zero!");
45+
}
46+
return people;
47+
}
48+
49+
private static int toNumber(String value) {
50+
try {
51+
int number = Integer.parseInt(value);
52+
if (number < 0) {
53+
throw new IllegalArgumentException("Please enter a positive number! Input: %d".formatted(number));
54+
}
55+
return number;
56+
} catch (NumberFormatException e) {
57+
throw new IllegalArgumentException("Please enter a valid number! Input: %s".formatted(value), e);
58+
}
59+
}
60+
61+
private static int divideRoundingUp(int value, int divisor) {
62+
return (value + divisor - 1) / divisor;
63+
}
64+
65+
private static String pluralize(int value, String singular, String plural) {
66+
return value == 1 ? singular : plural;
67+
}
68+
}

0 commit comments

Comments
 (0)