Puedo vivir aqui

16

En el juego Terraria , una de las mecánicas del juego consiste en construir casas para que un NPC pueda mudarse. Hay un conjunto estricto de reglas para lo que cuenta como una casa válida o no. Aquí está la lista de reglas:

  1. El área total de la casa debe ser de al menos 60 azulejos cuadrados, pero menos de 750. Además, el tamaño de la casa, incluido el marco exterior, debe ser al menos uno de estos:

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

    En aras de la simplicidad, puede asumir con seguridad que: a) Todas las casas de entrada serán rectángulos, y b) no #habrá baldosas sólidas dentro de la casa. Aquí está nuestro marco de 12x6 (dibujado en un hermoso ASCII):

    ############
    #          #
    #          #
    #          #
    #          #
    ############
    
  2. La casa debe estar cubierta de paredes de fondo. Estas no son baldosas sólidas, sino más bien una pared detrás de la casa en la tercera dimensión. Se permiten agujeros, pero no pueden ser más grandes que 4x4. Si hay una fila o columna de 5 o más caracteres de espacio en una fila, este es un agujero más grande que 4x4, y la casa no es válida. También se permiten múltiples agujeros, pero debe haber al menos una pared separada.

    ############
    #**********#
    #**********#
    #**********#
    #**********#
    ############
    
    ############
    #*    *    #
    #*    *    #
    #*    *    #
    #******    #
    ############  (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. Debe haber una entrada. Puede ser una puerta |a los lados o una plataforma -en el piso o el techo. Si la única entrada está en una esquina, el NPC no puede entrar. Además, si tiene una plataforma como piso, debe tener al menos un bloque sólido para que el NPC se pare. Este bloque sólido no puede estar directamente adyacente a las paredes laterales a la izquierda o la derecha. Estas son todas las casas válidas con entradas:

    ############
    #**********#
    |**********#
    #**********#
    #**********|
    ############  (Multiple doors, or doors up high are okay)
    
    ############
    #**********#
    #**********#
    #**********#
    #**********#
    #######----#
    
    #----#######
    #**********#
    #**********#
    #**********#
    #**********#
    ############
    
  4. Debe haber al menos una fuente de luz $, mesa Ty silla C, aunque se permite más. La fuente de luz puede estar en el aire o en el suelo, pero la mesa y la silla deben estar en el suelo, por ejemplo, en la fila más baja.

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

    Además, puede suponer que hay una pared detrás de cualquier mueble, por lo que una antorcha, una silla o una mesa pueden contar como un separador entre dos agujeros.

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

El reto

Debe escribir la función más corta que toma una casa como una cadena ASCII y devuelve verdadero / falso si es o no una vivienda válida. Puede tomar esto como una cadena delimitada por una nueva línea, una lista de cadenas o de cualquier otra manera, siempre que sea razonable. Por mi bien, incluya un programa corto para que pueda probar si funciona bien o no.

Como referencia, estas son todas entradas no válidas:

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

Tabla de clasificación

DJMcMayhem
fuente
66
Genial desafío, compañero amante de Terraria.
Rɪᴋᴇʀ
¿Podemos suponer que los agujeros serán rectangulares? De lo contrario, esto podría usar un caso de prueba en el que el todo no cabe en 4x4 pero que nunca contiene más de 4 espacios seguidos.
Martin Ender
Hay muchos puntos que no entiendo. 1. ¿El marco tiene que ser rectangular? " todas las casas serán rectángulos " sugiere que sí, pero no descarta claramente los marcos que no son rectangulares, sino que van a las cuatro esquinas de su cuadro delimitador alineado con el eje. Y posiblemente los agujeros pueden estar rodeados por #. 2. Como Martin preguntó, ¿qué significa exactamente " ningún agujero puede ser mayor que 4x4 "? (Tenga en cuenta también que no fue hasta mi tercera lectura que estuve seguro de entender cuál era el hoyo. Debería escribir las especificaciones para las personas que no han jugado el juego).
Peter Taylor
1
3. " Este bloque sólido no puede estar directamente adyacente a las paredes ": ¿qué es una pared? Desde el punto 2 parece ser *, pero eso excluiría los ejemplos dados de puertas válidas. 4. ¿" en el suelo " significa "en la penúltima fila" o "encima de #"? 5. " Esto no se aplica a la mesa y las sillas " . Entonces, ¿eso significa que un agujero de 4x4 con To Cdirectamente debajo es demasiado grande? 6. "El NPC no puede entrar porque las únicas entradas están en la esquina " No creo que la especificación haya dicho nada sobre las esquinas. ¿Pueden ser -o |si hay otras puertas?
Peter Taylor
7. Si las entradas en una esquina son un problema porque no admiten el acceso, ¿eso significa que cada una *debe ser accesible desde una entrada? ¿O se aíslan *en el medio de los agujeros permitidos, los agujeros que cortan toda la habitación en dos con solo un lado con una entrada permitida y las entradas que van directamente a un agujero permitido?
Peter Taylor

Respuestas:

2

Python 2, 503 439 bytes

No es muy corto, pero es una solución. Avísame si ves algo para jugar golf. También recomendaría mirar mi versión no golfista, ya que en realidad es legible.

Editar: Todos los ifs fuera de un bucle se han combinado en la parte inferior.

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

Pruébalo en línea

Sin golf:

También muestra la razón del resultado False, para fines de depuración.

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ón sin golf en línea

mbomb007
fuente