diff --git a/exercises/practice/change/.docs/instructions.md b/exercises/practice/change/.docs/instructions.md
index 59f4f4f9..30fa5677 100644
--- a/exercises/practice/change/.docs/instructions.md
+++ b/exercises/practice/change/.docs/instructions.md
@@ -1,14 +1,11 @@
# Instructions
-Correctly determine the fewest number of coins to be given to a customer such
-that the sum of the coins' value would equal the correct amount of change.
+Correctly determine the fewest number of coins to be given to a customer such that the sum of the coins' value would equal the correct amount of change.
## For example
-- An input of 15 with [1, 5, 10, 25, 100] should return one nickel (5)
- and one dime (10) or [5, 10]
-- An input of 40 with [1, 5, 10, 25, 100] should return one nickel (5)
- and one dime (10) and one quarter (25) or [5, 10, 25]
+- An input of 15 with [1, 5, 10, 25, 100] should return one nickel (5) and one dime (10) or [5, 10]
+- An input of 40 with [1, 5, 10, 25, 100] should return one nickel (5) and one dime (10) and one quarter (25) or [5, 10, 25]
## Edge cases
diff --git a/exercises/practice/change/.meta/config.json b/exercises/practice/change/.meta/config.json
index db3dcc03..9ef16d9f 100644
--- a/exercises/practice/change/.meta/config.json
+++ b/exercises/practice/change/.meta/config.json
@@ -21,7 +21,7 @@
".meta/example.php"
]
},
- "blurb": "Correctly determine change to be given using the least number of coins",
+ "blurb": "Correctly determine change to be given using the least number of coins.",
"source": "Software Craftsmanship - Coin Change Kata",
- "source_url": "https://web.archive.org/web/20130115115225/https://craftsmanship.sv.cmu.edu:80/exercises/coin-change-kata"
+ "source_url": "https://web.archive.org/web/20130115115225/http://craftsmanship.sv.cmu.edu:80/exercises/coin-change-kata"
}
diff --git a/exercises/practice/change/.meta/example.php b/exercises/practice/change/.meta/example.php
index b8af1ce6..35cdcce4 100644
--- a/exercises/practice/change/.meta/example.php
+++ b/exercises/practice/change/.meta/example.php
@@ -1,27 +1,5 @@
.
- *
- * To disable strict typing, comment out the directive below.
- */
-
declare(strict_types=1);
// adapted from the python example
diff --git a/exercises/practice/change/.meta/tests.toml b/exercises/practice/change/.meta/tests.toml
index 6d36d3c7..2d2f44bc 100644
--- a/exercises/practice/change/.meta/tests.toml
+++ b/exercises/practice/change/.meta/tests.toml
@@ -1,6 +1,16 @@
-# This is an auto-generated file. Regular comments will be removed when this
-# file is regenerated. Regenerating will not touch any manually added keys,
-# so comments can be added in a "comment" key.
+# This is an auto-generated file.
+#
+# Regenerating this file via `configlet sync` will:
+# - Recreate every `description` key/value pair
+# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
+# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
+# - Preserve any other key/value pair
+#
+# As user-added comments (using the # character) will be removed when this file
+# is regenerated, comments can be added via a `comment` key.
+
+[d0ebd0e1-9d27-4609-a654-df5c0ba1d83a]
+description = "change for 1 cent"
[36887bea-7f92-4a9c-b0cc-c0e886b3ecc8]
description = "single coin change"
@@ -23,6 +33,9 @@ description = "possible change without unit coins available"
[9a166411-d35d-4f7f-a007-6724ac266178]
description = "another possible change without unit coins available"
+[ce0f80d5-51c3-469d-818c-3e69dbd25f75]
+description = "a greedy approach is not optimal"
+
[bbbcc154-e9e9-4209-a4db-dd6d81ec26bb]
description = "no coins make 0 change"
diff --git a/exercises/practice/change/ChangeTest.php b/exercises/practice/change/ChangeTest.php
index 6746da6e..ce13ee83 100644
--- a/exercises/practice/change/ChangeTest.php
+++ b/exercises/practice/change/ChangeTest.php
@@ -1,27 +1,5 @@
.
- *
- * To disable strict typing, comment out the directive below.
- */
-
declare(strict_types=1);
class ChangeTest extends PHPUnit\Framework\TestCase
@@ -31,26 +9,55 @@ public static function setUpBeforeClass(): void
require_once 'Change.php';
}
+ /**
+ * uuid d0ebd0e1-9d27-4609-a654-df5c0ba1d83a
+ * @testdox change for 1 cent
+ */
+ public function testChangeForOneCent(): void
+ {
+ $this->assertEquals([1], findFewestCoins([1, 5, 10, 25], 1));
+ }
+
+ /**
+ * uuid 36887bea-7f92-4a9c-b0cc-c0e886b3ecc8
+ * @testdox single coin change
+ */
public function testSingleCoinChange(): void
{
$this->assertEquals([25], findFewestCoins([1, 5, 10, 25, 100], 25));
}
- public function testChange(): void
+ /**
+ * uuid cef21ccc-0811-4e6e-af44-f011e7eab6c6
+ * @testdox multiple coin change
+ */
+ public function testMultipleCoinChange(): void
{
$this->assertEquals([5, 10], findFewestCoins([1, 5, 10, 25, 100], 15));
}
+ /**
+ * uuid d60952bc-0c1a-4571-bf0c-41be72690cb3
+ * @testdox change with Lilliputian Coins
+ */
public function testChangeWithLilliputianCoins(): void
{
$this->assertEquals([4, 4, 15], findFewestCoins([1, 4, 15, 20, 50], 23));
}
+ /**
+ * uuid 408390b9-fafa-4bb9-b608-ffe6036edb6c
+ * @testdox change with Lower Elbonia Coins
+ */
public function testChangeWithLowerElboniaCoins(): void
{
$this->assertEquals([21, 21, 21], findFewestCoins([1, 5, 10, 21, 25], 63));
}
+ /**
+ * uuid 7421a4cb-1c48-4bf9-99c7-7f049689132f
+ * @testdox large target values
+ */
public function testWithLargeTargetValue(): void
{
$this->assertEquals(
@@ -59,6 +66,10 @@ public function testWithLargeTargetValue(): void
);
}
+ /**
+ * uuid f79d2e9b-0ae3-4d6a-bb58-dc978b0dba28
+ * @testdox possible change without unit coins available
+ */
public function testPossibleChangeWithoutUnitCoinsAvailable(): void
{
$this->assertEquals(
@@ -67,6 +78,10 @@ public function testPossibleChangeWithoutUnitCoinsAvailable(): void
);
}
+ /**
+ * uuid 9a166411-d35d-4f7f-a007-6724ac266178
+ * @testdox another possible change without unit coins available
+ */
public function testAnotherPossibleChangeWithoutUnitCoinsAvailable(): void
{
$this->assertEquals(
@@ -75,11 +90,28 @@ public function testAnotherPossibleChangeWithoutUnitCoinsAvailable(): void
);
}
+ /**
+ * uuid ce0f80d5-51c3-469d-818c-3e69dbd25f75
+ * @testdox a greedy approach is not optimal
+ */
+ public function testAGreedyApproachIsNotOptimal(): void
+ {
+ $this->assertEquals([10, 10], findFewestCoins([1, 10, 11], 20));
+ }
+
+ /**
+ * uuid bbbcc154-e9e9-4209-a4db-dd6d81ec26bb
+ * @testdox no coins make 0 change
+ */
public function testNoCoinsForZero(): void
{
$this->assertEquals([], findFewestCoins([1, 5, 10, 21, 25], 0));
}
+ /**
+ * uuid c8b81d5a-49bd-4b61-af73-8ee5383a2ce1
+ * @testdox error testing for change smaller than the smallest of coins
+ */
public function testForChangeSmallerThanAvailableCoins(): void
{
$this->expectException(InvalidArgumentException::class);
@@ -88,6 +120,10 @@ public function testForChangeSmallerThanAvailableCoins(): void
findFewestCoins([5, 10], 3);
}
+ /**
+ * uuid 3c43e3e4-63f9-46ac-9476-a67516e98f68
+ * @testdox error if no combination can add up to target
+ */
public function testErrorIfNoCombinationCanAddUpToTarget(): void
{
$this->expectException(InvalidArgumentException::class);
@@ -96,6 +132,10 @@ public function testErrorIfNoCombinationCanAddUpToTarget(): void
findFewestCoins([5, 10], 94);
}
+ /**
+ * uuid 8fe1f076-9b2d-4f44-89fe-8a6ccd63c8f3
+ * @testdox cannot find negative change values
+ */
public function testChangeValueLessThanZero(): void
{
$this->expectException(InvalidArgumentException::class);