Apakah air akhirnya mencapai tangki?

30

Di dunia seni ASCII, ada air, dinding hash, dan mekanisme huruf.

Anda berada di sebuah ruangan yang terdiri dari dinding hash ( #tanda):

#######
#     #
#     #
#     #
# ### #
#     #
#######

Anda memasang sumber air S ( Standa) dan tangki air E ( Etanda) yang dapat menerima air dari segala arah, tetapi Anda hanya memiliki satu sumber S dan satu tangki E.

#######
#  S  #
#     #
#     #
# ### #
#  E  #
#######

Jadi, Anda harus memilih dengan bijak di mana menempatkan sumber. Di situlah Anda melakukan keterampilan .

Tugas

Anda mendapatkan input yang terdiri dari string yang mewakili ruangan dengan sumber dan tangki:

#######
#  S  #
#     #
#     #
# ### #
#  E  #
#######

Anda harus mencari tahu apakah air akhirnya mencapai tangki. Jika memungkinkan, air akan mengalir ke bawah, ke kiri dan ke kanan, jika mungkin. Airnya tidak menumpuk karena tidak naik.

Jadi, untuk input di atas, hasilnya adalah:

#######
#  *  #
#  *  #
#*****#
#*###*#
#**O**#
#######

Air dengan gembira mencapai tangki, jadi Anda harus menampilkan nilai yang benar.

Tetapi jika air tidak mencapai tangki:

#######
#S    #
#     #
#  E  #
# ### #
#     #
#######

#######
#*    #
#*    #
#* X  #
#*### #
#*****#
#######

Maka Anda harus menampilkan nilai palsu.

Tulis program untuk memutuskan apakah air pada akhirnya mencapai tangki. Kode Anda harus sesingkat mungkin.

Asumsi

  • Asumsikan bahwa input selalu valid (seluruh ruangan adalah wilayah persegi panjang tertutup dengan S dan E).

  • Asumsikan hanya ada satu kamar yang disediakan sebagai input.

Uji Kasus

Program Anda harus mengembalikan nilai kebenaran untuk kasus uji berikut:

#######
#  S  #
#     #
#     #
# ### #
#  E  #
#######

#######
#  S  #
#     #
#  E  #
#     #
#     #
#######

#######
#     #
#     #
# SE  #
# ### #
#     #
#######

###############################################
#                      S                      #
#                                             #
#                                             #
#                                             #
#               ###############               #
#                                             #
#  ##################     ##################  #
#                                             #
#                                             #
#                    #####                    #
#                      E                      #
###############################################

#######
#  S  #
#     #
#     #
# ### #
#   # #
### ###
## E ##
#     #
#######

Tetapi nilai palsu untuk kasus uji berikut:

#######
#S    #
#     #
#  E  #
# ### #
#     #
#######

#######
#     #
# SE  #
#     #
#     #
#     #
#######

#######
#     #
#  E  #
#     #
#  S  #
#     #
#######

####################################
#                                  #
#                                  #
#                                  #
#S             #                  E#
####################################

Kamar kedua hingga terakhir dalam kategori True dan kamar terakhir dalam kategori False dicuri tanpa dipinjam dari Koth: Jump and Run by Manu (yang menghapus posting sandbox).

Kamar terakhir dalam kategori True adalah dari jawaban Martin Buttner di Retina .

pengguna48538
sumber
Catatan: Saya menghapus posting sandbox KOTH saya, tantangan Anda terlihat jauh lebih baik :)
CommonGuy
Bukankah airnya menumpuk sampai memenuhi ruangan? Dengan demikian air selalu mencapai tangki jika dan hanya jika mereka berada di ruangan yang sama.
Bob
1
Kiat pro untuk memformat kasus uji dalam tantangan benar / salah (atau tantangan klasifikasi dengan beberapa kelas): kelompokkan kasus uji berdasarkan hasil dan pisahkan grup sehingga Anda dapat menghindari bit from / to/ benar-benar (yang memudahkan peserta untuk memproses semua tes kasus sekaligus).
Martin Ender
1
Jadi pada dasarnya logika aliran cairan Minecraft. Meskipun di Minecraft saya pikir yang ke-3 dalam kasus uji Anda yang sebenarnya akan kembali salah karena air hanya akan pergi ke sisi kiri.
Patrick Roberts
1
Mengingatkan saya pada fisika air pasir yang jatuh.
user253751

Jawaban:

15

Siput , 20 byte

