Renderuj labirynt ASCII

18

Popatrz! To labirynt ASCII! Soo coolzors, amazeballs i takie tam.

+-+-----+---+
| |     |   |
| |  ++   | |
| |  ++ +-+ |
|       |   |
+-------+ | |
|         | |
+---------+-+

Ale, ale, ale ... ustalenie, w którą stronę idą wszystkie części labiryntu, jest uciążliwe. Chcę tylko narysować układ, a labirynt zamieni się w kulę bez mnóstwa czasu.

Co jeśli mógłbym to narysować w ...

#############
# #     #   #
# #  ##   # #
# #  ## ### #
#       #   #
######### # #
#         # #
#############

To byłoby takie słodkie!


Reguły (ponieważ reguły są fajne):

  • Napisz kod, aby przekonwertować ciąg znaków na labirynt ascii i wyślij wynik.
  • Wszelkie znaki niebiałe będą odczytywane jak ściana.
  • Każdy znak ściany decyduje, która postać będzie oparta na swoich sąsiadach (tylko w kierunku północnym, południowym, wschodnim i zachodnim).
    • Jeśli znak nie ma sąsiadów niebędących spacjami, będzie to znak plus (+).
    • Jeśli znak ma sąsiadów zarówno w kierunku pionowym (północ-południe), jak i poziomym (wschód-zachód), będzie to znak plus (+).
    • Jeśli znak ma sąsiadów tylko w kierunku pionowym (północ-południe), będzie to symbol potoku (|).
    • Jeśli znak ma sąsiadów tylko w kierunku poziomym (wschód-zachód), będzie to znak minus (-).
  • Dane wejściowe mogą być pojedynczymi łańcuchami (z wierszami oddzielonymi znakami nowej linii lub tablicą ciągów).
  • Wszystkie znaki wejściowe będą drukowalnymi znakami ASCII, nie musisz zajmować się rozszerzonymi zestawami znaków.
  • Użyj dowolnego starego języka, jaki chcesz.
  • Jeśli przed linią jest biała spacja, powinna ona być taka sama w każdej linii. Wszelkie spacje po każdym wierszu wyjścia są w porządku.
  • Spróbuj rozwiązać go przy użyciu najmniejszej liczby bajtów.

Przypadki testowe:

1: Ramka

Wejście:

##########
#        #
#        #
#        #
##########

Wynik:

+--------+
|        |
|        |
|        |
+--------+

2: Klasyczny labirynt

Wejście:

#################
        #       #
# ##### # ##### #
#   # # #     # #
# # # # ##### # #
#   # #       # # 
### # ####### # #
#   # #    #  # # 
# ### # ## # ##
#     # ##    #  
#################

Wynik:

--------+-------+
        |       |
| --+-+ | ----+ |
|   | | |     | |
| + | | +---- | |
|   | |       | | 
+-- | +----+- | |
|   | |    |  | | 
| --+ | ++ | -+
|     | ++    |  
+-----+-++----+--

3: Zielone jajka, stary.

Wejście:

I do not like green eggs and ham.
I do not like them, sam I am.
Would you like them here or there?
I would not like them anywhere!

Wynik:

| ++ +++ ++++ +++++ +++- -++ ----
| ++ +++ ++++ +++++ +++ + +++
+-+++ +++ ++++ ++++ ++++ ++ +++---
| +++-+ +++ ++++ ++-+ +++++++++

4: Sople

Wejście:

Word Icicle!
Word Icicle 
Word  cicle 
 ord  cicle 
 ord   icle 
 ord   i le 
 or    i le 
 or    i l  
 or      l  
 or         
  r         

Wynik:

++++ ++++++-
++++ ++++++ 
++++  +++++ 
 +++  +++++ 
 +++   ++++ 
 +++   | ++ 
 ++    | ++ 
 ++    | |  
 ++      |  
 ++         
  |         
AJFaraday
źródło
1
Czy trzecia linia zielonych jajek i szynki nie powinna się kończyć ---?
LiefdeWen
1
Wyniki dla mieszanych sąsiadów są nadal niejasne; nie jestem pewien, dlaczego sople mają w ogóle jakieś -s, ani dlaczego klasyczny labirynt nie ma czterech +s w dolnym rzędzie.
Neil
1
czy możemy przyjmować dane wejściowe jako kwadrat wypełniony spacjami (tj. matrycą)? Czy wyjście może mieć wokół siebie dodatkowe białe znaki? Czy naprawdę masz na myśli smallest number of characters, a nie bajty?
dzaima
1
Myślę, że 1) klasyczny labirynt powinien mieć +pośrodku pierwszego rzędu 2) !sople lodu powinny zostać zastąpione przez -. Czy mógłbyś dokładnie sprawdzić te?
Arnauld
1
Przez whitespace, po prostu nie myśli tylko miejsca? Nie chcę obsługiwać kart i prawdopodobnie nie chcesz, żebym również przekształcał nowe wiersze
Jo King

