-2

This is one of my first attempts to use Java and I tried my best, but I need to shorten it so it's not so long.

Important is that it keeps all the coins of the Euro. It's a German code so geld means money.

This part of the code System.out.println(rgeldt + " mal 2 Euro"); just means how often the 2 euros have to be ejected.

public static void Rueckgaberechner(Double geld) {
    System.out.println("Rueckgeld: ");
    int rgeldt = 0;
    while (geld >= 200) {
        geld = geld - 200;
        rgeldt = rgeldt + 1;
    }
    if (rgeldt >= 1) {
        System.out.println(rgeldt + " mal 2 Euro");
    }
    int rgeldO = 0;
    while (geld >= 100) {
        geld = geld - 100;
        rgeldO = rgeldO + 1;
    }
    if (rgeldO >= 1) {
        System.out.println(rgeldO + " mal 1 Euro");
    }
    int rgeldf = 0;
    while (geld >= 50) {
        geld = geld - 50;
        rgeldf = rgeldf + 1;
    }
    if (rgeldf >= 1) {
        System.out.println(rgeldf + " mal 50 Cent");
    }
    int rgeldtw = 0;
    while (geld >= 20) {
        geld = geld - 20;
        rgeldtw = rgeldtw + 1;
    }
    if (rgeldtw >= 1) {
        System.out.println(rgeldtw + " mal 20 Cent");
    }
    int rgeldten = 0;
    while (geld >= 10) {
        geld = geld - 10;
        rgeldten = rgeldten + 1;
    }
    if (rgeldten >= 1) {
        System.out.println(rgeldten + " mal 10 Cent");
    }
    int rgeldfive = 0;
    while (geld >= 5) {
        geld = geld - 5;
        rgeldfive = rgeldfive + 1;
    }
    if (rgeldfive >= 1) {
        System.out.println(rgeldfive + " mal 5 Cent");
    }
    int rgeldtwo = 0;
    while (geld >= 2) {
        geld = geld - 2;
        rgeldtwo = rgeldtwo + 1;
    }
    if (rgeldtwo >= 1) {
        System.out.println(rgeldtwo + " mal 2 Cent");
    }
    int rgeldone = 0;
    while (geld >= 1) {
        geld = geld - 1;
        rgeldone = rgeldone + 1;
    }
    if (rgeldone >= 1) {
        System.out.println(rgeldone + " mal 1 Cent");
    }
}
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
Kanukl
  • 3
  • 2
  • 3
    Questions about optimizing running code is better asked at [codereview.SE] – Jens Nov 03 '22 at 11:48
  • Replace the `while` loops with two simple `/` and `%` operations, then extract each return money calculation to one single method. (Oh, and you don't need `double` if your calculations are in cents and simple (which is the case here)). – steffen Nov 03 '22 at 11:54
  • Note that you should probably not use a Double or any other floating point format to represent money. See [Why not use Double or Float to represent currency?](https://stackoverflow.com/questions/3730019/why-not-use-double-or-float-to-represent-currency) – 3limin4t0r Nov 03 '22 at 13:47

4 Answers4

1

Assuming I've understood correctly and geld is number of cents and the goal is to output the change in as few coins as possible, you can do this without any loops by using division and modulo, e.g. to get the number of 2 euro coins in geld you can do

    int numberOf2Euros = (int) (geld / 200);
    geld = geld % 200;

Edit:

Adding implementation option for the fun of it:

import java.util.Arrays;
import java.util.Comparator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.stream.Collectors;

public class ChangeCalculator {

    enum EuroDenominations {
        ONE_CENT_COIN(1, "1¢"),
        TWO_CENT_COIN(2, "2¢"),
        FIVE_CENT_COIN(5, "5¢"),
        TEN_CENT_COIN(10, "10¢"),
        TWENTY_CENT_COIN(20, "20¢"),
        FIFTY_CENT_COIN(50, "50¢"),
        ONE_EURO_COIN(100, "€1"),
        TWO_EURO_COIN(200, "€2");
        // using an enum like this makes the types of change extensible
        // e.g. you can add a FIVE_EURO_NOTE here and no other changes are 
        // required

        private final int cents;
        private final String symbol;

        EuroDenominations(int cents,
                          String symbol) {
            this.cents = cents;
            this.symbol = symbol;
        }

        public int cents() {
            return cents;
        }

        public String symbol() {
            return symbol;
        }
    }

    public static Map<EuroDenominations, Integer> rueckgaberechner(double geld) {
        // it's preferable that methods don't mutate their input so here
        // we copy it into a temporary variable we can work with
        AtomicReference<Double> atomicGeld = new AtomicReference<>(geld);
        return Arrays.stream(EuroDenominations.values())
                // It's important that coins are evaluated in order of
                // largest to smallest and that this stream is evaluated 
                // sequentially
                .sorted(Comparator.comparing(EuroDenominations::cents).reversed())
                .collect(Collectors.toMap(Function.identity(), v -> {
                            double g = atomicGeld.get();
                            int i = (int) (g / v.cents());
                            atomicGeld.set(g % v.cents());
                            return i;
                        },
                        // merging will never happen, this is required
                        // by the function
                        (a, b) -> a,
                        // using a linked hashmap to retain insertion 
                        // order for pretty printing in size order later
                        LinkedHashMap::new)); 
        // since we're talking about money you should decide how you want
        // to handle rounding/remainders
    }

    public static void main(String[] args) {
        Map<EuroDenominations, Integer> rueckgaberechner = rueckgaberechner(388);
        System.out.println(rueckgaberechner);

        System.out.println("\nPretty print:");

        rueckgaberechner.entrySet().stream()
                .filter(entry -> entry.getValue() != 0)
                .forEach(entry -> System.out.printf("%d mal %s\n", entry.getValue(), entry.getKey().symbol()));
    }
}

Output:

{TWO_EURO_COIN=1, ONE_EURO_COIN=1, FIFTY_CENT_COIN=1, TWENTY_CENT_COIN=1, TEN_CENT_COIN=1, FIVE_CENT_COIN=1, TWO_CENT_COIN=1, ONE_CENT_COIN=1}

Pretty print:
1 mal €2
1 mal €1
1 mal 50¢
1 mal 20¢
1 mal 10¢
1 mal 5¢
1 mal 2¢
1 mal 1¢

You could re-order the enum to be in the required order by default to skip the sort step and use an EnumMap instead of LinkedHashMap for slightly better performance but the code becomes a little less obvious and a little more fragile.

0

You can put it into a own function:

public static void Rueckgaberechner(Double geld) {
    System.out.println("Rueckgeld: ");
    geld = anzahlRueckgeld(200,geld, " mal 2 Euro");
    geld = anzahlRueckgeld(100,geld, " mal 1 Euro");
    geld = anzahlRueckgeld(50,geld, " mal 50 cent");
    geld = anzahlRueckgeld(20,geld, " mal 20 cent");
    geld = anzahlRueckgeld(10,geld, " mal 10 cent");
    geld = anzahlRueckgeld(5,geld, " mal 5 cent");
    geld = anzahlRueckgeld(2,geld, " mal 2 cent");
    anzahlRueckgeld(1,geld, " mal 1 cent");
}

public static  double anzahlRueckgeld(int amount, double geld ,String text) {
    int rgeldt =0;
    
    while (geld >= amount) {
        geld = geld - amount;
        rgeldt = rgeldt + 1;
    }
    if (rgeldt >=1) {
        System.out.println(rgeldt +text);
    }
    return geld;
}

BTW: By convention, method names in java should start with lower case character

Jens
  • 67,715
  • 15
  • 98
  • 113
0

The input of your function should be in cents. This should be a natural number (int) vs a real number (float).

import java.util.*;

public class CoinDisplay {
    private static List<CoinDenomination> euroCoinDenominations = List.of(
        new CoinDenomination(200, "2 Euro"),
        new CoinDenomination(100, "1 Euro"),
        new CoinDenomination(50, "50 Cent"),
        new CoinDenomination(20, "20 Cent"),
        new CoinDenomination(10, "10 Cent"),
        new CoinDenomination(5, "5 Cent"),
        new CoinDenomination(2, "2 Cent"),
        new CoinDenomination(1, "1 Cent")
    );

    public static void main(String args[]) {
      System.out.println(formatCents(497, euroCoinDenominations));
    }
    
    public static String formatCents(int cents, List<CoinDenomination> coinDenoms) {
        List<String> result = new ArrayList<>();
        for (CoinDenomination denom : coinDenoms) {
            int count = (int) Math.floor(cents / denom.getAmount());
            if (count > 0) {
                result.add(String.format("%d × %s", count, denom.getDisplay()));
            }
            cents %= denom.getAmount();
        }
        return String.join(System.lineSeparator(), result);
    }

    private static class CoinDenomination {
        private int amount;
        private String display;
        public CoinDenomination(int amount, String display) {
            this.amount = amount;
            this.display = display;
        }
        public int getAmount() { return this.amount; }
        public String getDisplay() { return this.display; }
    }
}

Output

2 × 2 Euro
1 × 50 Cent
2 × 20 Cent
1 × 5 Cent
1 × 2 Cent

Here is a JavaScript version that works as a snippet:

const euroCoinDenominations = [
  { amount: 200 , display: '2 Euro'  },
  { amount: 100 , display: '1 Euro'  },
  { amount:  50 , display: '50 Cent' },
  { amount:  20 , display: '20 Cent' },
  { amount:  10 , display: '10 Cent' },
  { amount:   5 , display: '5 Cent'  },
  { amount:   2 , display: '2 Cent'  },
  { amount:   1 , display: '1 Cent'  }
];

const formatCents = (cents, coinDenominations) => {
  const result = [];
  for (let { amount, display } of coinDenominations) {
    const count = Math.floor(cents / amount);
    if (count > 0) {
      result.push(`${count} × ${display}`);
    }
    cents %= amount;
  }
  return result.join('\n');
};

console.log(formatCents(497, euroCoinDenominations));
.as-console-wrapper { top: 0; max-height: 100% !important; }
Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
0

You don't need to loop.

static int Rueckgaberechner(int geld, int unit, String message) {
    int regld = geld / unit;
    if (regld > 0)
        System.out.println(regld + " mal " + message);
    return geld % unit;
}

public static void Rueckgaberechner(int geld) {
    System.out.println("Rueckgeld: ");
    geld = Rueckgaberechner(geld, 200, "2 Euro");
    geld = Rueckgaberechner(geld, 100, "1 Euro");
    geld = Rueckgaberechner(geld, 50, "50 Cent");
    geld = Rueckgaberechner(geld, 20, "20 Cent");
    geld = Rueckgaberechner(geld, 10, "10 Cent");
    geld = Rueckgaberechner(geld, 5, "5 Cent");
    geld = Rueckgaberechner(geld, 2, "2 Cent");
    geld = Rueckgaberechner(geld, 1, "1 Cent");
}

public static void main(String[] args) {
    Rueckgaberechner(1498);
}

output:

Rueckgeld: 
7 mal 2 Euro
1 mal 50 Cent
2 mal 20 Cent
1 mal 5 Cent
1 mal 2 Cent
1 mal 1 Cent