Czy mogę tu mieszkać?

16

W grze Terraria jedna z mechaniki gry polega na budowaniu domów, aby mógł się do nich wprowadzić NPC. Istnieje ścisły zestaw zasad określających, czy dom jest ważny, czy nie. Oto lista zasad:

  1. Całkowita powierzchnia domu musi wynosić co najmniej 60 kwadratowych płytek, ale mniej niż 750. Ponadto rozmiar domu, w tym zewnętrzna rama, musi wynosić co najmniej jeden z tych:

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

    dla uproszczenia można bezpiecznie założyć, że: a) Wszystkie domy wejściowe będą prostokątami, i b) żadna solidna płytka #nie będzie w domu. Oto nasza rama 12x6 (narysowana w pięknym ASCII):

    ############
    #          #
    #          #
    #          #
    #          #
    ############
    
  2. Dom musi być przykryty ścianami w tle. To nie są solidne płytki, ale raczej ściana za domem w trzecim wymiarze. Otwory są dozwolone, ale żadne otwory nie mogą być większe niż 4x4. Jeśli rząd lub kolumna zawiera 5 lub więcej znaków spacji w rzędzie, jest to otwór większy niż 4x4, a dom jest nieprawidłowy. Dozwolone są również liczne otwory, ale musi być co najmniej jedna ściana od siebie.

    ############
    #**********#
    #**********#
    #**********#
    #**********#
    ############
    
    ############
    #*    *    #
    #*    *    #
    #*    *    #
    #******    #
    ############  (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. Musi być wejście. Mogą to być drzwi |po bokach lub platforma -na podłodze lub suficie. Jeśli jedyne wejście znajduje się na rogu, NPC nie może wejść. Ponadto, jeśli masz platformę jako podłogę, musisz mieć co najmniej jeden solidny blok, na którym NPC może stać. Ten solidny blok nie może przylegać bezpośrednio do bocznych ścian po lewej lub prawej stronie. Wszystkie są ważne domy z wejściami:

    ############
    #**********#
    |**********#
    #**********#
    #**********|
    ############  (Multiple doors, or doors up high are okay)
    
    ############
    #**********#
    #**********#
    #**********#
    #**********#
    #######----#
    
    #----#######
    #**********#
    #**********#
    #**********#
    #**********#
    ############
    
  4. Musi być co najmniej jedno źródło światła $, stół Ti krzesło C, chociaż dozwolone jest więcej. Źródło światła może znajdować się w powietrzu lub na ziemi, ale stół i krzesło muszą znajdować się na ziemi, np. W najniższym rzędzie.

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

    Możesz również założyć, że za meblami znajduje się ściana, więc pochodnia, krzesło lub stół mogą być liczone jako separator między dwoma otworami.

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

Wyzwanie

Musisz napisać najkrótszą funkcję, która przyjmuje dom jako ciąg ASCII i zwraca true / false, niezależnie od tego, czy jest to poprawna obudowa. Możesz traktować to jako ciąg rozdzielany znakiem nowej linii, listę ciągów lub w dowolny inny sposób, o ile jest to uzasadnione. Ze względu na mnie proszę dołączyć krótki program, dzięki czemu mogę przetestować, czy działa poprawnie, czy nie.

Dla odniesienia są to wszystkie nieprawidłowe dane wejściowe:

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

Tabela liderów

DJMcMayhem
źródło
6
Fajne wyzwanie, miłośnik Terraria.
Rɪᴋᴇʀ
Czy możemy założyć, że otwory będą prostokątne? W przeciwnym razie można użyć przypadku testowego, w którym całość nie mieści się w 4x4, ale nigdy nie zawiera więcej niż 4 spacje z rzędu.
Martin Ender,
Jest wiele punktów, które uważam za niejasne. 1. Czy rama musi być prostokątna? „ wszystkie domy będą prostokątami ”, sugerują, że tak, ale nie wykluczają wyraźnie ramek, które nie są prostokątne, ale wchodzą we wszystkie cztery rogi ich obwiedni wyrównanej do osi. I być może dziury mogą być otoczone #. 2. Jak zapytał Martin, co dokładnie oznacza „ żadne dziury nie mogą być większe niż 4x4 ”? (Zauważ też, że dopiero po trzecim czytaniu byłem pewien, że zrozumiałem, co to jest dziura. Powinieneś napisać specyfikację dla osób, które nie grały w grę).
Peter Taylor,
1
3. „ Ten solidny blok nie może bezpośrednio przylegać do ścian ” - co to jest ściana? Z punktu 2 wydaje się *, że tak, ale wykluczałoby to podane przykłady prawidłowych drzwi. 4. Czy „ na ziemi ” oznacza „w przedostatnim rzędzie” czy „nad a #”? 5. „ Nie dotyczy to stołu i krzeseł. ” Czy to oznacza, że ​​otwór 4x4 z Tlub Cbezpośrednio pod nim jest zbyt duży? 6. „ NPC nie może wejść, ponieważ jedyne wejścia znajdują się na rogu ”. Nie sądzę, żeby specyfikacja mówiła coś o rogach. Czy mogą być, -czy |są inne drzwi?
Peter Taylor,
7. Jeśli wejścia na rogu stanowią problem, ponieważ nie pozwalają na dostęp, czy to oznacza, że ​​każde *musi być dostępne od wejścia? Czy też są izolowane *w środku otworów, otwory, które przecinają cały pokój na pół z dozwoloną tylko jedną stroną, a wejścia, które prowadzą bezpośrednio do otworu są dozwolone?
Peter Taylor,

Odpowiedzi:

2

Python 2, 503 439 bajtów

Niezbyt krótki, ale to rozwiązanie. Daj mi znać, jeśli zobaczysz coś do gry w golfa. Polecam też przyjrzeć się mojej wersji bez golfa, ponieważ jest ona rzeczywiście czytelna.

Edycja: Wszystkie ifs poza pętlą zostały połączone na dole.

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

Wypróbuj online

Nie golfowany:

Podaje również przyczynę tego wyniku Falsedo celów debugowania.

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

Wersja bez golfa online

mbomb007
źródło