Beri saya uang tunai dari ATM

26

Tugasnya sederhana. Dapatkan saya beberapa 1000, 500dan 100catatan.

Bagaimana? Anda mungkin bertanya. Jangan khawatir, tidak perlu merampok bank karena ada ATM di dekatnya yang menerima kartu kredit Anda. Tetapi batas kredit Anda hanya cukup untuk tugas itu sehingga Anda harus berhati-hati dengan penarikan.

Tantangan

Mengingat jumlah 1000, 500dan 100catatan yang diperlukan, hitung penarikan khusus yang diperlukan untuk mendapatkan setidaknya banyak catatan itu. Dalam setiap penarikan, ATM dapat memuntahkan masing-masing catatan berdasarkan aturan berikut:

  • Jumlah yang ditarik ( A) kurang dari5000
    • Jika A%1000 == 0, maka ATM meludahi 1 500note, 5 100note dan sisanya 1000note
    • Kalau tidak A%500 == 0, ATM meludahi 5 100not, sisanya 1000not
    • Jika tidak A%1000 < 500, ATM akan meludahkan floor(A/1000) 1000catatan dan 100catatan lainnya
    • Jika tidak A%1000 > 500, ATM akan mengeluarkan floor(A/1000) 1000catatan, 1 500dan 100catatan lainnya
  • Jumlah yang ditarik lebih besar dari sama dengan 5000
    • Jika A%1000 == 0, maka ATM meludah 2 500catatan dan 1000catatan sisa
    • Jika tidak, A%500 == 0ATM akan meludahkan 1 500catatan dan 1000catatan lainnya
    • Jika tidak A%1000 < 500, ATM akan meludahkan floor(A/1000) 1000catatan dan 100catatan lainnya
    • Jika tidak A%1000 > 500, ATM akan mengeluarkan floor(A/1000) 1000catatan, 1 500dan 100catatan lainnya

Untuk klarifikasi, berikut adalah tabel lengkap catatan yang ditarik untuk semua jumlah yang mungkin hingga 7000(Anda dapat menarik lebih banyak, tetapi polanya tidak berubah setelahnya). Urutannya adalah <1000> <500> <100>:

 100 => 0 0 1                  2500 => 2 0 5                   4800 => 4 1 3
 200 => 0 0 2                  2600 => 2 1 1                   4900 => 4 1 4
 300 => 0 0 3                  2700 => 2 1 2                   5000 => 4 2 0
 400 => 0 0 4                  2800 => 2 1 3                   5100 => 5 0 1
 500 => 0 0 5                  2900 => 2 1 4                   5200 => 5 0 2
 600 => 0 1 1                  3000 => 2 1 5                   5300 => 5 0 3
 700 => 0 1 2                  3100 => 3 0 1                   5400 => 5 0 4
 800 => 0 1 3                  3200 => 3 0 2                   5500 => 5 1 0
 900 => 0 1 4                  3300 => 3 0 3                   5600 => 5 1 1
1000 => 0 1 5                  3400 => 3 0 4                   5700 => 5 1 2
1100 => 1 0 1                  3500 => 3 0 5                   5800 => 5 1 3
1200 => 1 0 2                  3600 => 3 1 1                   5900 => 5 1 4
1300 => 1 0 3                  3700 => 3 1 2                   6000 => 5 2 0
1400 => 1 0 4                  3800 => 3 1 3                   6100 => 6 0 1
1500 => 1 0 5                  3900 => 3 1 4                   6200 => 6 0 2
1600 => 1 1 1                  4000 => 3 1 5                   6300 => 6 0 3
1700 => 1 1 2                  4100 => 4 0 1                   6400 => 6 0 4
1800 => 1 1 3                  4200 => 4 0 2                   6500 => 6 1 0
1900 => 1 1 4                  4300 => 4 0 3                   6600 => 6 1 1
2000 => 1 1 5                  4400 => 4 0 4                   6700 => 6 1 2
2100 => 2 0 1                  4500 => 4 0 5                   6800 => 6 1 3
2200 => 2 0 2                  4600 => 4 1 1                   6900 => 6 1 4
2300 => 2 0 3                  4700 => 4 1 2                   7000 => 6 2 0
2400 => 2 0 4

Daftar disediakan oleh Martin

Tangkapan

Karena batas kredit dalam kartu kredit Anda hanya cukup, Anda perlu memastikan bahwa jumlah total yang ditarik di seluruh penarikan adalah seminimal mungkin untuk input / persyaratan catatan yang diberikan.

Memasukkan

Masukan bisa dalam format yang menguntungkan selama tiga angka sesuai dengan jumlah catatan yang diperlukan dari nilai 1000, 500dan 100. Tidak harus dalam urutan itu.

Keluaran

Output adalah jumlah yang akan ditarik dalam setiap transaksi yang dipisahkan oleh baris baru.

Contohnya

Input (format <1000> <500> <100>):

3 4 1

Keluaran:

600
600
600
3600

