Могу ли я жить здесь?

16

В игре Terraria , одна из игровых механик включает в себя строительство домов, чтобы NPC мог двигаться. Существует строгий набор правил для того, что считается действительным домом или нет. Вот список правил:

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

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

    для простоты вы можете смело предположить, что: а) все входные дома будут прямоугольниками, и б) никакой твердой плитки #не будет внутри дома. Вот наш кадр 12x6 (нарисован в красивой ASCII):

    ############
    #          #
    #          #
    #          #
    #          #
    ############
    
  2. Дом должен быть покрыт фоновыми стенами. Это не сплошная плитка, а стена за домом в третьем измерении. Отверстия разрешены, но отверстия не могут быть больше 4х4. Если в строке есть строка или столбец из 5 или более пробелов, это отверстие больше 4х4, и дом недействителен. Допускается также несколько отверстий, но между ними должна быть хотя бы одна стена.

    ############
    #**********#
    #**********#
    #**********#
    #**********#
    ############
    
    ############
    #*    *    #
    #*    *    #
    #*    *    #
    #******    #
    ############  (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 и возвращает истину / ложь, независимо от того, действительно ли это жилье. Вы можете принять это как строку с разделителями новой строки, список строк или любым другим способом, если это разумно. Ради меня, пожалуйста, включите короткую программу, чтобы я мог проверить, работает ли она правильно или нет.

Для справки, это все неверные данные:

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

Leaderboard

DJMcMayhem
источник
6
Классный вызов, приятель Террарии.
Rɪᴋᴇʀ
Можем ли мы предположить, что отверстия будут прямоугольными? В противном случае это может использовать тестовый случай, когда целое не помещается в 4x4, но никогда не содержит более 4 пробелов подряд.
Мартин Эндер
Есть много моментов, которые я нахожу неясными. 1. Должна ли рамка быть прямоугольной? « все дома будут прямоугольниками » предполагает, что они это делают, но явно не исключают рамки, которые не являются прямоугольными, но входят во все четыре угла их выровненного по оси ограничивающего прямоугольника. И, возможно, отверстия могут быть окружены #. 2. Как спросил Мартин, что именно означает « ни одна дыра не может быть больше 4х4 »? (Обратите внимание, что только после третьего прочтения я понял, что это за дыра. Вы должны написать спецификацию для людей, которые не играли в игру).
Питер Тейлор
1
3. « Этот сплошной блок не может быть непосредственно примыкающим к стенам » - что такое стена? С точки зрения 2 это, кажется *, но это исключило бы приведенные примеры действительных дверей. 4. Означает ли « на земле » «в предпоследнем ряду» или «над a #»? 5. « Это не относится к столу и стульям». Значит ли это, что отверстие 4х4 с Tили Cпрямо под ним слишком большое? 6. « NPC не может войти, потому что единственные входы находятся на углу ». Я не думаю, что спецификация что-то говорила о поворотах. Могут ли они быть -или |есть другие двери?
Питер Тейлор
7. Если входы на углу являются проблемой, потому что они не допускают доступ, означает ли это, что каждый *должен быть доступным от входа? Или изолированы *в середине разрешенных отверстий, отверстий, которые разрезают всю комнату на две части только с одной стороны, имеющей вход, и входов, которые выходят непосредственно в отверстие?
Питер Тейлор

Ответы:

2

Python 2, 503 439 байт

Не супер короткий, но это решение. Дай мне знать, если увидишь что-нибудь в гольфе. Я бы порекомендовал взглянуть и на мою версию без гольфа, так как она действительно читаема.

Изменить: все ifs вне цикла были объединены в нижней части.

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

Попробуйте онлайн

Ungolfed:

Также выводит причину результата 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

Беззвучная версия онлайн

mbomb007
источник