Mam 15 $ w kieszeni. Podobnie jestem w sklepie, który nie daje zmian. Podczas przeglądania zauważam przedmiot, który kosztuje 10 USD (zawiera podatek). Czy mogę kupić ten przedmiot bez utraty pieniędzy?
W takim przypadku odpowiedź brzmi „tak”. Bez względu na to, jak podzielę moje 15 $ (jedno 10 i jedno 5, lub trzy 5, lub coś innego), zawsze będę potrzebował dokładnie 10 $.
Jako drugi przykład mam 0,16 $ w kieszeni. Jakie inne kwoty muszę dokładnie zapłacić?
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
Co jeśli mam 0,27 $ w kieszeni?
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
W powyższym przypadku było tylko kilka pieniędzy, na które zawsze miałbym idealną zmianę.
Twoje zadanie
Napisz najkrótszy program (lub nazwaną funkcję), który bierze A) całkowitą kwotę pieniędzy i B) listę możliwych nominałów jako dane wejściowe i wyświetla listę kwot pieniędzy, na które muszę mieć doskonałą zmianę. Dane wejściowe mogą być STDIN lub argumentami programu lub funkcji. Nie będę zbyt surowy w zakresie formatowania danych wejściowych; może pasować do sposobu, w jaki tablice formatują Twój język.
Być może bardziej szczegółowe wyjaśnienie
Mam w kieszeni pewną ilość pieniędzy, która powstaje z zestawu możliwych demonstracji waluty. Jeśli mam 8 USD i wiem, że możliwymi nominałami są 2 i 3 USD, to w mojej kieszeni jest tyle różnych kombinacji rachunków. To są 2+2+2+2
i 3+3+2
. Aby móc wyprodukować dokładną ilość pieniędzy, muszę być w stanie wyprodukować tę ilość, korzystając tylko z rachunków, które mam w kieszeni. Gdybym miał cztery 2, mógłbym wyprodukować 2, 4, 6, or 8
. Gdybym miał dwie 3 i 2, mógłbym wyprodukować 2, 3, 5, 6, or 8
Ponieważ nie wiem, które z tych kombinacji faktycznie mam w kieszeni, moja ostateczna odpowiedź jest ograniczona do 2, 6, 8
. Są to wartości, które wiem, że mógłbym wytworzyć z kieszeni, biorąc pod uwagę całkowitą kwotę i możliwe nominały.
Ręcznie obliczany przykład I / O
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]
. Nie możesz2+2+2
zrobić 3 i3+3
nie zrobić 2 i 4?Odpowiedzi:
Python 2,
200197193140 bajtów(Podziękowania dla @Nabb za wskazówki)
Oto na razie kiepskie rozwiązanie na początek. Połączenie z
g(16, [1, 5, 10, 25])
- wyjściem jest zbiorem o odpowiednich nominałach.Podejście jest proste i dzieli się na dwa etapy:
f
analizuje wszystkie sposoby dotarcian
do nominałówD
(np.[1, 5, 10]
) i dla każdego z nich oblicza wszystkie kwoty, które można uzyskać za pomocą tych nominałów (npset([0, 1, 5, 6, 10, 11, 15, 16])
.).g
oblicza przecięcia wynikówf
, a następnie usuwa 0 dla ostatecznej odpowiedzi.Program rozwiązuje przypadki 1-5 i 7 grzywny, przepełnienie stosu na 6 i trwa wiecznie na 8.
Jeśli nie ma rozwiązania (np.
g(7, [2, 4, 6])
), Program zwraca pusty zestaw. Jeśli w takim przypadku dopuszcza się błąd, jest to krótszeg
:źródło
g=lambda L,c=0:L and g(L[1:],c)|g(L,c+L.pop(0))or{c}
jest trochę krótszy-{0}
do g i używając[L]*-~n
zamiast[L][-n:]
JavaScript (ES6) 162
203 207Edytuj Zmieniono sposób przecinania zestawów wyników w tablicy r. Trochę szybciej, ale algorytm wciąż śmierdzi.
Bardziej szczegółowe wyjaśnienie nastąpi.W skrócie: c jest funkcją rekurencyjną, która wylicza wszystkie możliwe poddziały. k jest funkcją rekurencyjną, która wylicza wszystkie możliwe sumy bez powtórzeń. Każdy nowy zestaw wyników znaleziony za pomocą funkcji k jest porównywany z poprzednim znalezionym zestawem, zachowane są tylko wspólne wyniki.
Dlaczego jest taki wolny? Konieczność zarządzania docelową sumą, powiedzmy, 1500 i pojedynczą wartością o wartości 1, wyliczenie wszystkich możliwych kwot nie jest dobrym pomysłem.
Nie golfił
Przetestuj w konsoli Firefox / FireBug
(czas 84 ms)
(czas 147252 ms, więc nie tak szybko)
źródło
Wolfram Methematica, 104 bajty
Niegolfowany (czytany od końca):
źródło