Bisakah saya tinggal di sini?

16

Dalam permainan Terraria , salah satu mekanik permainan melibatkan pembangunan rumah sehingga NPC dapat bergerak. Ada seperangkat aturan ketat untuk apa yang dianggap sebagai rumah yang valid atau tidak. Berikut daftar aturannya:

  1. Total area di rumah harus setidaknya 60 ubin persegi, tetapi kurang dari 750. Selain itu, ukuran rumah termasuk kerangka luar harus setidaknya salah satu dari ini:

    5x12
    6x10
    7x9
    8x8
    9x7
    10x6
    12x5
    15x4
    

    Demi kesederhanaan, Anda dapat dengan aman berasumsi bahwa: a) Semua rumah input akan berbentuk persegi panjang, dan b) tidak ada ubin padat #di dalam rumah. Berikut ini adalah bingkai 12x6 kami (digambar dalam ASCII yang indah):

    ############
    #          #
    #          #
    #          #
    #          #
    ############
    
  2. Rumah harus ditutupi dengan dinding latar belakang. Ini bukan ubin padat, melainkan dinding di belakang rumah di dimensi ketiga. Lubang diizinkan, tetapi tidak ada lubang yang bisa lebih besar dari 4x4. Jika ada baris atau kolom dengan 5 atau lebih karakter spasi dalam satu baris, ini adalah lubang yang lebih besar dari 4x4, dan rumah tidak valid. Banyak lubang juga diperbolehkan, tetapi harus ada setidaknya satu dinding yang terpisah.

    ############
    #**********#
    #**********#
    #**********#
    #**********#
    ############
    
    ############
    #*    *    #
    #*    *    #
    #*    *    #
    #******    #
    ############  (Still acceptable since neither hole is larger than 4x4 and there is a separator)
    
    ############
    #    ******#
    #***    ***#
    #    ******#
    #***    ***#
    ############  (Also still valid. No row or column of blank spaces is longer or taller than 4.)
    
  3. Harus ada jalan masuk. Ini bisa berupa pintu |di sisi atau platform- di lantai atau langit-langit. Jika satu-satunya pintu masuk berada di sudut, NPC tidak dapat masuk. Juga, jika Anda memiliki platform sebagai lantai, Anda harus memiliki setidaknya satu blok solid untuk berdiri di atas NPC. Blok padat ini tidak dapat berbatasan langsung dengan dinding samping di kiri atau kanan. Ini semua adalah rumah yang valid dengan pintu masuk:

    ############
    #**********#
    |**********#
    #**********#
    #**********|
    ############  (Multiple doors, or doors up high are okay)
    
    ############
    #**********#
    #**********#
    #**********#
    #**********#
    #######----#
    
    #----#######
    #**********#
    #**********#
    #**********#
    #**********#
    ############
    
  4. Setidaknya harus ada satu sumber cahaya $ , meja Tdan kursi C, meskipun lebih banyak diizinkan. Sumber cahaya bisa di udara atau di tanah, tetapi meja dan kursi keduanya harus di tanah, misalnya di baris terendah.

    ############
    #**********#
    #**********#
    #***$******|
    #****TC****|
    ############
    

    Juga, Anda dapat mengasumsikan bahwa ada dinding di belakang furnitur apa pun, sehingga obor, kursi atau meja dapat dianggap sebagai pemisah antara dua lubang.

    ############
    #*    *    #
    #*    *    #
    #*    $    #
    #**TC******|
    ############
    

Tantangan

Anda harus menulis fungsi terpendek yang mengambil rumah sebagai string ASCII, dan mengembalikan true / false apakah itu perumahan yang valid atau tidak. Anda dapat menganggap ini sebagai string terbatas baris baru, daftar string, atau cara lain selama itu masuk akal. Demi saya, harap sertakan program singkat sehingga saya dapat menguji apakah itu berfungsi dengan benar atau tidak.

Untuk referensi, ini semua input yang tidak valid:

############
-**********#
-****$*****#
-**********#
-******TC**#
############  (You can't have platforms on the sidewalls)

###########-
#**********#
#**********#
#****$*****#
#**T***C***#
###########|  (NPC can't enter because the only entrances are on the corner)

############
#**********#
#******$***#
#**********#
#T****C****#
##--------##  (NPC has nowhere to stand)

############
#**********#
#**********#
#**********#
#**$**TC***#
##########|#  (Door cannot be in the floor or ceiling)

############
#**********#
#**********#
#**********#
|**   T C  #
############  (Since table and chair do not count as a background wall, the hole in background is too wide)

####### ####
#**********#
#**********#
#****$*****#
#**T***C***|
############  (There's a hole in the frame.)


###########################################################################
#                                                                         #
#                                                                         #
#                                                                         #
#                                                                         #
#                                                                         #
#                                                                         #
#                                                                         #
#                                                                         #
#                                                                         #
###########################################################################  (House is 75x11, which is too big.)

Papan peringkat

