Ini adalah sprint terakhir ... dan separuh tim Anda sakit. Anda bekerja lembur, hanya membuat komitmen terakhir untuk hari itu, menanti-nanti ... mengapa lampu dimatikan? Saya tidak ingat petugas keamanan datang ... oh tidak! Saya meninggalkan kunci saya di rumah!
Ketika kengerian situasi mulai meresap, Anda memutuskan bahwa Anda akan melarikan diri .
Ringkasan Tugas
Untuk melakukan pelarian Anda, Anda perlu rencana! Namun, Anda tahu bahwa rencana apa pun memiliki kemungkinan gagal, dan rencana yang berbeda membutuhkan upaya yang berbeda.
Karena lapar, lelah, dan seorang insinyur, Anda memutuskan untuk menulis sebuah program singkat untuk menentukan cara terbaik untuk melarikan diri dari kompleks, menyeimbangkan kekhawatiran tentang kemungkinan keberhasilan dan upaya yang diperlukan.
Anda membuat peta bangunan:
#######################
# = #
! = ! <-- window
# ! = # (freedom!)
#################= #
# # = #
# # = #
# # = #
# o ! # # ! = #
##| ! ## # ! = #
#######################
^ ^ ^
me my door ludicrously high shelves
(locked) (climbable)
Untuk keluar dari kantor, Anda harus memindahkan diri dari peta. Di sini Anda melihat ada 2 jendela ( !
), salah satunya akan mengarahkan Anda ke kebebasan, tetapi hanya satu yang dapat diakses. Kami mendefinisikan 'off the map' sebagai memiliki kaki Anda di luar batas peta
Jenis sel
- empty, you can be here (i.e. the escapee can consume this cell)
# - solid (your desk, your in-tray), you can't be here, but you can stand on it
! - destructible, (co-worker's desk, door, window), you can't be here until you smash it first (turning it into an empty cell)
= - climbable, (fire ladder, filing cabinet, etc.), you can be here
Sel-sel yang semula dikonsumsi oleh pelarian dianggap kosong.
Spesifikasi Tindakan
Anda memiliki sejumlah tindakan yang memungkinkan di disposable Anda. Ini didefinisikan oleh transisi keadaan sederhana dengan beberapa probabilitas keberhasilan integer. Misalnya, untuk berjalan, Anda memindahkan sel satu pelarian, yang kami wakili dengan transisi ini:
Langkah
1 stp, 100%, mirror
o. o
|. --> |
# #
Titik-titik menunjukkan sel yang harus kosong (atau dapat dipanjat, tetapi tidak solid atau dapat dirusak) baik karena kita bergerak ke dalamnya atau melewatinya. 100% berarti Anda memiliki peluang 100% untuk tidak melukai diri sendiri dan mengakhiri pelarian Anda yang berani. Semua probabilitas adalah persentase bilangan bulat antara 1% dan 100% inklusif. Diagram pertama menunjukkan keadaan awal (berdiri di atas sesuatu yang kokoh, berdiri di sebelah ruang kosong). Diagram kedua menunjukkan status terminal (dipindahkan ke ruang kosong). Tidak ada persyaratan untuk setiap sel yang tidak ditentukan (spasi, ) di sebelah kiri (keadaan awal) untuk menjadi sesuatu yang khusus. Sel yang tidak ditentukan (spasi,
) di sebelah kanan (keadaan terminal) harus sama dengan sebelumnya (mis. apa pun yang ada di belakang pelarian, atau apa pun yang kebetulan saya jalani (baik itu ruang kosong atau lainnya). Perhatikan bahwa semua tangan kanan (keadaan terminal) ) diagram hanya akan mengubah sel dari yang dapat dirusak menjadi kosong, tidak ada perubahan lain yang dapat terjadi. "1 stp" berarti biayanya 1 stp: kami mendefinisikan "stp" sebagai jumlah energi yang diperlukan untuk mengambil langkah.
"Cermin" berarti tindakan ini memiliki dua bentuk. Tindakan "kanan" ditampilkan, tindakan "kiri" adalah cermin yang tepat, misalnya:
.o
.|
#
adalah bentuk cermin (Kiri) dari
o.
|.
#
Tindakan yang tepat disebut "Kanan" (mis. "Langkah Kanan") Tindakan kiri disebut "Kiri" (misalnya "Langkah Kiri")
Dalam diagram ini, pelarian ditunjukkan oleh
o
|
ketika berdiri (tinggi 2 unit) dan
%
saat berjongkok (tinggi 1 unit). Sel yang harus padat atau dapat dirusak ditunjukkan dengan hash #
,. Sel yang tidak boleh padat atau dapat dirusak ditunjukkan oleh sebuah titik .
. Sel-sel yang harus dirusak ditandai dengan ledakan !
. Ruang kosong yang baru dibuat ditunjukkan oleh garis bawah _
.
x
adalah titik referensi yang tidak bergerak (tidak ada, tidak ada batasan pada apa sel itu harus (seperti spasi )).
Catatan: kami mengabaikan masalah perlambatan cepat saat Anda menyentuh lantai, dan ya, dalam game ini Anda dapat melakukan lompatan yang sangat epik ke tangga)
Langkah
1 stp, 100%, mirror
o. o
|. --> |
x# x#
Turun
1 stp, 100%, mirror
= =
o. --> o
|. |
x= x=
Acak
3 stp, 100%, mirror
%. %
x# --> x#
Naik
10 stp, 95%, cermin
o. %
|# --> #
x# x#
Penurunan
0 stp, 100%
o
| --> o
x. x|
Jatuhkan (Berdiri)
0 stp, 100%
% o
x. --> x|
Memanjat
2 stp, 100%
= o
o --> |
x| x
Mendekam
2 stp, 100%
o
| --> %
x# x#
Berdiri
4 stp, 100%
. o
% --> |
x# x#
Lompat Pendek
4 stp, 95%, cermin
o.. o
|.. --> |
x# x#
Lompat jauh
7 stp, 75%, cermin
o... o
|... --> |
x# x#
Loncat tinggi
12 stp, 90%, cermin
.. o
o. --> |
|
x# x#
Masukkan kembali Anda ke dalamnya!
20 stp, 80%, cermin
o!. _o
|!. --> _|
x# x#
Meninju
8 stp, 90%, cermin
o! o_
| --> |
x# x#
Tendangan
8 stp, 85%, cermin
o o
|! --> |_
x# x#
Stempel
8 stp, 90%
o o
| --> |
x! x_
Rencana
Rencana adalah urutan tindakan yang didefinisikan di atas. Sebagai contoh:
Step Left
High Jump Left
Crouch
Shuffle Left
Shuffle Left
Stand
Long Jump Left
Put your back into it! Left
Step Left
Perhatikan dimasukkannya tetes. Aturan harus ditetapkan untuk menghentikan Anda melakukan apa pun selain menjatuhkan, tetapi Anda masih harus merencanakannya!
Setiap rencana memiliki upaya yang diperlukan, yang merupakan jumlah dari upaya untuk setiap langkah. Ada juga probabilitas keberhasilan, yang merupakan produk dari probabilitas keberhasilan setiap tindakan. Contoh sederhana:
Step Right: 1stp, 100%
Long Jump Right: 7stp, 75%
Step Right: 1stp, 100%
Stamp: 8stp, 90%
Drop: 0stp, 100%
Drop: 0stp, 100%
Drop: 0stp, 100%
Drop: 0stp, 100%
Step Left: 1stp, 100%
Step Left: 1stp, 100%
High Jump Left: 12stp, 90%
Effort = 1+7+1+8+1+1+12 = 31
Success Probability = 75%*90*90% = 60.75%
'Contoh yang dikerjakan' untuk peta di bagian atas halaman dapat ditemukan sebagai intisari .
Memasukkan
Input datang dalam dua bagian, integer, dan array atau serangkaian karakter.
Integer adalah probabilitas keberhasilan minimum yang dapat Anda terima (persen). Itu harus ditafsirkan sebagai persentase, jadi 80 berarti rencana Anda harus berhasil dengan probabilitas tidak kurang dari 80%.
Peta yang valid adalah persegi panjang yang mencakup pelarian berdiri (ukuran minimum 1x2) dan tidak ada simbol yang tidak ditentukan. Semua baris akan memiliki panjang yang sama. Anda dapat menerima input sebagai string berdimensi 1 dimensi (pembatas harus karakter tunggal yang konsisten, atau salah satu pasangan CRLF dan LFCR), sebagai larik 1 dimensi yang serupa, atau larik 2 dimensi. Jika format input yang Anda pilih tidak menunjukkan lebar atau tinggi peta dalam beberapa cara, Anda dapat menerima argumen tambahan untuk ini (Anda harus menyatakan ini dengan jelas dalam jawaban Anda). Anda dapat mencampur argumen baris perintah dan input standar jika cocok untuk Anda (misalnya memetakan dari stdin, probabilitas keberhasilan minimum dari argv). Berikut ini adalah contoh peta yang valid dan tidak valid.
Sah:
o
|
Sah:
# #
! o #
! | #
#########
Tidak valid (tidak ada pelarian):
# #
! #
! #
#########
Tidak valid (pelarian selalu mulai berdiri):
# #
! #
! % #
#########
Tidak valid (simbol tidak valid):
# #
! ~ #
! #
#########
Tidak valid (bukan persegi panjang / baris panjang berbeda):
# #
! o #
! | #
#########
Anda dapat menganggap input Anda valid (Saya tidak peduli apa yang program Anda lakukan jika input yang diberikan salah).
Keluaran
Output adalah teks (ASCII). Dapat dikembalikan sebagai string, atau dicetak ke output standar. Rencana tersebut harus dibatasi oleh LF, CRLF, atau LFCR. Demikian pula, harus ada LF, CRLF, atau LFCR lain setelah Upaya yang Diperlukan. Istirahat garis trailing adalah opsional.
Anda harus mengeluarkan rencana optimal bersama dengan upaya yang diperlukan, atau "Tidak ada harapan!" jika tidak ada rencana seperti itu. Anda tidak perlu menampilkan probabilitas keberhasilan. Teks ini mungkin atau tidak memiliki trailing line break.
Rencana optimal didefinisikan sebagai rencana (lihat di atas) yang membutuhkan upaya minimum dengan setidaknya probabilitas keberhasilan yang diberikan. Perhatikan bahwa perhitungan probabilitas Anda harus tepat, Anda mungkin tidak menganggap bahwa floating point cukup baik (Inilah sebabnya saya tidak mengharapkan Anda untuk memproduksinya). Saya akan mencoba merancang kasus uji untuk menguji secara adil ini (jika Anda lulus dan tidak membuat asumsi bodoh maka Anda dapat menganggap kiriman Anda valid).
Format:
Required Effort: <effort>
<plan>
Misalnya untuk input
50
# #
! o #
! | #
#########
Output yang sesuai adalah:
Required Effort: 23
Step Left
Step Left
Step Left
Kick Left
Punch Left
Step Left
Step Left
Step Left
Step Left
Peluang sukses di sini adalah 76,5%.
Untuk peta yang sama, tetapi probabilitas keberhasilan minimum 80%, Anda harus "Masukkan kembali ke dalamnya", yang akan membutuhkan lebih banyak usaha tetapi memenuhi kriteria probabilitas keberhasilan. Jika probabilitas keberhasilan minimum lebih besar dari 80%, Anda harus berpikir sedikit lebih keras (baik meninju atau menendang bagian pintu dan keluar). Jika probabilitas keberhasilan minimum adalah 100%, Anda harus mencetak "Tidak ada harapan!"
Contohnya
Ada kemungkinan bahwa ada lebih dari satu rencana yang valid untuk input, output Anda tidak harus persis seperti ini, tetapi harus memiliki upaya yang diperlukan yang benar, dan menjadi rencana yang valid. Anda dapat menggunakan verifikasi untuk memeriksa solusi Anda (lihat di bawah)
Memasukkan:
100
o
|
Keluaran:
Required Effort: 0
Drop
Memasukkan:
5
# = #
# = !
# = ! ! !
# =#######
# = #
# = o #
# = ! | #
##########
Keluaran:
Required Effort: 57
Step Left
Kick Left
Step Left
Step Left
Step Left
Climb Up
Climb Up
Climb Up
Climb Up
Climb off Right
High Jump Right
Long Jump Right
Step Right
Drop
Kick Right
Crouch
Shuffle Right
Shuffle Right
Memasukkan:
60
#########
# ! # #
! ! ! o #
! # ! | #
#########
Keluaran:
Required Effort: 58
Step Left
Kick Left
Crouch
Shuffle Left
Shuffle Left
Stand
Punch Left
Clamber Up Left
Shuffle Left
Drop (Stand)
Kick Left
Crouch
Shuffle Left
Shuffle Left
Untuk peta yang sama, tetapi 80%, hasilnya harus:
There is no hope!
Untuk peta yang sama, tetapi 50%, upaya yang diperlukan menjadi 56 dengan rencana yang berbeda)
Memasukkan:
50
#######################
# # = #
! # = !
# # = #
###### #####!## =### #
#= ## # = #
#=############# = #
#= = #
#= o = #
#!!| = #
#######################
Keluaran:
Required Effort: 121
Step Right
Step Right
Step Right
Step Right
Step Right
Step Right
Step Right
Step Right
Step Right
Step Right
Step Right
Step Right
Step Right
Step Right
Climb Up
Climb Up
Climb Up
Climb Up
Climb Up
Climb Up
Climb off Right
Long Jump Left
Step Left
Step Left
Stamp
Drop
Drop
Crouch
Shuffle Left
Shuffle Left
Shuffle Left
Shuffle Left
Shuffle Left
Shuffle Left
Stand
Clamber Up Left
Stand
Clamber Up Left
Stand
Step Left
Step Left
Step Left
Step Left
Punch Left
Clamber Up Left
Shuffle Left
Memasukkan:
66
######
# ###
#o ! !
#| ! !
### ##
######
Keluaran:
Required Effort: 37
Step Right
Put your back into it! Right
Kick Right
Crouch
Shuffle Right
Shuffle Right
Memasukkan:
Yang ini dirancang untuk memeriksa sejumlah asumsi salah yang mungkin menjadi korban, dan akibatnya mungkin terlihat agak aneh
30
###################
# ## # # # # = #
! ## # # # = #
# # # = #
## ############= #
# ## # #= #
# = # #= #
! = # #= #
# = # #= #
#o= ! ==#
#|= ! =#
#!= # ==########==#
# # ! !! =#
# # !! ! = #
# # !!!!#########
# # # #
# # # #
###################
Keluaran dengan peluang kendala keberhasilan 30:
Required Effort: 199
Long Jump Right
Put your back into it! Right
<snip>
Output dengan peluang kendala kesuksesan 32:
Required Effort: 200
Long Jump Right
Punch Right
<snip>
Dengan menggunakan peta di bagian atas sebagai input, dengan probabilitas kendala keberhasilan 1%, Anda harus mendapatkan Upaya yang Diperlukan sebesar 116 (peluang keberhasilan ~ 32%, ini membutuhkan waktu sekitar 20 detik untuk dijalankan dalam program pengujian saya).
Kriteria Kemenangan
Ini kode-golf, semoga kode terpendek menang.
Agar memenuhi syarat, fungsi atau program Anda harus bekerja dan dapat menyelesaikan masing-masing testcases di atas dalam waktu kurang dari 30 menit dengan mesin yang masuk akal. Solver saya melakukannya masing-masing dalam waktu kurang dari 30 detik. Jika skrip uji (di bawah) berjalan dalam waktu kurang dari 30 menit, Anda pasti senang.
Contoh Solver, Verifier, Test Script, dan TestCases (dengan solusi)
Kode C # untuk solver, dan verifier solusi, tersedia di sini sebagai intisari . Inti juga berisi file.txt
, yang merupakan bentuk tindakan yang dapat dibaca (cukup) dari mesin yang dijelaskan di atas, dan diperlukan untuk menjalankan program. Perbedaan apa pun antara file dan spek itu tidak disengaja.
Inti juga berisi sejumlah kasus uji (termasuk semua contoh di atas), dan skrip PowerShell untuk secara otomatis menjalankan pengajuan terhadap mereka. Jika skrip memberi tahu Anda bahwa tes tertentu gagal, Anda dapat berlari OfficeEscapeSolver.exe testcase<n>.txt outputFromYourProgram.txt
untuk melihat detail lebih lanjut. Contoh solusi untuk kasus uji ini adalah di Intisari lain .
Semua kode adalah kekacauan lengkap (meskipun tidak diubah), tetapi Anda tidak perlu menyimpang jauh dari static void Main(...)
untuk mengubah jumlah output (jangan ragu untuk menggunakan informasi ini, saya telah menyediakannya untuk keuntungan Anda!).
Melewati uji kasus tidak harus berarti bahwa output Anda terbentuk dengan baik, karena skrip dan verifikator sangat murah hati. Output Anda harus sesuai dengan spesifikasi di atas agar kiriman Anda valid.
Jika Anda merasa telah menemukan bug dengan solver atau script tes, ada kesalahan dalam file.txt
, atau testcase cerdik, maka silakan komentar pada posting ini atau ping saya di SE Chat; Saya mungkin tidak akan memperhatikan upaya komunikasi lainnya.
Saya tidak akan memberikan skrip uji dalam Bash atau Batch, karena saya tidak mengetahuinya, tapi saya senang memasukkan terjemahan dan akan menulis versi C # jika orang menginginkannya.
Poskan Amble
Punya pertanyaan? Jangan tunda, tanyakan kepada mereka hari ini!
Tugas ini dimaksudkan untuk membutuhkan usaha , untuk memberikan pegolf serius sesuatu untuk menenggelamkan gigi mereka.
Terima kasih kepada ais523 untuk umpan baliknya pada Input / Output.
Saya dapat memberikan lebih banyak testcases dalam file inti jika orang menginginkan lebih (tidak ingin posting ini menjadi lebih lama), atau ingin memberikan sebagian dari mereka sendiri.
sumber
Jawaban:
Perl 5,
142514641481146914851438 byteItu tantangan yang menyenangkan! Dan, yang mengejutkan, sepertinya saya memiliki kode terpendek sejauh ini dengan sedikit di bawah 1.5kB! :)
Cukup yakin saya akhirnya berhasil. Pembatas yang digunakan adalah
:
, dan ada bantalan ekstra dari dua baris di atas dan satu kolom di kedua sisi. Jadi untuk masukan Anda dari:program saya akan mengambil: (NB: harus ada titik dua di akhir, tetapi tidak di awal!)
Saya menggunakan regex untuk menerjemahkan dari satu peta ke peta lain dan menyelesaikannya dengan kekerasan. Namun, saya tidak menambahkan peta ke daftar jika peta itu telah dicapai dengan sedikit usaha dan probabilitas lebih besar atau sama. Peta dihapus dari daftar setelah semua gerakan yang mungkin dari titik itu telah habis. Program berakhir dengan sukses ketika cocok dengan regex yang menunjukkan saya telah mencapai sisi atau bawah dan berakhir dengan "Tidak ada harapan!" ketika daftar peta habis.
Sayangnya, ada banyak efisiensi yang diperdagangkan untuk melepas beberapa byte, sehingga versi golfnya agak lambat;) Perl tampaknya menemukan eval khususnya sangat menyakitkan.
Tanpa kata perpisahan lebih lanjut,
Demi kewarasan, ada hal yang sama dengan baris baru dan beberapa komentar:
Saya sudah dapat melihat beberapa tempat untuk menghilangkan beberapa byte lagi, tetapi saya belum ingin menjalani semua pengujian lagi. Kemudian! :)
Sunting: Menambahkan beberapa padding di bawah ini juga agar sesuai dengan output Anda lebih tepatnya ketika melarikan diri melalui lantai. Menghapus beberapa evals, sehingga kodenya mungkin berjalan lebih cepat sekarang juga!
Sunting: Tidak menangani tangga dan jatuh dengan benar. Masih tidak menangani tangga dengan benar ... Mencoba memperbaikinya sekarang.
sumber
C #,
181414811395 byteBetapa kerasnya !! Saya benar-benar senang dengan ini sekarang!
Cobalah secara Online
Program yang lengkap, mengambil input ke STDIN, output ke STDOUT. Pada dasarnya menulis ulang pemecah asli saya, menggunakan BFS sederhana dan tidak efisien diimplementasikan untuk menemukan jalur yang optimal. Ini cukup cepat, tidak bisa jauh lebih lambat daripada implementasi saya yang lain (saya belum benar-benar menghitung waktunya), tentu berjalan dalam batas waktu. Sebagian besar biaya adalah tabel Tindakan, yang dikodekan sebagai nilai terpisah koma yang mencatat nama, peta 'cocok / hancurkan', dan properti lainnya dari setiap tindakan yang tersedia.
Dimulai dengan membaca dalam probabilitas minimum keberhasilan dan peta. Kemudian itu menemukan pelarian, menghapusnya dari peta, dan membuat 'kondisi pencarian' yang mengandung informasi ini. Kemudian, ia melakukan BFS, yang berulang kali melihat status jatuh tempo berikutnya dengan sedikit usaha (memastikan ia menemukan solusi optimal). Sebelum memperluas node, ia membandingkan upaya dan probabilitas keberhasilannya dengan node sebelumnya dengan peta yang sama dan lokasi pelarian, dan menolaknya sendiri jika sudah ditemukan rute yang lebih baik untuk keadaan ini. Jika itu bertahan, ini menambahkan dirinya ke tabel 'terlihat' sehingga ia bisa menolak status nanti. Ini semua untuk kinerja, dan tanpa itu faktor percabangan akan sangat besar. Kemudian memeriksa apakah pelarian dari peta. Jika ya, maka ia menang! Ini melacak kembali keadaan (setiap keadaan sebelumnya direkam dengan masing-masing negara) dan membangun rencana (secara terbalik) sebelum keluar dari loop BFS. Kalau tidak, ia mencoba menerapkan setiap tindakan, dan menambahkan apa pun yang dapat diterapkan ke
due
antrian, sebelum menyortir antrian ini sehingga kita mendapatkan usaha yang paling tidak menyatakan iterasi berikutnya.Kode yang diformat dan dikomentari:
sumber