Чи можу я тут жити?


16

У грі Terraria одна з ігрових механіків передбачає будівництво будинків, щоб NPC міг переїхати. Існує суворий набір правил щодо того, що вважається дійсним будинком чи ні. Ось перелік правил:

  1. Загальна площа будинку повинна бути не менше 60 квадратних плиток, але менше 750. Також розмір будинку, включаючи зовнішній каркас, повинен бути хоча б одним із таких:

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

    для простоти можна сміливо припускати, що: а) всі будинки, що вводяться, будуть прямокутниками; б) жодна суцільна плитка #не буде всередині будинку. Ось наш кадр розміром 12x6 (намальований красивим ASCII):

    ############
    #          #
    #          #
    #          #
    #          #
    ############
    
  2. Будинок повинен бути покритий фоновими стінами. Це не суцільна плитка, а швидше стіна за будинком у третьому вимірі. Допускаються отвори, але жодні отвори не можуть бути більше 4х4. Якщо в рядку є рядок або стовпець із 5 або більше символів пробілу, це отвір, більший за 4x4, і будинок недійсний. Допускається також декілька отворів, але одна з них повинна бути принаймні одна стіна.

    ############
    #**********#
    #**********#
    #**********#
    #**********#
    ############
    
    ############
    #*    *    #
    #*    *    #
    #*    *    #
    #******    #
    ############  (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. Має бути вхід. Це можуть бути двері |з боків або майданчик -на підлозі або стелі. Якщо єдиний вхід знаходиться на розі, NPC не може увійти. Крім того, якщо у вас є майданчик як підлога, у вас повинен бути принаймні один міцний блок, щоб NPC стояв. Цей суцільний блок не може бути безпосередньо поруч із бічними стінками зліва чи справа. Це всі дійсні будинки з входами:

    ############
    #**********#
    |**********#
    #**********#
    #**********|
    ############  (Multiple doors, or doors up high are okay)
    
    ############
    #**********#
    #**********#
    #**********#
    #**********#
    #######----#
    
    #----#######
    #**********#
    #**********#
    #**********#
    #**********#
    ############
    
  4. Повинно бути принаймні одне джерело світла $, стіл Tі стілець C, хоча дозволено більше. Джерело світла може знаходитися в повітрі або на землі, але стіл і стілець повинні бути на землі, наприклад, у нижньому ряду.

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

    Також можна припустити, що за будь-якими меблями стоїть стіна, тому факел, стілець або стіл можна вважати роздільником між двома отворами.

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

Змагання

Ви повинні записати найкоротшу функцію, яка приймає будинок як рядок ASCII та повертає true / false незалежно від того, чи це дійсний корпус чи ні. Ви можете сприймати це як рядки з обмеженою новою лінією, список рядків або будь-яким іншим способом, наскільки це розумно. Заради мене, будь ласка, включіть коротку програму, щоб я міг перевірити, працює вона правильно чи ні.

Для довідки, це все недійсні введення:

############
-**********#
-****$*****#
-**********#
-******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.)

Таблиця лідерів


6
Класний виклик, любитель Терарії.
Rɪᴋᴇʀ

Чи можна припустити, що отвори будуть прямокутні? В іншому випадку це може використовувати тестовий випадок, коли ціле не вміщується в 4х4, але який ніколи не містить більше 4 проміжків підряд.
Мартін Ендер

Є багато моментів, які я вважаю незрозумілими. 1. Чи повинен рама бути прямокутною? " усі будинки будуть прямокутниками " говорить про те, що вони роблять, але чітко не виключає рамки, які є не прямокутними, але заходять у всі чотири кути обмежувальної коробки, вирівняної по осі. І, можливо, діри можуть бути оточені #. 2. За запитанням Мартіна, що саме означає " жоден отвір не може бути більше 4х4 "? (Зауважте також, що до мого третього читання я не був впевнений, що я розумію, що це за діра. Ви повинні написати специфікацію для людей, які не грали в цю гру).
Пітер Тейлор

1
3. " Цей твердий блок не може бути безпосередньо прилеглий до стін " - що таке стіна? З пункту 2 це здається *, але це виключало б наведені приклади дійсних дверей. 4. Чи означає " на землі " "в передостанньому ряду" чи "над а #"? 5. " Це не стосується столу та стільців ". Так це означає, що отвір 4x4 з a Tабо Cбезпосередньо під ним занадто великий? 6. " NPC не може зайти, тому що єдині входи є на розі ". Я не думаю, що спецслужба сказала нічого про кути. Вони можуть бути -або |якщо є інші двері?
Пітер Тейлор

7. Якщо під'їзди на розі є проблемою, оскільки вони не допускають доступу, чи означає це, що кожен з них *має бути доступний до входу? Або *в середині отвори дозволені отвори, отвори, які розрізають всю кімнату надвоє, лише одна сторона має вхід, а входи, які прямують в отвір, дозволені?
Пітер Тейлор

Відповіді:


2

Python 2, 503 439 байт

Не надто короткий, але це рішення. Повідомте мене, якщо ви бачите щось для гольфу. Я б рекомендував переглянути і мою версію, яка не перебуває, бо вона справді читабельна.

Редагувати: Усі if зовнішні петлі об'єднані внизу.

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

Спробуйте в Інтернеті

Безголівки:

Також виводить причину результату Falseдля налагодження.

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

Безкоштовна версія в Інтернеті

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.