Ich habe 15 Dollar in der Tasche. Ebenso bin ich in einem Geschäft, das kein Wechselgeld gibt. Beim Surfen sehe ich einen Artikel, der 10 US-Dollar kostet (inklusive Steuern). Kann ich diesen Artikel kaufen, ohne Geld zu verlieren?
In diesem Fall lautet die Antwort ja. Egal wie meine 15 $ aufgeteilt sind (eine 10 und eine 5 oder drei 5 oder etwas anderes), ich werde immer genau die 10 $ haben, die benötigt werden.
Als zweites Beispiel habe ich 0,16 Dollar in der Tasche. Welche anderen Geldbeträge muss ich genau bezahlen können?
Possible Divisions:
0.01, 0.05, 0.10
0.01, 0.05 x 3
0.01 x 16
Guaranteed Exact Change:
0.01, 0.05, 0.06, 0.10, 0.11, 0.15, 0.16
Was ist, wenn ich 0,27 USD in der Tasche habe?
Possible Divisions:
0.01 x 2, 0.25
0.01 x 2, 0.05, 0.10 x 2
0.01 x 2, 0.05 x 3, 0.10
0.01 x 2, 0.05 x 5
0.01 x 27
Guaranteed Exact Change:
0.01, 0.02, 0.25, 0.26, 0.27
Im obigen Fall gab es nur wenige Geldbeträge, für die ich immer ein perfektes Wechselgeld hätte.
Deine Aufgabe
Schreiben Sie das kürzeste Programm (oder die benannte Funktion), das A) einen ganzzahligen Geldbetrag und B) eine Liste möglicher Stückelungen als Eingabe verwendet und eine Liste der Geldbeträge ausgibt, für die ich eine perfekte Änderung haben muss. Die Eingabe kann entweder STDIN oder Argumente für das Programm oder die Funktion sein. Ich werde bei der Eingabeformatierung nicht sehr streng sein. Es kann übereinstimmen, wie Ihre Sprache Arrays formatiert.
Vielleicht eine ausführlichere Erklärung
Ich habe einen bestimmten Geldbetrag in der Tasche, der sich aus einer Reihe möglicher Währungsdemonstrationen zusammensetzt. Wenn ich 8 Dollar habe und weiß, dass die möglichen Stückelungen 2 und 3 Dollar sind, dann gibt es nur so viele verschiedene Kombinationen von Scheinen, die in meiner Tasche sein könnten. Das sind 2+2+2+2
und 3+3+2
. Um einen genauen Geldbetrag produzieren zu können, muss ich in der Lage sein, diese Menge nur mit den Rechnungen zu produzieren, die sich in meiner Tasche befinden. Wenn ich vier 2er hätte, könnte ich produzieren 2, 4, 6, or 8
. Wenn ich zwei 3er und eine 2er hätte, könnte ich produzieren. 2, 3, 5, 6, or 8
Da ich nicht weiß, welche dieser Kombinationen ich tatsächlich in meiner Tasche habe, reduziert sich meine endgültige Antwort auf 2, 6, 8
. Dies sind die Werte, von denen ich weiß, dass ich sie angesichts der Gesamtmenge und der möglichen Stückelungen aus meiner Tasche produzieren kann.
Handberechnete Beispiel-E / A.
7 [3, 4]
3, 4, 7 //only one possible division into 3 + 4
7 [3, 2]
2, 3, 4, 5, 7 //the only division is 3 + 2 + 2
6 [2, 3, 4]
6 //divisions are 2+2+2, 3+3, 2+4
16 [1, 5, 10, 25] //this represents one of the examples above
1, 5, 6, 10, 11, 15, 16
27 [1, 5, 10, 25] //another example from above
1, 2, 25, 26, 27
1500 [1, 5, 10, 25, 100, 500, 1000, 2000]
500, 1000, 1500
600 [100, 500, 1000, 2000]
100, 500, 600
600 [200, 1, 5, 10, 25, 100, 500, 1000, 2000]
600
6 [2, 3, 4]
. Kannst du nicht2+2+2
3 machen und3+3
nicht 2 und 4 machen?Antworten:
Python 2,
200197193140 Bytes(Danke an @Nabb für Tipps)
Hier ist eine schlecht Golf Lösung für den Moment, um die Dinge in Gang zu bringen. Call with
g(16, [1, 5, 10, 25])
- output ist eine Menge mit den relevanten Nennwerten.Der Ansatz ist unkompliziert und gliedert sich in zwei Schritte:
f
untersucht alle Möglichkeiten,n
mit StückelungenD
(z. B.[1, 5, 10]
) zu erreichen, und berechnet für jede alle Beträge, die mit diesen Stückelungen (zset([0, 1, 5, 6, 10, 11, 15, 16])
. B. ) erzielt werden können .g
berechnet die Schnittpunkte der Ergebnisse vonf
und entfernt dann 0 für die endgültige Antwort.Das Programm löst die Fälle 1-5 und 7 fein, stapelt Überläufe auf 6 und dauert ewig auf 8.
Wenn es keine Lösung gibt (z. B.
g(7, [2, 4, 6])
), gibt das Programm einen leeren Satz zurück. Wenn in einem solchen Fall ein Fehler ausgegeben werden darf, ist hier ein kürzererg
:quelle
g=lambda L,c=0:L and g(L[1:],c)|g(L,c+L.pop(0))or{c}
ist etwas kürzer-{0}
in g[L]*-~n
[L][-n:]
JavaScript (ES6) 162
203 207Bearbeiten Die Art und Weise, wie Ergebnismengen in Array r geschnitten werden, wurde geändert. Ein bisschen schneller, aber der Algorithmus stinkt immer noch.
Eine ausführlichere Erklärung folgt.Kurz gesagt: c ist eine rekursive Funktion, die alle möglichen Unterteilungen auflistet. k ist eine rekursive Funktion, die alle möglichen Summen ohne Wiederholungen auflistet. Jede neue Ergebnismenge, die mit der Funktion k gefunden wurde, wird mit der zuvor gefundenen Menge verglichen. Es werden nur die gemeinsamen Ergebnisse beibehalten.
Warum ist es so langsam? Es ist keine gute Idee, eine Zielsumme von beispielsweise 1500 und ein einzelnes Stück Wert 1 zu verwalten und alle möglichen Summen aufzulisten.
Ungolfed
Test In Firefox / Firebug - Konsole
(Zeit 84 ms)
(Zeit 147252 ms, also nicht sooo schnell)
quelle
Wolfram Methematica, 104 Bytes
Ungolfed (vom Ende lesen):
quelle