Skip to content

Commit 0af034f

Browse files
authored
Sync book-store (#850)
1 parent cb9d5b1 commit 0af034f

File tree

5 files changed

+193
-115
lines changed

5 files changed

+193
-115
lines changed
Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,20 @@
11
# Instructions
22

3-
To try and encourage more sales of different books from a popular 5 book
4-
series, a bookshop has decided to offer discounts on multiple book purchases.
3+
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.
54

65
One copy of any of the five books costs $8.
76

8-
If, however, you buy two different books, you get a 5%
9-
discount on those two books.
7+
If, however, you buy two different books, you get a 5% discount on those two books.
108

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

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

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

17-
Note: that if you buy four books, of which 3 are
18-
different titles, you get a 10% discount on the 3 that
19-
form part of a set, but the fourth book still costs $8.
15+
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.
2016

21-
Your mission is to write a piece of code to calculate the
22-
price of any conceivable shopping basket (containing only
23-
books of the same series), giving as big a discount as
24-
possible.
17+
Your mission is to write code to calculate the price of any conceivable shopping basket (containing only books of the same series), giving as big a discount as possible.
2518

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

@@ -33,36 +26,36 @@ For example, how much does this basket of books cost?
3326

3427
One way of grouping these 8 books is:
3528

36-
- 1 group of 5 --> 25% discount (1st,2nd,3rd,4th,5th)
37-
- +1 group of 3 --> 10% discount (1st,2nd,3rd)
29+
- 1 group of 5 (1st, 2nd,3rd, 4th, 5th)
30+
- 1 group of 3 (1st, 2nd, 3rd)
3831

3932
This would give a total of:
4033

4134
- 5 books at a 25% discount
42-
- +3 books at a 10% discount
35+
- 3 books at a 10% discount
4336

4437
Resulting in:
4538

46-
- 5 x (8 - 2.00) == 5 x 6.00 == $30.00
47-
- +3 x (8 - 0.80) == 3 x 7.20 == $21.60
39+
- 5 × (100% - 25%) × $8 = 5 × $6.00 = $30.00, plus
40+
- 3 × (100% - 10%) × $8 = 3 × $7.20 = $21.60
4841

49-
For a total of $51.60
42+
Which equals $51.60.
5043

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

53-
- 1 group of 4 books --> 20% discount (1st,2nd,3rd,4th)
54-
- +1 group of 4 books --> 20% discount (1st,2nd,3rd,5th)
46+
- 1 group of 4 books (1st, 2nd, 3rd, 4th)
47+
- 1 group of 4 books (1st, 2nd, 3rd, 5th)
5548

5649
This would give a total of:
5750

5851
- 4 books at a 20% discount
59-
- +4 books at a 20% discount
52+
- 4 books at a 20% discount
6053

6154
Resulting in:
6255

63-
- 4 x (8 - 1.60) == 4 x 6.40 == $25.60
64-
- +4 x (8 - 1.60) == 4 x 6.40 == $25.60
56+
- 4 × (100% - 20%) × $8 = 4 × $6.40 = $25.60, plus
57+
- 4 × (100% - 20%) × $8 = 4 × $6.40 = $25.60
6558

66-
For a total of $51.20
59+
Which equals $51.20.
6760

6861
And $51.20 is the price with the biggest discount.
Lines changed: 31 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,42 @@
11
<?php
22

3-
/*
4-
* By adding type hints and enabling strict type checking, code can become
5-
* easier to read, self-documenting and reduce the number of potential bugs.
6-
* By default, type declarations are non-strict, which means they will attempt
7-
* to change the original type to match the type specified by the
8-
* type-declaration.
9-
*
10-
* In other words, if you pass a string to a function requiring a float,
11-
* it will attempt to convert the string value to a float.
12-
*
13-
* To enable strict mode, a single declare directive must be placed at the top
14-
* of the file.
15-
* This means that the strictness of typing is configured on a per-file basis.
16-
* This directive not only affects the type declarations of parameters, but also
17-
* a function's return type.
18-
*
19-
* For more info review the Concept on strict type checking in the PHP track
20-
* <link>.
21-
*
22-
* To disable strict typing, comment out the directive below.
23-
*/
24-
25-
declare(strict_types=1);
26-
27-
function total($items)
3+
function total(array $items): int
284
{
29-
return calculate($items, 0);
30-
}
5+
$groups = array_fill(1, 5, 0); // Groups of books
6+
$sets = array_fill(1, 5, 0); // Sets by size
317

32-
function calculate($items, $total)
33-
{
34-
if (empty($items)) {
35-
return $total;
8+
// Group the basket
9+
foreach ($items as $bookId) {
10+
$groups[$bookId]++;
3611
}
3712

38-
$group = array_unique($items);
39-
$totalMin = INF;
40-
41-
for ($i = count($group); $i > 0; $i--) {
42-
$itemsToRemove = array_flip(array_slice($group, 0, $i));
43-
$itemsRemaining = array_filter($items, function ($x) use (&$itemsToRemove) {
44-
if (array_key_exists($x, $itemsToRemove)) {
45-
unset($itemsToRemove[$x]);
46-
return false;
13+
// Arrange groups into counts by set size
14+
while (array_sum($groups) > 0) {
15+
$setSize = 0;
16+
foreach ($groups as $key => $count) {
17+
if ($count > 0) {
18+
$setSize++;
19+
$groups[$key]--;
4720
}
48-
return true;
49-
});
50-
$totalCurrent = calculate($itemsRemaining, $total + totalForGroup($i));
51-
$totalMin = min([$totalMin, $totalCurrent]);
21+
}
22+
if ($setSize > 0) {
23+
$sets[$setSize]++;
24+
}
5225
}
5326

54-
return $totalMin;
55-
}
27+
// Replace each 3set+5set with two 4sets
28+
while ($sets[3] > 0 && $sets[5] > 0) {
29+
$sets[3]--;
30+
$sets[5]--;
31+
$sets[4] += 2;
32+
}
5633

57-
function totalForGroup($count)
58-
{
59-
$discount = [0, 0, 0.05, 0.1, 0.2, 0.25];
60-
$price = 8;
61-
return $price * $count * (1 - $discount[$count]);
34+
// Calculate the total cost
35+
$cost = 800 * $sets[1] +
36+
(800 * 2 * 0.95) * $sets[2] +
37+
(800 * 3 * 0.9) * $sets[3] +
38+
(800 * 4 * 0.8) * $sets[4] +
39+
(800 * 5 * 0.75) * $sets[5];
40+
41+
return (int)$cost;
6242
}

exercises/practice/book-store/.meta/tests.toml

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
1-
# This is an auto-generated file. Regular comments will be removed when this
2-
# file is regenerated. Regenerating will not touch any manually added keys,
3-
# so comments can be added in a "comment" key.
1+
# This is an auto-generated file.
2+
#
3+
# Regenerating this file via `configlet sync` will:
4+
# - Recreate every `description` key/value pair
5+
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
6+
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
7+
# - Preserve any other key/value pair
8+
#
9+
# As user-added comments (using the # character) will be removed when this file
10+
# is regenerated, comments can be added via a `comment` key.
411

512
[17146bd5-2e80-4557-ab4c-05632b6b0d01]
613
description = "Only a single book"
@@ -33,16 +40,25 @@ description = "Two groups of four is cheaper than groups of five and three"
3340
description = "Group of four plus group of two is cheaper than two groups of three"
3441

3542
[68ea9b78-10ad-420e-a766-836a501d3633]
36-
description = "Two each of first 4 books and 1 copy each of rest"
43+
description = "Two each of first four books and one copy each of rest"
3744

3845
[c0a779d5-a40c-47ae-9828-a340e936b866]
3946
description = "Two copies of each book"
4047

4148
[18fd86fe-08f1-4b68-969b-392b8af20513]
42-
description = "Three copies of first book and 2 each of remaining"
49+
description = "Three copies of first book and two each of remaining"
4350

4451
[0b19a24d-e4cf-4ec8-9db2-8899a41af0da]
45-
description = "Three each of first 2 books and 2 each of remaining books"
52+
description = "Three each of first two books and two each of remaining books"
4653

4754
[bb376344-4fb2-49ab-ab85-e38d8354a58d]
4855
description = "Four groups of four are cheaper than two groups each of five and three"
56+
57+
[5260ddde-2703-4915-b45a-e54dbbac4303]
58+
description = "Check that groups of four are created properly even when there are more groups of three than groups of five"
59+
60+
[b0478278-c551-4747-b0fc-7e0be3158b1f]
61+
description = "One group of one and four is cheaper than one group of two and three"
62+
63+
[cf868453-6484-4ae1-9dfc-f8ee85bbde01]
64+
description = "One group of one and two plus three groups of four is cheaper than one group of each size"

exercises/practice/book-store/BookStore.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@
2424

2525
declare(strict_types=1);
2626

27-
function total(array $items): float
27+
/**
28+
* Note: we expect the total in cents (1$ = 100 cents).
29+
*/
30+
function total(array $items): int
2831
{
2932
throw new \BadFunctionCallException("Implement the total function");
3033
}

0 commit comments

Comments
 (0)