Skip to content

Commit

Permalink
Sync change (exercism#862)
Browse files Browse the repository at this point in the history
  • Loading branch information
tomasnorre authored Nov 18, 2024
1 parent 23b0421 commit 9562ac8
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 56 deletions.
9 changes: 3 additions & 6 deletions exercises/practice/change/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -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

Expand Down
4 changes: 2 additions & 2 deletions exercises/practice/change/.meta/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
22 changes: 0 additions & 22 deletions exercises/practice/change/.meta/example.php
Original file line number Diff line number Diff line change
@@ -1,27 +1,5 @@
<?php

/*
* By adding type hints and enabling strict type checking, code can become
* easier to read, self-documenting and reduce the number of potential bugs.
* By default, type declarations are non-strict, which means they will attempt
* to change the original type to match the type specified by the
* type-declaration.
*
* In other words, if you pass a string to a function requiring a float,
* it will attempt to convert the string value to a float.
*
* To enable strict mode, a single declare directive must be placed at the top
* of the file.
* This means that the strictness of typing is configured on a per-file basis.
* This directive not only affects the type declarations of parameters, but also
* a function's return type.
*
* For more info review the Concept on strict type checking in the PHP track
* <link>.
*
* To disable strict typing, comment out the directive below.
*/

declare(strict_types=1);

// adapted from the python example
Expand Down
19 changes: 16 additions & 3 deletions exercises/practice/change/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -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"
Expand All @@ -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"

Expand Down
86 changes: 63 additions & 23 deletions exercises/practice/change/ChangeTest.php
Original file line number Diff line number Diff line change
@@ -1,27 +1,5 @@
<?php

/*
* By adding type hints and enabling strict type checking, code can become
* easier to read, self-documenting and reduce the number of potential bugs.
* By default, type declarations are non-strict, which means they will attempt
* to change the original type to match the type specified by the
* type-declaration.
*
* In other words, if you pass a string to a function requiring a float,
* it will attempt to convert the string value to a float.
*
* To enable strict mode, a single declare directive must be placed at the top
* of the file.
* This means that the strictness of typing is configured on a per-file basis.
* This directive not only affects the type declarations of parameters, but also
* a function's return type.
*
* For more info review the Concept on strict type checking in the PHP track
* <link>.
*
* To disable strict typing, comment out the directive below.
*/

declare(strict_types=1);

class ChangeTest extends PHPUnit\Framework\TestCase
Expand All @@ -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(
Expand All @@ -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(
Expand All @@ -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(
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand Down

0 comments on commit 9562ac8

Please sign in to comment.