Skip to content

Commit 7c1a8ae

Browse files
authored
Add change (#377)
1 parent 019a60c commit 7c1a8ae

File tree

8 files changed

+200
-0
lines changed

8 files changed

+200
-0
lines changed

config.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -830,6 +830,14 @@
830830
"prerequisites": [],
831831
"difficulty": 5
832832
},
833+
{
834+
"slug": "change",
835+
"name": "Change",
836+
"uuid": "fff0dee7-06d5-4771-8e03-228475204db4",
837+
"practices": [],
838+
"prerequisites": [],
839+
"difficulty": 8
840+
},
833841
{
834842
"slug": "flower-field",
835843
"name": "Flower Field",
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Instructions
2+
3+
Determine the fewest number of coins to give a customer so that the sum of their values equals the correct amount of change.
4+
5+
## Examples
6+
7+
- An amount of 15 with available coin values [1, 5, 10, 25, 100] should return one coin of value 5 and one coin of value 10, or [5, 10].
8+
- An amount of 40 with available coin values [1, 5, 10, 25, 100] should return one coin of value 5, one coin of value 10, and one coin of value 25, or [5, 10, 25].
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Introduction
2+
3+
In the mystical village of Coinholt, you stand behind the counter of your bakery, arranging a fresh batch of pastries.
4+
The door creaks open, and in walks Denara, a skilled merchant with a keen eye for quality goods.
5+
After a quick meal, she slides a shimmering coin across the counter, representing a value of 100 units.
6+
7+
You smile, taking the coin, and glance at the total cost of the meal: 88 units.
8+
That means you need to return 12 units in change.
9+
10+
Denara holds out her hand expectantly.
11+
"Just give me the fewest coins," she says with a smile.
12+
"My pouch is already full, and I don't want to risk losing them on the road."
13+
14+
You know you have a few options.
15+
"We have Lumis (worth 10 units), Viras (worth 5 units), and Zenth (worth 2 units) available for change."
16+
17+
You quickly calculate the possibilities in your head:
18+
19+
- one Lumis (1 × 10 units) + one Zenth (1 × 2 units) = 2 coins total
20+
- two Viras (2 × 5 units) + one Zenth (1 × 2 units) = 3 coins total
21+
- six Zenth (6 × 2 units) = 6 coins total
22+
23+
"The best choice is two coins: one Lumis and one Zenth," you say, handing her the change.
24+
25+
Denara smiles, clearly impressed.
26+
"As always, you've got it right."
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"authors": [
3+
"BNAndras"
4+
],
5+
"files": {
6+
"solution": [
7+
"change.coffee"
8+
],
9+
"test": [
10+
"change.spec.coffee"
11+
],
12+
"example": [
13+
".meta/example.coffee"
14+
]
15+
},
16+
"blurb": "Correctly determine change to be given using the least number of coins.",
17+
"source": "Software Craftsmanship - Coin Change Kata",
18+
"source_url": "https://web.archive.org/web/20130115115225/http://craftsmanship.sv.cmu.edu:80/exercises/coin-change-kata"
19+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
class Change
2+
@findFewestCoins: (coins, targetBalance) ->
3+
throw new Error "target can't be negative" if targetBalance < 0
4+
5+
return [] if targetBalance is 0
6+
7+
availableCoins = coins.toSorted()
8+
queue = [0]
9+
visited = {0: []}
10+
11+
while queue.length > 0
12+
initialBalance = queue.shift()
13+
14+
for coin in availableCoins
15+
updatedBalance = initialBalance + coin
16+
continue if updatedBalance > targetBalance or visited[updatedBalance]
17+
18+
usedCoins = visited[initialBalance].concat coin
19+
if updatedBalance is targetBalance
20+
return usedCoins.toSorted (a, b) -> a - b
21+
22+
visited[updatedBalance] = usedCoins
23+
queue.push updatedBalance
24+
25+
throw new Error "can't make target with given coins"
26+
27+
module.exports = Change
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
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+
[d0ebd0e1-9d27-4609-a654-df5c0ba1d83a]
13+
description = "change for 1 cent"
14+
15+
[36887bea-7f92-4a9c-b0cc-c0e886b3ecc8]
16+
description = "single coin change"
17+
18+
[cef21ccc-0811-4e6e-af44-f011e7eab6c6]
19+
description = "multiple coin change"
20+
21+
[d60952bc-0c1a-4571-bf0c-41be72690cb3]
22+
description = "change with Lilliputian Coins"
23+
24+
[408390b9-fafa-4bb9-b608-ffe6036edb6c]
25+
description = "change with Lower Elbonia Coins"
26+
27+
[7421a4cb-1c48-4bf9-99c7-7f049689132f]
28+
description = "large target values"
29+
30+
[f79d2e9b-0ae3-4d6a-bb58-dc978b0dba28]
31+
description = "possible change without unit coins available"
32+
33+
[9a166411-d35d-4f7f-a007-6724ac266178]
34+
description = "another possible change without unit coins available"
35+
36+
[ce0f80d5-51c3-469d-818c-3e69dbd25f75]
37+
description = "a greedy approach is not optimal"
38+
39+
[bbbcc154-e9e9-4209-a4db-dd6d81ec26bb]
40+
description = "no coins make 0 change"
41+
42+
[c8b81d5a-49bd-4b61-af73-8ee5383a2ce1]
43+
description = "error testing for change smaller than the smallest of coins"
44+
45+
[3c43e3e4-63f9-46ac-9476-a67516e98f68]
46+
description = "error if no combination can add up to target"
47+
48+
[8fe1f076-9b2d-4f44-89fe-8a6ccd63c8f3]
49+
description = "cannot find negative change values"
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
class Change
2+
@findFewestCoins: (coins, target) ->
3+
4+
module.exports = Change
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
Change = require './change'
2+
3+
describe 'Change', =>
4+
it 'change for 1 cent', =>
5+
results = Change.findFewestCoins [1, 5, 10, 25], 1
6+
expect(results).toEqual [1]
7+
8+
xit 'single coin change', =>
9+
results = Change.findFewestCoins [1, 5, 10, 25, 100], 25
10+
expect(results).toEqual [25]
11+
12+
xit 'multiple coin change', =>
13+
results = Change.findFewestCoins [1, 5, 10, 25, 100], 15
14+
expect(results).toEqual [5, 10]
15+
16+
xit 'change with Lilliputian Coins', =>
17+
results = Change.findFewestCoins [1, 4, 15, 20, 50], 23
18+
expect(results).toEqual [4, 4, 15]
19+
20+
xit 'change with Lower Elbonia Coins', =>
21+
results = Change.findFewestCoins [1, 5, 10, 21, 25], 63
22+
expect(results).toEqual [21, 21, 21]
23+
24+
xit 'large target values', =>
25+
results = Change.findFewestCoins [1, 2, 5, 10, 20, 50, 100], 999
26+
expect(results).toEqual [
27+
2, 2, 5, 20, 20, 50, 100, 100, 100, 100, 100, 100, 100, 100, 100,
28+
]
29+
30+
xit 'possible change without unit coins available', =>
31+
results = Change.findFewestCoins [2, 5, 10, 20, 50], 21
32+
expect(results).toEqual [2, 2, 2, 5, 10]
33+
34+
xit 'another possible change without unit coins available', =>
35+
results = Change.findFewestCoins [4, 5], 27
36+
expect(results).toEqual [4, 4, 4, 5, 5, 5]
37+
38+
xit 'a greedy approach is not optimal', =>
39+
results = Change.findFewestCoins [1, 10, 11], 20
40+
expect(results).toEqual [10, 10]
41+
42+
xit 'no coins make 0 change', =>
43+
results = Change.findFewestCoins [1, 5, 10, 21, 25], 0
44+
expect(results).toEqual []
45+
46+
xit 'error testing for change smaller than the smallest of coins', =>
47+
expect ->
48+
Change.findFewestCoins [5, 10], 3
49+
.toThrow new Error "can't make target with given coins"
50+
51+
xit 'error testing if no combination can add up to target', =>
52+
expect ->
53+
Change.findFewestCoins [5, 10], 94
54+
.toThrow new Error "can't make target with given coins"
55+
56+
xit 'cannot find negative change values', =>
57+
expect ->
58+
Change.findFewestCoins [1, 2, 5], -5
59+
.toThrow new Error "target can't be negative"

0 commit comments

Comments
 (0)