Odpowiedzi:

11

APL (Dyalog Unicode) , 57 35 bajtów SBCS

–22 dzięki nowatorskiemu rozwiązaniu firmy ngn .

Anonimowa ukryta funkcja przyjmująca jako argument macierz znaków.

{⊃'+-|+'↓⍨25 4 2⊃¨⊂⍱∘⌽⍨' '≠,⍵}⌺3 3

Wypróbuj online!

{… W }⌺3 3 każdej dzielnicy 3 na 3 zastosuj następującą funkcję:

,⍵ ravel (spłaszczyć)

' '≠ Boolean gdzie spacja

⍱∘⌽⍨ że NOR jest odwrotny (w tym ani górny NOR dolny, ani lewy NOR prawy)

5 4 2⊃¨⊂pick 5 th , 4 th , oraz 2 nd element z tej całej listy
  tj pustym siebie, nie pionowe, poziome nie

2⊥ oceniać w podstawie 2 (binarnie)
  tj. ≥4: pusta jaźń; 3: brak sąsiadów; 2: brak horyzontalnych sąsiadów; 1: bez pionu; 0: ma oba

'+-|+'↓⍨ upuść tyle elementów z tego ciągu,
  tj. puste ja :; sam +:; sąsiedniej pionowej (ach): |+; pozioma -|+:; obie:+-|+

 wybierz pierwszy element (pad ze spacją, jeśli nie są dostępne),
  tj. puste self :; sam +:; sąsiedniej pionowej (ach): |; pozioma -:; obie:+


Stare rozwiązanie

Anonimowa ukryta funkcja przyjmująca jako argument macierz znaków.

{' +-|+'⊃⍨1⍳⍨(' '=5⊃,⍵),(∧/,⊢)∨/2 21' '≠(90 1)/,⍵}⌺3 3

Wypróbuj online!

{… W }⌺3 3 każdej dzielnicy 3 na 3 zastosuj następującą funkcję:

,⍵ ravel (spłaszczyć)

()/ Filtruj za pomocą następującej maski:

  9⍴0 1 cyklicznie przekształcaj [0,1]do długości 9 (wybiera N, W, E, S)

' '≠ Boolean gdzie spacja

1⌽ obróć o jeden krok w lewo; [W,E,S,N]

2 2⍴ przekształcić w matrycę 2 na 2; [[W,E],[S,N]]

∨/ redukcja rzędów LUB: [horizontal,vertical]

() Zastosuj następującą funkcję ukrytą:

   tożsamość; [horizontal,vertical]

  ∧/, poprzedzone jego zmniejszeniem AND; [both,horizontal,vertical]

(), Wstaw następujące:

  ,⍵ ravel (spłaszcz) sąsiedztwo

  5⊃ odebrać 5 th elementu (sam)

  ' '= Boolean, jeśli spacja (tzn. Pusta)

 Teraz mamy [empty,both,horizontal,vertical]

1⍳⍨ indeks skrajnie lewej 1 (daje 5, jeśli w ogóle nie ma sąsiadów)

' +-|+'⊃⍨ użyj tego, aby wybrać symbol

   

Adám
źródło
6

JavaScript (ES6), 110 bajtów

Format I / O: tablica ciągów.

a=>a.map((s,y)=>s.replace(/\S/g,(_,x)=>'+|-+'[[-1,p=0,1,2].map(c=>p|=(a[y+c%2]||0)[x+~-c%2]>' '?c&1||2:0)|p]))

Wypróbuj online!

Lub 108 bajtów , używając zamiast tego macierzy znaków.

Arnauld
źródło
6

Python 2 , 181 168 bajtów

dzięki Leaky Nun za -13 bajtów

m=input()
f=lambda x,y:(['']+m+[''])[y+1][x:x+1]>' '
print[[(c<'!')*' 'or'+-|+'[f(x+1,y)|f(x-1,y)|2*f(x,y+1)|2*f(x,y-1)]for x,c in enumerate(r)]for y,r in enumerate(m)]

Wypróbuj online!

ovs
źródło
5

MATLAB, 113 110 101 bajtów

