Визуализация лабиринта ASCII


18

смотреть! Это лабиринт ASCII! Су кулзоры, амазонки и прочее.

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

Но, но, но ... тяжело понять, в каком направлении движутся все части лабиринта. Я просто хочу нарисовать макет лабиринта и сделать себя супер-куль без нагрузки времени.

Что если бы я мог просто нарисовать это в ...

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

Это было бы так мило!


Правила (потому что правила это охлаждение):

  • Напишите код для преобразования строки в ascii-лабиринт и вывода результата.
  • Любой непробельный символ будет читаться как стена.
  • Каждый символ стены будет определять, какой персонаж будет основан на его соседях (только в северном, южном, восточном и западном направлениях).
    • Если у символа нет соседей, не являющихся пробелами, это будет знак плюс (+).
    • Если у символа есть соседи как в вертикальном (север-юг), так и в горизонтальном (восток-запад) направлениях, это будет знак плюс (+).
    • Если символ имеет соседей только в вертикальном (север-юг) направлении, он будет символом трубы (|).
    • Если у символа есть соседи только в горизонтальном (восток-запад) направлении, это будет знак минус (-).
  • Входные данные могут быть одной строкой (со строками, разделенными символами новой строки, или массивом строк).
  • Все входные символы будут печатными символами ASCII, вам не нужно иметь дело с расширенными кодировками.
  • Используйте любой старый язык, пожалуйста.
  • Если перед строкой есть пробел, он должен быть одинаковым в каждой строке. Любой пробел после каждой строки вывода в порядке.
  • Попытайтесь решить это с наименьшим количеством байтов.

Тестовые случаи:

1: рамка

Входные данные:

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

Выход:

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

2: классический лабиринт

Входные данные:

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

Выход:

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

3: Зеленые яйца, человек.

Входные данные:

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!

Выход:

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

4: Сосульки

Входные данные:

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

Выход:

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

1
Разве третья линия зеленых яиц и ветчины не должна заканчиваться ---?
LiefdeWen

1
Результаты для смешанных соседей все еще неясны; не уверен, почему у сосулек вообще есть -s или почему у классического лабиринта нет четырех +s в нижнем ряду.
Нил

1
Разрешено ли нам принимать входные данные в виде квадрата с пробелами (т. е. матрицы)? Можно ли выводить лишние пробелы вокруг него? Кроме того, вы действительно имеете в виду smallest number of characters, а не байты?
Дзайма

1
Я думаю, что 1) классический лабиринт должен иметь +в середине 1-го ряда 2) !Сосульки должны быть заменены на -. Не могли бы вы еще раз проверить эти?
Арнаулд

1
К whitespace, ты имеешь в виду просто пространство? Я не хочу поддерживать вкладки, и вы, вероятно, не хотите, чтобы я также трансформировал переводы строк
Джо Кинг,

Ответы:


11

APL (Dyalog Unicode) , 57 35 байт SBCS

–22 благодаря новому решению от ngn .

Анонимная молчаливая функция, принимающая символьную матрицу в качестве аргумента.

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

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

{… В }⌺3 3 каждом районе 3 на 3 примените следующую функцию:

,⍵ Равель (сплющить)

' '≠ Логическое, где не пробел

⍱∘⌽⍨ что NOR все наоборот (вкл. ни сверху, ни снизу, ни слева, ни справа)

5 4 2⊃¨⊂выбрать 5- й , 4- й и 2- й элементы из этого списка,
  то есть пустое «я», без вертикали, без горизонтали

2⊥ оценивать в base-2 (двоичное),
  т.е. ≥4: пустое «я»; 3: нет соседей; 2: нет горизонтальных соседей; 1: нет вертикали; 0: имеет оба

'+-|+'↓⍨ уронить , что многие элементы из этой строки ,
  т.е. пустых себя: ; один +:; вертикальный сосед (ы) только: |+; горизонтальный -|+:; и то и другое:+-|+

 выбрать первый элемент (pad с пробелом, если они недоступны),
  т.е. пустое self :; один +:; вертикальный сосед (ы) только: |; горизонтальный -:; и то и другое:+


Старое решение

Анонимная молчаливая функция, принимающая символьную матрицу в качестве аргумента.

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

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

{… В }⌺3 3 каждом районе 3 на 3 примените следующую функцию:

,⍵ Равель (сплющить)

()/ Фильтровать, используя следующую маску:

  9⍴0 1 циклически изменить [0,1]до длины 9 (выбирает N, W, E, S)

' '≠ Логическое, где не пробел

1⌽ поверните на один шаг влево; [W,E,S,N]

2 2⍴ преобразовать в матрицу 2 на 2; [[W,E],[S,N]]

∨/ построчное ИЛИ сокращение: [horizontal,vertical]

() Применить следующую молчаливую функцию:

   личность; [horizontal,vertical]

  ∧/, предшествует его сокращение И; [both,horizontal,vertical]

(), Добавьте следующее:

  ,⍵ расплющить окрестности

  5⊃ выбрать 5- й элемент (сам)

  ' '= Булево, если пробел (т.е. пустой)

 Теперь у нас есть [empty,both,horizontal,vertical]

1⍳⍨ индекс крайнего левого 1 (дает 5, если соседей нет вообще)

' +-|+'⊃⍨ используйте это, чтобы выбрать символ

   


6

JavaScript (ES6), 110 байт

Формат ввода / вывода: массив строк.

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]))

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

Или 108 байтов , используя вместо этого матрицу символов.



5

MATLAB, 113 110 101 байт

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)

Преобразует входные данные в логические, применяет свертку по горизонтали и вертикали и объединяет выходные данные для создания соответствующих символов.

@Adriaan сохранил 3 байта для сообщения, что вы можете засорять вывод в PPCG: P

9 байтов сохранено благодаря многочисленным комментариям @flawr!



2

Retina 0.8.2 , 92 байта

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

Попробуйте онлайн! Требуется прямоугольный ввод. Ссылка включает в себя тестовые случаи. Объяснение:

\S
0

Измените все не пробелы на 0s.

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

Найдите все 0s с другим 0непосредственно выше или ниже в том же столбце и измените их на 1. Теперь 1s - это места с вертикальными соседями, в то время как у 0s нет вертикальных соседей.

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

Ищите все цифры без горизонтальных соседей. У 0s тоже нет вертикальных соседей, поэтому они становятся +s, а у 1s вертикальные соседи, поэтому они становятся |s.

T`d`-+

Остальные цифры имеют горизонтальных соседей. У 1s также есть вертикальные соседи, поэтому они становятся +s, в то время как у 0s есть только горизонтальные соседи, поэтому они становятся -s.


1

Python 3 , 336 байт

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)

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

Мне пришлось использовать много кода, чтобы справиться с ошибками в крайнем случае.


1

C (gcc) , 143 байта

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);}}

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

Функция f изменяет массив строк на месте. Область вокруг массива должна быть дополнена пробелами (немного ограничена). Хотя это не совсем соответствует требованиям, используемым большинством решений, оно соответствует правилам, если мы говорим, что представляем новую строку с двумя пробелами (и принимаем массив строк, оканчивающихся на новые строки).

Ungolfed

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 = '+';
                }
            }
        }
    }
}

Это было забавное испытание арифметики указателей. Используя итерацию указателя в стиле C, легко получить горизонтальных соседей, но вертикальные были более жесткими. К счастью, указатель y все еще присутствует (что указывает на начальное значение z), поэтому я могу вывести из него свой индекс и использовать его для доступа к тому же элементу в другой строке. Это было очень неправильно писать, y[-1][z-*y]поскольку это бросает вызов любому разумному стилю!


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.