Saya memiliki $ 15 di saku saya. Demikian juga, saya berada di toko yang tidak memberikan perubahan. Saat menjelajah, saya melihat item yang harganya $ 10 (termasuk pajak). Bisakah saya membeli barang itu tanpa kehilangan uang?
Dalam hal ini, jawabannya adalah ya. Tidak peduli bagaimana $ 15 saya dibagi (satu 10 dan satu 5, atau tiga 5s, atau yang lain), saya akan selalu memiliki $ 10 persis yang dibutuhkan.
Sebagai contoh kedua, saya memiliki $ 0,16 di saku saya. Berapa jumlah uang lain yang harus saya bayarkan?
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
Bagaimana jika saya memiliki $ 0,27 di saku saya?
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
Dalam kasus di atas, hanya ada beberapa jumlah uang yang saya akan selalu memiliki perubahan sempurna.
Tugas Anda
Tuliskan program terpendek (atau fungsi bernama) yang mengambil A) jumlah uang integer dan B) daftar kemungkinan denominasi sebagai input, dan mengeluarkan daftar jumlah uang yang saya harus memiliki perubahan sempurna. Input dapat berupa STDIN atau argumen untuk program atau fungsi. Saya tidak akan menjadi super ketat pada pemformatan input; itu bisa cocok dengan bagaimana format bahasa Anda array.
Mungkin Penjelasan Lebih Detail
Saya memiliki sejumlah uang di saku, yang terbentuk dari serangkaian kemungkinan demonstrasi mata uang. Jika saya memiliki $ 8, dan saya tahu bahwa denominasi yang mungkin adalah $ 2 dan $ 3, maka hanya ada begitu banyak kombinasi tagihan yang berbeda yang ada di saku saya. Ini 2+2+2+2
dan 3+3+2
. Agar dapat menghasilkan jumlah uang yang tepat, saya harus dapat menghasilkan jumlah itu dengan hanya menggunakan tagihan yang ada di saku saya. Jika saya punya empat 2, saya bisa menghasilkan 2, 4, 6, or 8
. Jika saya memiliki dua angka 3 dan 2, saya bisa menghasilkan. 2, 3, 5, 6, or 8
Karena saya tidak tahu kombinasi mana yang sebenarnya saya miliki di saku saya, jawaban akhir saya berkurang menjadi 2, 6, 8
. Inilah nilai-nilai yang saya tahu dapat saya hasilkan dari saku, mengingat jumlah total dan kemungkinan denominasi.
Contoh Tangan-Dihitung 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]
. Tidak dapat2+2+2
membuat 3, dan3+3
tidak membuat 2 dan 4?Jawaban:
Python 2,
200197193140 byte(Terima kasih kepada @Nabb untuk kiatnya)
Berikut ini adalah solusi golf yang buruk untuk saat ini untuk memulai sesuatu. Panggilan dengan
g(16, [1, 5, 10, 25])
- keluaran adalah seperangkat denominasi yang relevan.Pendekatannya mudah, dan dipecah menjadi dua langkah:
f
melihat semua cara untuk mencapain
dengan denominasiD
(mis.[1, 5, 10]
), dan untuk masing-masing itu berhasil semua jumlah yang dapat dibuat dengan denominasi ini (misalnyaset([0, 1, 5, 6, 10, 11, 15, 16])
).g
menghitung persimpangan hasilf
, lalu menghilangkan 0 untuk jawaban akhir.Program ini menyelesaikan case 1-5 dan 7 fine, menumpuk overflow 6 dan berlangsung selamanya 8.
Jika tidak ada solusi (mis.
g(7, [2, 4, 6])
), Maka program mengembalikan set kosong. Jika kesalahan diizinkan untuk kasus seperti itu, maka inilah yang lebih pendekg
:sumber
g=lambda L,c=0:L and g(L[1:],c)|g(L,c+L.pop(0))or{c}
sedikit lebih pendek-{0}
ke g dan menggunakan[L]*-~n
bukannya[L][-n:]
JavaScript (ES6) 162
203 207Sunting Mengubah cara untuk memotong set hasil dalam array r. Sedikit lebih cepat, tetapi algoritmanya masih bau.
Penjelasan lebih rinci akan mengikuti.Singkatnya: c adalah fungsi rekursif yang menyebutkan semua subdivisi yang mungkin. k adalah fungsi rekursif yang menghitung semua jumlah yang mungkin tanpa pengulangan. Setiap set hasil baru yang ditemukan dengan fungsi k dibandingkan dengan set sebelumnya yang ditemukan, hanya hasil umum yang disimpan.
Kenapa sangat lambat? Harus mengelola total target, katakanlah, 1500 dan sepotong nilai 1, menghitung semua jumlah yang mungkin bukan ide yang baik.
Tidak disatukan
Uji di Firefox / konsol FireBug
(waktu 84 msec)
(waktu 147252 msec, jadi tidak terlalu cepat)
sumber
Wolfram Methematica, 104 byte
Tidak Digubah (baca dari akhir):
sumber