HiveBrain v1.2.0
Get Started
← Back to all entries
patternjavaMinor

Converting Java int-based amount to Coin metrics

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
coinamountjavametricsbasedconvertingint

Problem

I was tasked with writing a method which would take in an int (for amount in coins) and then convert the coins, accordingly, by counting how many quarters, dimes, nickels, and pennies were located in the amount. Afterwards, it would return a String which stated each count of individual coin.

```
public class Coins {

private static final int QUARTER_VALUE = 25;
private static final int DIME_VALUE = 10;
private static final int NICKEL_VALUE = 5;
private static final int PENNY_VALUE = 1;

public static String convert(int amount) {
int currentAmount = amount;
int quarters = 0;
int dimes = 0;
int nickels = 0;
int pennies = 0;

String quarterUnit = new String();
String dimeUnit = new String();
String nickelUnit = new String();
String pennyUnit = new String();

if (amount != 0) {
quarters = amount / QUARTER_VALUE;

currentAmount =
amount - (quarters * QUARTER_VALUE);

dimes = currentAmount / DIME_VALUE;

currentAmount =
amount - (quarters QUARTER_VALUE) - (dimes DIME_VALUE);

nickels = currentAmount / NICKEL_VALUE;

currentAmount =
amount - (quarters * QUARTER_VALUE)
- (dimes DIME_VALUE) - (nickels NICKEL_VALUE);

pennies = currentAmount / PENNY_VALUE;
}

if (quarters == 1) {
quarterUnit = " quarter";
}

else if (quarters > 1 || quarters == 0){
quarterUnit = " quarters";
}

if (dimes == 1) {
dimeUnit = " dime";
}

else if (dimes > 1 || dimes == 0) {
dimeUnit = " dimes";
}

if (nickels == 1) {
nickelUnit = " nickel";
}

else if (nickels > 1 || nickels == 0) {
nickelUnit = " nickels";
}

if (pennies == 1) {

Solution

Highlighting what a few helper classes can do :

Imagine this enum

private enum Coin {
    QUARTER(25, "quarter"), DIME(10, "dime"), NICKEL(5, "nickel"), PENNY(1, "penny", "pennies");
    ...


and a tuple of quotient and remainder :

private static class QuotientAndRemainder {
    private final int quotient;
    private final int remainder;


so the enum can sport this method :

public QuotientAndRemainder divide(int pennies) {
    return QuotientAndRemainder.quotient(pennies / pennyValue).withRemainder(pennies % pennyValue);
}


and this one :

public String format(int amount) {
    return Integer.toString(amount) + ' ' + (amount == 1 ? singular : multiple);
}


then the convert method simply becomes :

public static String convert(int amount) {
    return print(minimalChange(amount));
}

private static String print(Map amounts) {
    StringBuilder builder = new StringBuilder();
    for (Coin coin : amounts.keySet()) {
        builder.append(coin.format(amounts.get(coin))).append('\n');
    }
    return builder.toString();
}

private static Map minimalChange(int amount) {
    int penniesLeft = amount;
    Map amounts = new EnumMap(Coin.class);
    for (Coin coin : Coin.values()) {
        QuotientAndRemainder quotientAndRemainder = coin.divide(penniesLeft);
        amounts.put(coin, quotientAndRemainder.quotient());
        penniesLeft = quotientAndRemainder.remainder();
    }
    return amounts;
}


Adding larger units of currency now simply comes down to adding them to the enum.

Code Snippets

private enum Coin {
    QUARTER(25, "quarter"), DIME(10, "dime"), NICKEL(5, "nickel"), PENNY(1, "penny", "pennies");
    ...
private static class QuotientAndRemainder {
    private final int quotient;
    private final int remainder;
public QuotientAndRemainder divide(int pennies) {
    return QuotientAndRemainder.quotient(pennies / pennyValue).withRemainder(pennies % pennyValue);
}
public String format(int amount) {
    return Integer.toString(amount) + ' ' + (amount == 1 ? singular : multiple);
}
public static String convert(int amount) {
    return print(minimalChange(amount));
}

private static String print(Map<Coin, Integer> amounts) {
    StringBuilder builder = new StringBuilder();
    for (Coin coin : amounts.keySet()) {
        builder.append(coin.format(amounts.get(coin))).append('\n');
    }
    return builder.toString();
}

private static Map<Coin, Integer> minimalChange(int amount) {
    int penniesLeft = amount;
    Map<Coin, Integer> amounts = new EnumMap<Coin, Integer>(Coin.class);
    for (Coin coin : Coin.values()) {
        QuotientAndRemainder quotientAndRemainder = coin.divide(penniesLeft);
        amounts.put(coin, quotientAndRemainder.quotient());
        penniesLeft = quotientAndRemainder.remainder();
    }
    return amounts;
}

Context

StackExchange Code Review Q#31014, answer score: 5

Revisions (0)

No revisions yet.