beberapa lagi:

7 2 5
5000
3500

1 2 3
600
1700

21 14 2
600
600
600
1600
5000
5000
5000
5000
5000

Asumsi

  • Anda dapat berasumsi bahwa ATM memiliki jumlah catatan tanpa batas untuk setiap jumlah.
  • Anda juga dapat mengasumsikan bahwa Anda dapat melakukan sejumlah transaksi.
  • Selain itu, solusi untuk beberapa nilai input mungkin tidak unik, sehingga Anda dapat mengeluarkan 1 dari solusi yang memenuhi jumlah minimum yang mungkin dan persyaratan catatan minimum yang diperlukan.

Seperti biasa, Anda dapat menulis input pembacaan program lengkap melalui STDIN / ARGV dan mencetak output ke STDOUT atau fungsi mengambil input melalui argumen dan mengembalikan daftar bilangan bulat yang sesuai dengan jumlah atau string dengan jumlah yang dipisahkan oleh baris baru.

Ini adalah kode-golf sehingga kode terpendek dalam byte menang.

Pengoptimal
sumber
@ Kacki memang. Diedit.
Pengoptimal
Apakah ada batasan kecepatan? Haruskah test case terakhir 21 14 2selesai dalam waktu yang wajar?
Jakube
1
@ Jakube Dalam waktu yang wajar - ya (katakanlah kurang dari 5-6 jam). Tetapi dengan demikian, tidak ada batasan karena ini adalah kode-golf.
Pengoptimal
Jadi, jika saya menarik 0, itu akan memberi saya lima 100 catatan?
AJMansfield
@AJMansfield tentu saja tidak. Anda tidak dapat menarik jumlah 0
Pengoptimal

Jawaban:

7

JavaScript, 184 148

function g(a,b,c){x=[];while(a>0||b>0||c>0){i=b<3||a<4?a:4;a-=i;if(i>3&&b>1){b-=2;i++}else{i+=(c--<b&&i>4?0:.1)+(b-->0?.5:0)}x.push(i*1e3)}return x}

http://jsfiddle.net/vuyv4r0p/2/

mengembalikan daftar bilangan bulat yang sesuai dengan jumlah penarikan

hoffmale
sumber
Coba g(5,1,1). Salah satu solusi yang lebih baik: 5600.
jimmy23013
harus diperbaiki sekarang
hoffmale
g(5,1,0), Solusi: 5500.
jimmy23013
yang sekarang juga harus diperbaiki ^ terima kasih untuk menunjukkan hal itu, saya pasti terlalu mengantuk
hoffmale
g(5,2,0), Solusi: 6000.
jimmy23013
1

Perl 5: 223

Edit

Solusi ini dilakukan dengan asumsi yang salah bahwa 7K adalah batas ATM. Ini benar-benar membuat tugas lebih menarik karena membutuhkan pemrograman dinamis (pola gerakannya cukup teratur, tetapi pengkodean akan lebih lama daripada menghitung langsung seperti yang saya lakukan). Dengan jumlah yang memungkinkan, pola perpindahan sangat teratur sehingga mudah untuk mengkodekannya. Saya tidak tahu apakah solusi oleh @hoffmale sekarang benar, tetapi akan ada di antara baris-baris ini. Sedihnya itu akan menjadi tugas lain di mana seseorang pertama kali datang dengan solusi dan kemudian porting ke bahasa golf untuk menang.

Sedikit lebih lambat dari solusi asli (tapi masih sub-detik untuk parameter di bawah 100).

#!perl -pa
$c{0,0}=$f=($a,$b,$c)=@F;for$i(0..$b){for$j(0..$a){
/.(?=.$)/>($n=$c{$i-$`,$j-$'})||${$r=\$c{$i,$j}}<($x=$n+$&)&&$$r
or$f=$$r="$x $n".($'.$&+5*$`)."00
"for 204..206,105,106,11..15,110..114}}$_=$f."100
"x($c-$f+3);s/.*\b3//

Solusi 259 lebih cepat.

#!perl -pa
$c{0,0}=($a,$b,$c)=@F;for$i(0..$b){for$j(0..$a){
/\B./<($%=$c{$i-$&,$j-$'}+$`)&&(!${$r=\$c{$i,$j}}||$$r>$%)and$d{$i,$j}=$_,$$r=$%for
qw/024 025 026 015 016/,101..105,110..114}}
$d{$b,$a}=~/\B./,$c-=$`,$b-=$&,$a-=$',print$'.$`+5*$&,"00
"while$a+$b;$_="100
"x$c

Menggunakan STDIN:

$perl atm.pl <<<"21 14 2"
5000
5000
5000
5000
5000
600
600
600
1600
nutki
sumber
Coba 10 0 0. Solusi yang lebih baik: 10100.
jimmy23013
@ user23013 oops, saya salah paham pertanyaannya. Saya berasumsi 7k adalah jumlah maksimum :( Saya harap saya akan bisa memperbaikinya.
nutki