Bayangkan skenario berikut ini: Anda bermain kapal perang dengan seorang teman tetapi memutuskan untuk menipu. Daripada memindahkan kapal setelah dia menembak di tempat kapal Anda dulu, Anda memutuskan untuk tidak menempatkan kapal sama sekali. Anda memberi tahu dia bahwa semua tembakannya meleset, sampai tidak mungkin menempatkan kapal sedemikian rupa.
Anda harus menulis fungsi, atau program lengkap, yang entah bagaimana membutuhkan 3 argumen: ukuran bidang, daftar jumlah ukuran kapal, dan daftar tembakan.
Medan perang
Salah satu parameter yang diberikan adalah ukuran papan. Medan perang adalah kuadrat sel, dan parameter yang diberikan hanyalah satu sisi kuadrat.
Misalnya, berikut ini adalah papan ukuran 5.
Koordinat di lapangan ditentukan sebagai string 2-komponen: huruf diikuti oleh angka. Anda dapat mengandalkan huruf-huruf dalam beberapa kasus tertentu.
Surat menentukan kolom, nomor menentukan baris sel (1-diindeks). Misalnya dalam gambar di atas, sel yang disorot ditandai dengan "D2"
.
Karena hanya ada 26 huruf, bidang tidak boleh lebih besar dari 26x26.
Kapal
Kapal adalah garis lurus 1 atau lebih blok. Jumlah kapal ditentukan dalam daftar, di mana elemen pertama adalah jumlah kapal 1-sel, kedua - kapal 2-sel dan sebagainya.
Misalnya, daftar [4,1,2,0,1]
akan membuat kapal berikut:
Ketika ditempatkan di medan perang, kapal tidak dapat berpotongan, atau bahkan saling menyentuh. Bahkan dengan sudut. Namun mereka dapat menyentuh tepi lapangan.
Di bawah ini Anda dapat melihat contoh penempatan kapal yang valid:
Anda dapat mengasumsikan bahwa untuk kapal tertentu, selalu ada penempatan di papan kosong ukuran tertentu.
Keluaran
Jika penempatan kapal seperti itu ada, Anda harus mengeluarkannya.
Program ini harus mengeluarkan matriks yang dipisahkan dengan baris baru dari karakter ascii dari 3 jenis - satu untuk menunjukkan sel kosong, satu - potongan kapal, dan satu - sel yang ditandai sebagai "tidak terjawab". Tidak ada karakter lain yang harus di-output.
Sebagai contoh,
ZZ@Z
\@@Z
@\\Z
\Z\\
(Dalam contoh ini, saya mendefinisikan @
sel kosong, sel \
"terlewatkan", danZ
menjadi bagian kapal)
Jika tidak ada penempatan seperti itu, program / fungsi harus kembali tanpa mengeluarkan apa pun.
Memasukkan
Jika Anda memutuskan untuk membuat program full-blown, terserah Anda menentukan bagaimana daftar tersebut diinput, beberapa mungkin melalui argumen, beberapa melalui stdin.
Ini adalah kode-golf , jumlah karakter terendah yang menang.
Contoh solusi dioptimalkan non-golf dapat ditemukan di sini
Kompilasi dengan -std=c99
, argumen pertama adalah ukuran papan, argumen lain adalah ukuran kapal. Daftar pemotretan yang dipisahkan baris baru diberikan pada stdin. Contoh:
./a 4 1 1 1 <<< $'A2\nA4\nB3\nC3\nC4\D4'
sumber
26x26
? Saya membuat sketsa solusi berdasarkan regexps dan rekursi, dan itu menjadi sangat lambat = tidak dapat digunakan untuk bidang lebih dari6x6
. Entah saya melakukan sesuatu yang sangat bodoh, atau kurangnya jawaban berarti bahwa orang lain juga tidak berhasil.10x10
yang4,3,2,1
dihitung secara instan setidaknya dengan shipetJawaban:
GolfScript, 236 karakter
Masukan diberikan pada STDIN. Baris pertama berisi ukuran dan jumlah kapal, masing-masing koordinat baris berikut dari satu tembakan.
Contoh:
Saya pikir juga tantangan ini harus memiliki setidaknya satu jawaban GolfScript. Pada akhirnya itu menjadi sangat ungolfscriptish karena algoritma yang digunakan yang mendukung kinerja lebih pendek.
Kode beranotasi:
sumber
SWI-Prolog,
536441 1 byte1 baris UNIX berakhir, baris baru akhir tidak dihitung
Versi dengan semua optimasi dihapus ( 441 bytes):
Karena kode diubah untuk meminimalkan jumlah byte, maka tidak akan lagi menerima daftar bidikan yang memiliki duplikat.
Versi dengan optimasi dasar, sepenuhnya golf ( 536 → 506 byte)
Saya menerapkan beberapa pemeriksaan dasar ( menghitung jumlah blok kapal yang diperlukan ) untuk membuat kode keluar lebih cepat untuk kasus yang jelas tidak mungkin. Kode itu juga kebal terhadap duplikat dalam daftar tembakan sejauh ini.
Di bawah ini adalah versi (agak) dapat dibaca, dengan komentar rinci:
Format pertanyaan:
Permintaan sampel (menggunakan sampel dalam pertanyaan):
sumber
Matlab - 536 karakter
Diperbarui: Pemformatan output yang jauh lebih kecil, beberapa spasi kosong dihapus.
Diperbarui: Menambahkan versi golf
Diperbarui: Menambahkan versi komentar, mengurangi versi golf dengan ~ 100 karakter
Ini adalah versi golfnya.
Ini beberapa contoh.
Garis besar dengan 'kron' (dekat bagian bawah kode un-golf) adalah bagian favorit saya dari ini. Ini menulis '1' untuk semua lokasi di peta yang berdekatan dengan posisi tertentu. Bisakah Anda melihat cara kerjanya? Ini menggunakan produk tensor kronecker, perkalian matriks, dan indeks peta sebagai array linier ...
sumber
Python, 464 karakter
Input (stdin):
Keluaran:
Bekerja menggunakan integer yang memegang bitmap dari berbagai fitur:
sumber
[::-1]
yang membuatnya mencoba kapal terpanjang pertama. Ia juga melakukan backtracks begitu menemukan sebuah kapal yang tidak dapat diletakkannya.Python, 562 karakter, -8 dengan output jelek, +4? untuk permohonan bash
Catatan: level inden adalah spasi, tab, tab + spasi, tab + tab, dan tab + tab + spasi. Ini menghemat beberapa karakter dari menggunakan spasi saja.
Penggunaan dan contoh :
Mengambil input dari argumen baris perintah. Output kosong sebagai spasi, tembakan sebagai
.
, dan@
sebagai bagian dari kapal:Saat tidak dapat dipecahkan, tidak mencetak apa pun:
The
2>X
adalah untuk menekan pesan kesalahan sejak keluar program dengan melemparkan pengecualian. Jangan ragu untuk menambahkan penalti +4 jika dianggap adil. Kalau tidak, aku harus melakukantry: ... except:0
untuk menekannya, yang akan memakan lebih banyak karakter.Saya juga bisa mencetak output sebagai angka (
0
,1
, dan2
) untuk mencukur 8 karakter, tapi saya nilai estetika.Penjelasan :
Saya mewakili papan sebagai daftar daftar bilangan bulat dengan ukuran 2 lebih besar dari input, untuk menghindari keharusan melakukan pengecekan batas.
0
mewakili ruang kosong,1
tembakan, dan2
kapal. Saya menjalankan daftar tembakanQ
dan menandai semua tembakan. Saya mengonversi daftar kapal menjadi daftar kapal yang eksplisitX
, misalnya[4, 0, 2, 0, 1]
menjadi[5, 3, 3, 1, 1, 1, 1]
. Maka itu adalah algoritma backtracking sederhana: dalam urutan urutan ukuran menurun, mencoba untuk menempatkan kapal, dan kemudian mencoba menempatkan sisa kapal. Jika tidak berhasil, coba slot berikutnya. Begitu berhasil, daftar kapalX
adalah nol, dan mengaksesX[0]
melempar pengecualian yang keluar dari program. Sisanya hanya golf berat (awalnya 1615 karakter).sumber
Perl,
455 447 437 436 422418Bertakuk:
Saya berharap ini dapat di-golf lebih lanjut (mis. Dengan
eval<>
input pra-format, seperti yang saya lihat tidak apa-apa (?)), Dan juga beberapa hal lainnya (50$
sigils? Tidak, mereka akan tinggal).Kecepatan, seperti yang saya katakan sebelumnya, bisa menjadi masalah (dari seketika (lihat contoh di bawah) hingga sangat-sangat lama), tergantung di mana solusinya adalah pada pohon rekursi, tetapi biarlah itu menjadi pertanyaan tentang keusangan perangkat keras yang digunakan. Saya akan melakukan versi yang dioptimalkan nanti, dengan rekursi hilang dan 2-3 trik lain yang jelas.
Dijalankan seperti ini, 3 baris diumpankan melalui STDIN:
~
adalah laut (solusi artistik, bukan),o
's danx
s adalah kapal dan tembakan. 5 baris pertama mendapatkan input dan menyiapkan 'medan perang' kami.$N
adalah size,@S
adalah array kapal yang tidak gulungan (mis.1 1 1 1 2 3 3 5
seperti di atas) ,, dan bercabang untuk iterasi berikutnya. Dan seterusnya.$f
adalah string yang mewakili medan perang (baris dengan baris baru digabungkan). Berikutnya adalah subrutin rekursif, yang mengharapkan status medan perang saat ini dan daftar kapal yang tersisa. Ia memeriksa dari kiri ke kanan, atas ke bawah dan mencoba menempatkan setiap kapal di setiap posisi, baik secara horizontal maupun vertikal (lihat? Matang untuk mengoptimalkan, tetapi itu nanti). Kapal horisontal adalah pengganti regexp yang jelas, vertikal sedikit rumit - manipulasi string bitwise untuk menggantikan dalam 'kolom'. Jika berhasil (H, V atau keduanya), posisi baru yang tidak dapat diakses ditandai dengan!
Sunting: Oke, inilah 594 bytes (ketika tidak diindentasikan) versi yang benar-benar mencoba untuk menjadi berguna (yaitu cepat) - dioptimalkan dengan kemampuan terbaik saya sambil tetap menerapkan teknik yang sama - rekursi (meskipun dilakukan 'secara manual') dan regexps. Itu memelihara 'tumpukan' -
@A
- Array negara yang layak diselidiki. 'Status' adalah 4 variabel: string medan perang saat ini, indeks dari mana mulai mencoba menempatkan kapal, referensi ke array kapal yang tersisa, dan indeks kapal berikutnya untuk mencoba. Awalnya ada satu 'negara' - mulai dari string kosong, semua kapal. Pada pertandingan (H atau V, lihat di atas), keadaan saat ini didorong untuk menyelidiki kemudian, keadaan yang diperbarui (dengan kapal ditempatkan dan posisi yang tidak dapat diakses ditandai) didorong dan blok dihidupkan ulang. Ketika akhir string medan perang tercapai tanpa hasil, keadaan selanjutnya yang tersedia dari@A
diselidiki (jika ada).Optimalisasi lainnya adalah: tidak memulai kembali dari awal string, mencoba menempatkan kapal besar terlebih dahulu, tidak memeriksa kapal dengan ukuran yang sama jika sebelumnya gagal dalam posisi yang sama, + mungkin sesuatu yang lain (seperti tidak ada
$&
variabel dll.)..
OTOH, masih perlu waktu lama untuk kasus yang mustahil seperti
6 5 4 3 2 1
contoh di atas. Mungkin versi praktis harus segera keluar jika total tonase kapal melebihi kapasitas medan perang.sumber
Solusi C #
sumber
size=1 ships={1} moves={"A1"}
,.Jawa, 1178
Ya terlalu lama ._.
Tidak Disatukan:
Sampel-Input
Sampel-Output
Dengan
O
tembakan meleset#
bagian kapal_
tembak di sini selanjutnya ;-)Lihat di ideone.com
Penanganan input mengharapkan spasi di sekitar angka /
;
dan tidak akan bekerja sebaliknya.Saya menempatkan kapal-kapal besar terlebih dahulu karena mereka memiliki lebih sedikit tempat untuk dikunjungi. Jika Anda ingin beralih ke yang kecil dulu Anda bisa mengganti
pop()
denganremove(0)
danpush(s)
add(0,s)
bahkan dengan mengganti hanya satu dari keduanya yang masih harus menghasilkan program yang valid.Jika Anda mengizinkan kapal saling menyentuh,
g(int,int)
fungsinya dapat sangat disederhanakan atau dihapus.sumber