3ドル.98: 15 quarters, 2 dimes, 3 pennies
3ドル.98: 1 two pound, 1 pound, 1 fifty pence, 2 twenty pences, 1 five pence, 1 two pence, 1 one pence
3ドル.98: 15 quarters, 2 dimes, 3 pennies
3ドル.98: 1 two pound, 1 pound, 1 fifty pence, 2 twenty pences, 1 five pence, 1 two pence, 1 one pence
3ドル.98: 15 quarters, 2 dimes, 3 pennies
3ドル.98: 1 two pound, 1 pound, 1 fifty pence, 2 twenty pences, 1 five pence, 1 two pence, 1 one pence
I chose to addTo record the number of coins of a particular face value, we'll need our CoinCount
class:
public class CoinCount
{
public CoinType Coin { get; set; }
public int Count { get; set; }
}
Then we have a BagOfCoins
helper class to keep track of a collection of coins, to allow future expansion of the facilities offered by that class. The constructor takes the amount of money and the list of coins and immediately stores the coins. Again, this allows forFor future expansion, the class constructors or methods can be expanded; e.g. a second constructor might also include knowledge of how many of each coin are available to use as change.
I chose to add a BagOfCoins
helper class to keep track of a collection of coins, to allow future expansion of the facilities offered by that class. The constructor takes the amount of money and the list of coins and immediately stores the coins. Again, this allows for future expansion, e.g. a second constructor might also include knowledge of how many of each coin are available to use as change.
To record the number of coins of a particular face value, we'll need our CoinCount
class:
public class CoinCount
{
public CoinType Coin { get; set; }
public int Count { get; set; }
}
Then we have a BagOfCoins
helper class to keep track of a collection of coins. The constructor takes the amount of money and the list of coins and immediately stores the coins. For future expansion, the class constructors or methods can be expanded; e.g. a second constructor might also include knowledge of how many of each coin are available to use as change.
- 161
- 3
CoinType
has private setters, since we copy references to these objects and do not want/expect them to change unexpectedly. It also copes with basic variants for pluralisation.
Initialisation of the coin denomination list is almost identical to Denis' codeFlater's answer.
The BagOfCoins
constructor checks the coin list to ensure it is ordered.
Edit: Rather than using OrderByDescending
, it is more efficient to Zip
the same list offset by one and compare sequential values, as explained in debug modethis answer . This has the added advantage of allowing us to reject lists of coins where two coins have the same face value.
if (!coinsAllowed.SequenceEqualZip(coinsAllowed.OrderByDescendingSkip(c1), (a, b) => cb.FaceValue < a.FaceValue).Contains(false))
{
throw new ArgumentException(
"The coinsAllowed parameter must be ordered in descending face value");
}
This wouldIt may be a sensible wayconsidered inefficient to go if all our unit tests are run against debug builds but we do not wantperform the overhead of checking everyordering check each time. An alternative would be to build a separate class CoinDemoninations
which has a constructor that takes the list and always throws an exception if the list is not in descending order. (Further checks such as test for equal values could also be made, if it is likely that users will be able to maintain the list of coin types themselves).
CoinType
has private setters, since we copy references to these objects and do not want/expect them to change unexpectedly. It also copes with basic variants for pluralisation.
Initialisation of the coin denomination list is almost identical to Denis' code.
The BagOfCoins
constructor checks the coin list to ensure it is ordered in debug mode.
if (!coinsAllowed.SequenceEqual(coinsAllowed.OrderByDescending(c => c.FaceValue)))
{
throw new ArgumentException(
"The coinsAllowed parameter must be ordered in descending face value");
}
This would be a sensible way to go if all our unit tests are run against debug builds but we do not want the overhead of checking every time. An alternative would be to build a separate class CoinDemoninations
which has a constructor that takes the list and always throws an exception if the list is not in descending order. (Further checks such as test for equal values could also be made, if it is likely that users will be able to maintain the list of coin types themselves).
CoinType
has private setters, since we copy references to these objects and do not want them to change unexpectedly. It also copes with basic variants for pluralisation.
Initialisation of the coin denomination list is almost identical to Flater's answer.
The BagOfCoins
constructor checks the coin list to ensure it is ordered.
Edit: Rather than using OrderByDescending
, it is more efficient to Zip
the same list offset by one and compare sequential values, as explained in this answer . This has the added advantage of allowing us to reject lists of coins where two coins have the same face value.
if (coinsAllowed.Zip(coinsAllowed.Skip(1), (a, b) => b.FaceValue < a.FaceValue).Contains(false))
{
throw new ArgumentException(
"The coinsAllowed parameter must be ordered in descending face value");
}
It may be considered inefficient to perform the ordering check each time. An alternative would be to build a separate class CoinDemoninations
which has a constructor that takes the list and always throws an exception if the list is not in descending order.
- 161
- 3