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);