Es kann auch passieren, das nur 2x 20 in der Kasse ist und somit 60 auch nicht mit 20er auszahlbar ist?
Nein, es wird angenommen, dass immer unendlich viele Scheine in der Kasse sind (leider nur eine Annahme
).
Ich hab jetzt hoffentlich eine Lösung. Das ganze hab ich rekursiv gelöst. Bei jedem Funktionsaufruf wird geprüft, ob der (Rest-) Betrag durch eine der Noten teilbar ist. Wenn ja: fertig.
Bisher hab ich kein Beispiel gefunden, wo es nicht funktioniert. Vielleicht möchte ja jemand versuchen, ein Beispiel zu finden, wo es fehlschlägt.
Delphi-Quellcode:
unit UVorschuss;
interface
uses
Generics.Collections;
type
TGeldstueckliste = TList<Currency>;
TVorschuss =
class(TObject)
private
FGeldstueckliste: TGeldstueckliste;
Function GroessterBetrag(ABetrag : Currency) : Currency;
protected
public
constructor Create;
destructor Destroy;
override;
property Geldstueckliste : TGeldstueckliste
read FGeldstueckliste;
Function IsBetragAuszahlbar(ABetrag : Currency) : Boolean;
end;
implementation
{ TVorschuss }
constructor TVorschuss.Create;
begin
inherited;
FGeldstueckliste := TGeldstueckliste.Create;
end;
destructor TVorschuss.Destroy;
begin
FGeldstueckliste.Free;
inherited;
end;
function TVorschuss.GroessterBetrag(ABetrag: Currency): Currency;
var
Geldstueck : Double;
begin
result := 0;
for Geldstueck
in FGeldstueckliste
do
begin
if (Geldstueck <= ABetrag)
and (Geldstueck > Result)
then
result := Geldstueck;
end;
end;
function TVorschuss.IsBetragAuszahlbar(ABetrag: Currency): Boolean;
var
sub : Double;
NeuerBetrag : Double;
i : integer;
intBetrag : integer;
begin
result := False;
i := 0;
intBetrag := trunc(ABetrag * 100);
while (i <= FGeldstueckliste.Count - 1)
and not result
do
begin
result := (intBetrag
mod trunc(FGeldstueckliste.Items[i] * 100)) = 0;
inc(i);
end;
if not Result
then
begin
sub := GroessterBetrag(ABetrag);
if sub > 0
then
begin
NeuerBetrag := ABetrag - sub;
if NeuerBetrag = 0
then
result := True
else
result := IsBetragAuszahlbar(NeuerBetrag);
end
else
result := false;
end;
end;
end.