function F(A)
B=A>32
c=[1 1 1]
f=@(c)conv2(B,c,'s')>1
h=f(c)
v=f(c')
char((13*h+92*v-94*(h&v)).*B+32)

Konwertuje dane wejściowe na logiczne, stosuje splot w poziomie i pionie i łączy dane wyjściowe, aby utworzyć odpowiednie znaki.

3 bajty zapisane przez @Adriaan na powiedzenie mi, że możesz zablokować wyjście w PPCG: P

9 bajtów zapisanych dzięki licznym komentarzom @flawr!

Brain Guider
źródło
2

Retina 0.8.2 , 92 bajty

\S
0
(?<=(.)*)0(?=(?>.*\n(?<-1>.)*)0)|0(?=(.)*)(?<=0(?>(?<-2>.)*\n.*))
1
T`d`+|`\b.\b
T`d`-+

Wypróbuj online! Wymaga wejścia prostokątnego. Link zawiera przypadki testowe. Wyjaśnienie:

\S
0

Zmień wszystkie spacje na 0s.

(?<=(.)*)0(?=(?>.*\n(?<-1>.)*)0)|0(?=(.)*)(?<=0(?>(?<-2>.)*\n.*))
1

Poszukaj wszystkich 0s z innym 0bezpośrednio powyżej lub poniżej w tej samej kolumnie i zmień je na 1. 1S są teraz miejscami z pionowymi sąsiadami, podczas gdy 0s nie mają pionowych sąsiadów.

T`d`+|`\b.\b

Poszukaj wszystkich cyfr bez poziomych sąsiadów. Do 0s nie mają pionowe sąsiadów albo, więc stają się one +s, podczas gdy 1y mają pionowe sąsiadów, więc stają |s.

T`d`-+

Pozostałe cyfry mają poziomych sąsiadów. 1Y również pionowe sąsiadów, więc stają się one +s, podczas gdy 0s tylko poziome sąsiadów, więc stają -s.

Neil
źródło
1

Python 3 , 336 bajtów

def g(s):
 h,j,s=' +|-+','',s.splitlines()
 s+=['']
 for n in range(len(s)):
  s[n]+=' '
  for i in range(len(s[n])-1):
   l,r,k=s[n][i-1],s[n][i+1],0
   try:u=s[n-1][i]
   except:u=' '
   try:d=s[n+1][i]
   except:d=' '
   if not s[n][i]==' ':
    k+=1
    if not u==d==' ':k+=1
    if not l==r==' ':k+=2
   j+=h[k]
  j+='\n'
 print(j)

Wypróbuj online!

Musiałem użyć dużo kodu, aby poradzić sobie z błędami wielkości liter.

akozi
źródło
1

C (gcc) , 143 bajty

char**y,*z,h,v;f(char**x){for(y=x;*y;++y)for(z=*y;*z;++z)if(*z-32){h=z[1]-32|z[-1]-32;v=y[1][z-*y]-32|y[-1][z-*y]-32;*z=h?v?43:45:(v?'|':43);}}

Wypróbuj online!

Funkcja f modyfikuje tablicę ciągów w miejscu. Obszar wokół tablicy musi być wypełniony spacjami (nieco ograniczony). Chociaż nie spełnia to dokładnie wymagań większości rozwiązań, jest zgodne z regułami, jeśli mówimy, że reprezentujemy znak nowej linii z dwoma spacjami (i bierzemy ciąg znaków kończący się znakami nowego wiersza).

Nie golfił

f(char**x){
    char **y;
    for (y = x; *y; ++y) {
        char *z;
        for (z = *y; *z; ++z) {
            if (*z != ' ') {
                if (z[1] != ' ' || z[-1] != ' ') {
                    // Horizontal exists
                    if (y[1][z-*y] != ' ' || y[-1][z-*y] != ' ')
                        // Vertical exists
                        *z = '+';
                    else
                        *z = '-';
                } else {
                    // Horizontal doesn't exist
                    if (y[1][z-*y] != ' ' || y[-1][z-*y] != ' ')
                        // Vertical exists
                        *z = '|';
                    else
                        *z = '+';
                }
            }
        }
    }
}

To było zabawne wyzwanie arytmetyki wskaźników. Używając iteracji wskaźnika w stylu C, łatwo jest uzyskać poziomych sąsiadów, ale pionowe były trudniejsze. Na szczęście wskaźnik y wciąż jest w pobliżu (co wskazuje na początkową wartość z), więc mogę wydedukować z niego swój indeks i użyć go, aby uzyskać dostęp do tego samego elementu w innym wierszu. Czułem się bardzo źle, pisząc y[-1][z-*y]wbrew rozsądnemu stylowi!

LambdaBeta
źródło
120 bajtów
pułap pułapek