Skip to content

Commit 3583423

Browse files
Add book-store exercise (#52)
1 parent 84472e8 commit 3583423

File tree

7 files changed

+295
-0
lines changed

7 files changed

+295
-0
lines changed

config.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,14 @@
366366
"prerequisites": [],
367367
"difficulty": 6
368368
},
369+
{
370+
"slug": "book-store",
371+
"name": "Book Store",
372+
"uuid": "c9333f25-a92f-4f47-bf5f-f5543fc028b3",
373+
"practices": [],
374+
"prerequisites": [],
375+
"difficulty": 7
376+
},
369377
{
370378
"slug": "change",
371379
"name": "Change",
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Instructions
2+
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.
4+
5+
One copy of any of the five books costs $8.
6+
7+
If, however, you buy two different books, you get a 5% discount on those two books.
8+
9+
If you buy 3 different books, you get a 10% discount.
10+
11+
If you buy 4 different books, you get a 20% discount.
12+
13+
If you buy all 5, you get a 25% discount.
14+
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.
16+
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.
18+
19+
For example, how much does this basket of books cost?
20+
21+
- 2 copies of the first book
22+
- 2 copies of the second book
23+
- 2 copies of the third book
24+
- 1 copy of the fourth book
25+
- 1 copy of the fifth book
26+
27+
One way of grouping these 8 books is:
28+
29+
- 1 group of 5 (1st, 2nd,3rd, 4th, 5th)
30+
- 1 group of 3 (1st, 2nd, 3rd)
31+
32+
This would give a total of:
33+
34+
- 5 books at a 25% discount
35+
- 3 books at a 10% discount
36+
37+
Resulting in:
38+
39+
- 5 × (100% - 25%) × $8 = 5 × $6.00 = $30.00, plus
40+
- 3 × (100% - 10%) × $8 = 3 × $7.20 = $21.60
41+
42+
Which equals $51.60.
43+
44+
However, a different way to group these 8 books is:
45+
46+
- 1 group of 4 books (1st, 2nd, 3rd, 4th)
47+
- 1 group of 4 books (1st, 2nd, 3rd, 5th)
48+
49+
This would give a total of:
50+
51+
- 4 books at a 20% discount
52+
- 4 books at a 20% discount
53+
54+
Resulting in:
55+
56+
- 4 × (100% - 20%) × $8 = 4 × $6.40 = $25.60, plus
57+
- 4 × (100% - 20%) × $8 = 4 × $6.40 = $25.60
58+
59+
Which equals $51.20.
60+
61+
And $51.20 is the price with the biggest discount.
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"authors": [
3+
"keiravillekode"
4+
],
5+
"files": {
6+
"solution": [
7+
"book_store.fut"
8+
],
9+
"test": [
10+
"test.fut"
11+
],
12+
"example": [
13+
".meta/example.fut"
14+
]
15+
},
16+
"blurb": "To try and encourage more sales of different books from a popular 5 book series, a bookshop has decided to offer discounts of multiple-book purchases.",
17+
"source": "Inspired by the harry potter kata from Cyber-Dojo.",
18+
"source_url": "https://cyber-dojo.org"
19+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
def tally (basket: []i32): []i32 =
2+
let array = loop array = replicate 6 0 for book in basket do
3+
array with [book] = array[book] + 1
4+
in
5+
array
6+
7+
def sort [n] (array: [n]i32): []i32 =
8+
let a = loop a = copy array for i in 1..<n do
9+
let ai = a[i]
10+
let (a2, j) = loop (a2, j) = (a, i) while j > 0 && a2[j - 1] > ai do
11+
(a2 with [j] = a2[j - 1], j - 1)
12+
in
13+
a2 with [j] = ai
14+
in
15+
a
16+
17+
def difference [n] (a: [n]i32): []i32 =
18+
let d = loop d = replicate 6 a[5] for i in 1..<6 do
19+
d with [6 - i] = a[i] - a[i - 1]
20+
in
21+
d
22+
23+
def adjust [n] (d: [n]i32): []i32 =
24+
let one = d[1]
25+
let two = d[2]
26+
let three = d[3]
27+
let four = d[4]
28+
let five = d[5]
29+
let adjustment = i32.min three five
30+
in
31+
[0, one, two, three - adjustment, four + 2 * adjustment, five - adjustment]
32+
33+
def price [n] (c: [n]i32): i32 =
34+
let one = c[1]
35+
let two = c[2]
36+
let three = c[3]
37+
let four = c[4]
38+
let five = c[5]
39+
in
40+
800 * one + 1520 * two + 2160 * three + 2560 * four + 3000 * five
41+
42+
def total (basket: []i32): i32 =
43+
basket
44+
|> tally
45+
|> sort
46+
|> difference
47+
|> adjust
48+
|> price
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
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.
11+
12+
[17146bd5-2e80-4557-ab4c-05632b6b0d01]
13+
description = "Only a single book"
14+
15+
[cc2de9ac-ff2a-4efd-b7c7-bfe0f43271ce]
16+
description = "Two of the same book"
17+
18+
[5a86eac0-45d2-46aa-bbf0-266b94393a1a]
19+
description = "Empty basket"
20+
21+
[158bd19a-3db4-4468-ae85-e0638a688990]
22+
description = "Two different books"
23+
24+
[f3833f6b-9332-4a1f-ad98-6c3f8e30e163]
25+
description = "Three different books"
26+
27+
[1951a1db-2fb6-4cd1-a69a-f691b6dd30a2]
28+
description = "Four different books"
29+
30+
[d70f6682-3019-4c3f-aede-83c6a8c647a3]
31+
description = "Five different books"
32+
33+
[78cacb57-911a-45f1-be52-2a5bd428c634]
34+
description = "Two groups of four is cheaper than group of five plus group of three"
35+
36+
[f808b5a4-e01f-4c0d-881f-f7b90d9739da]
37+
description = "Two groups of four is cheaper than groups of five and three"
38+
39+
[fe96401c-5268-4be2-9d9e-19b76478007c]
40+
description = "Group of four plus group of two is cheaper than two groups of three"
41+
42+
[68ea9b78-10ad-420e-a766-836a501d3633]
43+
description = "Two each of first four books and one copy each of rest"
44+
45+
[c0a779d5-a40c-47ae-9828-a340e936b866]
46+
description = "Two copies of each book"
47+
48+
[18fd86fe-08f1-4b68-969b-392b8af20513]
49+
description = "Three copies of first book and two each of remaining"
50+
51+
[0b19a24d-e4cf-4ec8-9db2-8899a41af0da]
52+
description = "Three each of first two books and two each of remaining books"
53+
54+
[bb376344-4fb2-49ab-ab85-e38d8354a58d]
55+
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"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
def total (basket: []i32): i32 = ???
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import "book_store"
2+
3+
-- Only a single book
4+
-- ==
5+
-- input { [1] }
6+
-- output { 800 }
7+
8+
-- Two of the same book
9+
-- ==
10+
-- input { [2, 2] }
11+
-- output { 1600 }
12+
13+
-- Empty basket
14+
-- ==
15+
-- input { empty([0]i32) }
16+
-- output { 0 }
17+
18+
-- Two different books
19+
-- ==
20+
-- input { [1, 2] }
21+
-- output { 1520 }
22+
23+
-- Three different books
24+
-- ==
25+
-- input { [1, 2, 3] }
26+
-- output { 2160 }
27+
28+
-- Four different books
29+
-- ==
30+
-- input { [1, 2, 3, 4] }
31+
-- output { 2560 }
32+
33+
-- Five different books
34+
-- ==
35+
-- input { [1, 2, 3, 4, 5] }
36+
-- output { 3000 }
37+
38+
-- Two groups of four is cheaper than group of five plus group of three
39+
-- ==
40+
-- input { [1, 1, 2, 2, 3, 3, 4, 5] }
41+
-- output { 5120 }
42+
43+
-- Two groups of four is cheaper than groups of five and three
44+
-- ==
45+
-- input { [1, 1, 2, 3, 4, 4, 5, 5] }
46+
-- output { 5120 }
47+
48+
-- Group of four plus group of two is cheaper than two groups of three
49+
-- ==
50+
-- input { [1, 1, 2, 2, 3, 4] }
51+
-- output { 4080 }
52+
53+
-- Two each of first four books and one copy each of rest
54+
-- ==
55+
-- input { [1, 1, 2, 2, 3, 3, 4, 4, 5] }
56+
-- output { 5560 }
57+
58+
-- Two copies of each book
59+
-- ==
60+
-- input { [1, 1, 2, 2, 3, 3, 4, 4, 5, 5] }
61+
-- output { 6000 }
62+
63+
-- Three copies of first book and two each of remaining
64+
-- ==
65+
-- input { [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 1] }
66+
-- output { 6800 }
67+
68+
-- Three each of first two books and two each of remaining books
69+
-- ==
70+
-- input { [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 1, 2] }
71+
-- output { 7520 }
72+
73+
-- Four groups of four are cheaper than two groups each of five and three
74+
-- ==
75+
-- input { [1, 1, 2, 2, 3, 3, 4, 5, 1, 1, 2, 2, 3, 3, 4, 5] }
76+
-- output { 10240 }
77+
78+
-- Check that groups of four are created properly even when there are more groups of three than groups of five
79+
-- ==
80+
-- input { [1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 5, 5] }
81+
-- output { 14560 }
82+
83+
-- One group of one and four is cheaper than one group of two and three
84+
-- ==
85+
-- input { [1, 1, 2, 3, 4] }
86+
-- output { 3360 }
87+
88+
-- One group of one and two plus three groups of four is cheaper than one group of each size
89+
-- ==
90+
-- input { [1, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 5] }
91+
-- output { 10000 }
92+
93+
let main (basket: []i32): i32 =
94+
total basket

0 commit comments

Comments
 (0)