Baru-baru ini di Puzzling.SE, ada masalah yang saya tulis tentang menentukan dua botol dari jumlah yang lebih besar yang diracuni ketika racun hanya aktif jika kedua komponen diminum. Itu akhirnya menjadi cobaan berat, dengan sebagian besar orang berhasil menurunkannya menjadi 18 atau 19 tahanan menggunakan algoritma yang sama sekali berbeda.
Pernyataan masalah asli adalah sebagai berikut:
Anda adalah penguasa kerajaan abad pertengahan yang suka mengadakan pesta. Petugas pengadilan yang mencoba meracuni salah satu botol anggur Anda terakhir kali sangat marah mengetahui bahwa Anda berhasil mengidentifikasi botol mana yang telah diracuni dari 1.000 botol dengan hanya sepuluh tahanan.
Kali ini dia sedikit rajin. Dia mengembangkan racun komposit
P
: cairan biner yang hanya mematikan ketika dua komponen yang tidak berbahaya bercampur secara individu; ini mirip dengan cara kerja epoksi. Dia mengirimi Anda peti berisi 1.000 botol anggur lagi. Satu botol memiliki komponenC_a
dan yang lain memiliki komponenC_b
. (P = C_a + C_b
)Siapa pun yang minum kedua komponen akan mati pada tengah malam pada malam mereka minum komponen terakhir, terlepas dari kapan di hari mereka menyerap cairan. Setiap komponen racun tetap berada di dalam tubuh sampai komponen kedua aktif, jadi jika Anda minum satu komponen satu hari dan komponen lainnya di hari berikutnya, Anda akan mati pada tengah malam di akhir hari kedua.
Anda memiliki dua hari sebelum pesta berikutnya. Berapa jumlah minimum tahanan yang perlu Anda gunakan untuk pengujian untuk mengidentifikasi dua botol yang tercemar, dan algoritma apa yang perlu Anda ikuti dengan jumlah tahanan itu?
Bonus
Selain itu, anggaplah Anda memiliki batas tetap 20 tahanan yang Anda miliki, berapa jumlah botol maksimum yang dapat Anda uji secara teoritis dan sampai pada kesimpulan yang akurat tentang botol mana yang terpengaruh?
Tugas Anda adalah membangun program untuk memecahkan masalah bonus. Diberikan n
tahanan, program Anda akan menyusun jadwal pengujian yang akan dapat mendeteksi dua botol beracun di antara m
botol, di mana m
sebesar mungkin.
Program Anda awalnya akan mengambil sebagai input nomor N
, jumlah tahanan. Maka akan ditampilkan:
M
, jumlah botol yang akan Anda coba untuk menguji. Botol-botol ini akan diberi label dari1
keM
.N
baris, berisi label botol masing-masing tahanan akan minum.
Program Anda kemudian akan mengambil input tahanan mana yang mati di hari pertama, dengan tahanan di baris pertama 1
, baris berikutnya 2
, dll. Lalu, itu akan menampilkan:
N
lebih banyak garis, berisi label botol yang akan diminum setiap tahanan. Tahanan yang mati akan memiliki garis kosong.
Program Anda kemudian akan mengambil input tahanan mana yang mati pada hari kedua, dan menghasilkan dua angka, A
dan B
, mewakili dua botol mana yang menurut program Anda mengandung racun.
Contoh input untuk dua tahanan dan empat botol mungkin seperti itu, jika botol 1
dan 3
diracuni:
> 2 // INPUT: 2 prisoners
4 // OUTPUT: 4 bottles
1 2 3 // OUTPUT: prisoner 1 will drink 1, 2, 3
1 4 // OUTPUT: prisoner 2 will drink 1, 4
> 1 // INPUT: only the first prisoner died
// OUTPUT: prisoner 1 is dead, he can't drink any more bottles
3 // OUTPUT: prisoner 2 drinks bottle 3
> 2 // INPUT: prisoner 2 died
1 3 // OUTPUT: therefore, the poisoned bottles are 1 and 3.
The above algorithm may not actually work in all
cases; it's just an example of input and output.
Jadwal pengujian program Anda harus berhasil menentukan setiap kemungkinan pasangan botol beracun agar dapat menjadi pengiriman yang valid.
Program Anda akan dinilai berdasarkan kriteria berikut, dalam urutan:
Jumlah botol maksimum yang dapat dilihat untuk kasing
N = 20
.Jumlah botol untuk kasing
N = 21
, dan kasing lebih tinggi setelahnya.Panjang kode. (Kode pendek menang.)
sumber
Jawaban:
Python 2.7.9 - 21 botol
Dengan anggapan bahwa spekulasi ESultanik benar tentang apa inputnya ketika banyak tahanan mati
Algoritma: setiap tahanan minum dari setiap botol kecuali nomor mereka (tahanan pertama tidak minum botol pertama). Jika mereka tidak mati, botol nomor mereka diracuni. Jika hanya satu tahanan yang selamat, botol ekstra itu diracuni.
sumber
Perl 5 , 66 botol
(72 botol untuk 21 tahanan)
Para tahanan dibagi secara optimal menjadi 2 kelompok. Botol dikelompokkan dalam set.
Setiap tahanan dari grup 1 akan minum dari semua set kecuali satu. Akan ada 1 atau 2 yang selamat. Set 1 atau 2 yang tidak diminum akan berlanjut hingga hari ke 2.
Pada hari ke-2 tahanan yang tersisa (termasuk yang selamat) minum dari semua botol yang tersisa kecuali satu.
Ketika 2 tahanan bertahan hidup maka botol yang tidak mereka minum diracun.
Jika hanya 1 tahanan yang tersisa maka botol yang mereka minum juga mencurigakan.
Kode ini mencakup fungsionalitas tambahan untuk memfasilitasi pengujian. Ketika botol poisened ditambahkan sebagai parameter tambahan, maka itu tidak akan meminta masukan tentang siapa yang mati.
Uji
Tes tanpa input manual
sumber
Seperti tradisi, saya akan memposting jawaban referensi tempat terakhir.
Python - 7 botol
Buat setiap tahanan minum satu botol yang mungkin kecuali untuk dua botol terakhir. Jika ada tahanan yang mati, pasangan yang diminum oleh tahanan itu adalah yang beracun. Kalau tidak, itu dua botol terakhir yang diracuni.
Untuk penjatahan setidaknya
n(n-1)/2 - 1
tahanan, Anda dapat melakukan hinggan
botol. Sebabn = 7
, batas bawah ini adalah20
.Kami hanya membutuhkan satu hari agar solusi ini berfungsi. Solusi dua hari dengan ruang lingkup yang sama mungkin mendapatkan hingga 20 botol
N = 20
, tetapi itu terlalu banyak untuk jawaban sepele.sumber