DJMcMayhem
sumber
6
Tantangan keren, sesama pecinta Terraria.
Rɪᴋᴇʀ
Bisakah kita mengasumsikan bahwa lubang akan berbentuk persegi panjang? Kalau tidak, ini bisa menggunakan test case di mana keseluruhan tidak muat di 4x4 tetapi yang tidak pernah mengandung lebih dari 4 spasi berturut-turut.
Martin Ender
Ada banyak poin yang saya temukan tidak jelas. 1. Apakah bingkai harus persegi panjang? " semua rumah akan menjadi persegi panjang " menunjukkan bahwa mereka melakukannya, tetapi tidak secara jelas mengesampingkan bingkai yang bukan persegi panjang tetapi masuk ke keempat sudut kotak pembatas sumbu-selaras mereka. Dan mungkin lubang bisa dikelilingi oleh #. 2. Seperti yang Martin tanyakan, apa sebenarnya arti " tidak ada lubang yang lebih besar dari 4x4 "? (Perhatikan juga bahwa baru kali ketiga saya membaca-ulang saya yakin memahami apa lubangnya. Anda harus menulis spesifikasi untuk orang-orang yang belum memainkan permainan).
Peter Taylor
1
3. " Blok padat ini tidak dapat berbatasan langsung dengan dinding " - apa itu dinding? Dari poin 2 tampaknya *, tetapi itu akan mengecualikan contoh pintu valid yang diberikan. 4. Apakah " di tanah " berarti "di baris kedua dari belakang" atau "di atas a #"? 5. " Ini tidak berlaku untuk meja dan kursi. " Jadi apakah itu berarti bahwa lubang 4x4 dengan Tatau Clangsung di bawahnya terlalu besar? 6. " NPC tidak bisa masuk karena satu-satunya pintu masuk ada di sudut " Saya tidak berpikir spek mengatakan apa-apa tentang sudut. Mungkin mereka ada -atau |jika ada pintu lain?
Peter Taylor
7. Jika pintu masuk di sudut adalah masalah karena mereka tidak mengakui akses, apakah itu berarti masing-masing *harus dapat dijangkau dari pintu masuk? Atau diisolasi *di tengah lubang diizinkan, lubang yang memotong seluruh ruangan menjadi dua dengan hanya satu sisi yang memiliki pintu masuk diizinkan, dan pintu masuk yang langsung masuk ke lubang diizinkan?
Peter Taylor

Jawaban:

2

Python 2, 503 439 byte

Bukan super pendek, tapi itu solusinya. Beri tahu saya jika Anda melihat sesuatu tentang golf. Saya akan merekomendasikan untuk melihat versi saya yang belum di-serigala, karena sebenarnya bisa dibaca.

Sunting: Semua ifs di luar loop telah digabungkan di bagian bawah.

def f(s):
 s=s.split("\n");e=l=0;h=len(s);w=len(s[0])
 for c in s[0][1:-1]+s[-1][1:-1]:
    if(c in"#-")<1:return 0
    if"-"==c:e=1
 for r in s[1:-1]:
    if(r[0]in"#|")*(r[-1]in"#|")<1or" "*5in r:return 0
    if"$"in r:l=1
 for r in zip(*s):
    if" "*5in`r`[2::5]:return 0
 if(h*w<60)+(h*w>749)+(w<5)+(h<4)or" "in s[0][0]+s[0][-1]+s[-1][0]+s[-1][-1]or("T"in s[-2])*("C"in s[-2])*l<1or("#"in s[-1][2:-2])<1or"|"in"".join(s[1:-1])<1>e:return 0
 return 1

Cobalah online

Tidak Terkumpul:

Juga menampilkan alasan hasilnya False, untuk tujuan debugging.

def f(s):

    # check dimensions
    s=s.split("\n")
    h=len(s)
    w=len(s[0])
    if h*w < 60 or h*w > 749 or w<5 or h<4: return False,"Size"

    # top / bottom
    e=0
    for c in s[0][1:-1]+s[-1][1:-1]:
        if(c in"#-")<1:return False,"T/B"

        # entrance
        if"-"==c:e=1

    # no spaces in corners -_-
    if" "in s[0][0]+s[0][-1]+s[-1][0]+s[-1][-1]: return False,"Corner"

    # light, table, chair
    l=t=c=0

    # left / right
    for r in s[1:-1]:
        if(r[0]in"#|")*(r[-1]in"#|")<1: return False,"L/R"

        # walls, put above
        if" "*5in r: return False,"Walls"

        # light
        if"$"in r:l=1

    # table, chair
    if"T"in s[-2]:t=1
    if"C"in s[-2]:c=1

    if l*t*c<1: return False,"L/T/C"

    # wall columns
    for r in zip(*s): # Transpose
        if" "*5in`r`[2::5]: # Tuple to string
            return False,"Walls"

    # entrance
    if"|"in"".join(s[1:-1])<1>e: return False,"Entrance"

    # place to stand
    if("#"in s[-1][2:-2])<1: return False,"Stand"

    return True

Versi tidak online secara online

mbomb007
sumber