\S{d(=\#n)?^#},!(t\E

Mencetak 0untuk nilai falsey dan 1untuk nilai sebenarnya.

Cobalah online!

  • \Scocok Sdi awal
  • d mengatur arah ke bawah
  • {...}, cocok dengan barang-barang di kawat gigi 0 atau lebih kali
  • =\#adalah penegasan yang berhasil jika ada #arang di depan siput, tetapi tidak menggerakkannya
  • n ternyata 90 derajat di kedua arah
  • (...)? cocok dengan pola dalam tanda kurung 0 atau 1 kali
  • \ ​ mencocokkan ruang dan menggerakkan siput ke atasnya
  • !(... adalah pernyataan negatif
  • t teleport ke sembarang kotak yang tak tertandingi di dalam kisi
  • \E cocok E
feersum
sumber
Saya tidak ingin mengkompilasi bahasa ini sendiri. Apakah ada penerjemah online untuk ini?
user48538
@ zyabin101 Tidak, tidak ada juru bahasa online.
feersum
Oke, saatnya menelepon Dennis. : P Di mana proyektor saya?
user48538
5
i.imgur.com/dvWrAwP.png Saya membuatnya sendiri.
user48538
Yah, saya sudah mencoba , tetapi mencetak 0 untuk semua kasus uji tetapi satu untuk saya. Apa yang saya lakukan salah?
Dennis
11

Tergelincir , 20 + 2 = 22 byte

S>( ^4|^4(?|`#)^T)*E

Jadi Slip masih rusak seperti biasa, tetapi untuk sekali ini adalah tantangan yang sebenarnya bisa dilakukan. Itu tidak pernah benar-benar dirancang untuk menjadi golf, jadi itu tidak akan pernah mengalahkan Siput apa pun: P

Membutuhkan rtanda (tidak ada sel berulang) untuk mengakhiri.

Cobalah online . Keluaran adalah jalan yang diambil untuk kebenaran, kosong untuk kepalsuan.

S                 Match S
>                 Rotate pointer downward
(                 Either...
 <space>^4          Match a space and point downwards
 |                  or
 ^4                 Point downwards
 (?|`#)             Match # below then reset pointer
 ^T                 Either turn left or right
)*                ... 0+ times
E                 Match E
Sp3000
sumber
6

Retina , 87 byte

Hitungan byte mengasumsikan penyandian ISO 8859-1.

+mT`E `S`(?<=^(?(1)!)(?<-1>.)*S.*¶(.)*)[E ]|.?S(?=(.)*¶.*#(?<-2>.)*(?(2)!)$)[E ]?
M`E
0

Cobalah online!

Sebanyak pemrosesan string 2D dimungkinkan pada Retina (atau .NET regex secara umum), ini tidak sepenuhnya ringkas ...

Penjelasan

+mT`E `S`(?<=^(?(1)!)(?<-1>.)*S.*¶(.)*)[E ]|.?S(?=(.)*¶.*#(?<-2>.)*(?(2)!)$)[E ]?

Ini adalah genangan-banjir yang menandai semua sel dengan air S. Ia melakukannya dengan mencocokkan karakter yang dapat dijangkau dan kemudian mentransliterasinya ke Sdengan T-mode. Isi banjir ini melewati kedua ruang dan E. Di +awal mengulangi ini sampai output berhenti berubah.

Adapun regex yang sebenarnya berisi dua kasus terpisah:

(?<=^(?(1)!)(?<-1>.)*S.*¶(.)*)[E ]

Ini cocok dengan spasi atau Eyang persis satu sel di bawah S. Pencocokan vertikal dilakukan dengan menghitung awalan pada garis saat ini menggunakan kelompok penyeimbang sehingga kami dapat memastikan bahwa posisi horizontal sama. Yang ini merawat air yang jatuh.

.?S(?=(.)*¶.*#(?<-2>.)*(?(2)!)$)[E ]?

Ini sangat mirip: cocok dengan Sdan jika tersedia karakter sebelum dan sesudahnya, asalkan karakter langsung di bawah Sadalah a #. Ini menangani penyebaran air di sepanjang tanah.

Ketika kita selesai, sangat mudah untuk menentukan apakah airnya mencapai E. Jika ya, maka Etelah dihapus dari string di banjir-fill, dan jika tidak Emasih ada. Jadi mari kita hitung jumlah Es:

M`E

Tapi sekarang itu 0(yang saya anggap palsu) untuk kasus uji kebenaran dan 1(yang saya anggap benar) untuk kasus uji palsu. Kami dapat membalikkan ini dengan sangat mudah dengan menghitung jumlah 0s dalam hasil ini:

0

Selesai

Martin Ender
sumber
Menambahkan input Anda sebagai test case.
user48538