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
혼합 된 이웃에 대한 결과는 여전히 불분명합니다. 왜 고드름이 전혀 없는지 -또는 왜 고전 미로가 +맨 아래 줄에 4를 가지고 있지 않은지 확실 하지 않습니다 .
Neil

1
공백으로 채워진 사각형으로 입력을 취할 수 있습니까 (예 : 행렬)? 출력에 여분의 공백이 허용됩니까? 또한 smallest number of characters바이트가 아닌을 의미 합니까?
dzaima

1
나는 1) 고전 미로가 +첫 번째 줄의 중간에 !있어야한다고 생각합니다 -. 이것들을 다시 확인해 주시겠습니까?
Arnauld

1
whitespace, 당신은 단지 공간을 의미합니까? 나는 탭을 지원하고 싶지 않으며 아마 줄 바꿈을 바꾸고 싶지 않을 것입니다.
Jo King

답변:


11

APL (Dyalog Unicode) , 57 35 바이트 SBCS

ngn의 새로운 솔루션 덕분에 –22 .

문자 행렬을 인수로 사용하는 익명의 암묵적 함수.

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

온라인으로 사용해보십시오!

{}⌺3 3 각 3x3 이웃에 다음 기능을 적용하십시오.

,⍵ 라벨 (평평하게)

' '≠ 공백이 아닌 부울

⍱∘⌽⍨ NOR 반대입니다 (위쪽 NOR 아래쪽, 왼쪽 NOR 오른쪽 없음)

5 4 2⊃¨⊂전체 목록에서 5 번째 , 4 번째 및 2 번째 요소를 선택합니다.
  즉 비어있는 자기, 수직, 수평 없음

2⊥ 기수 -2 (이진)에서 평가,
  즉 ≥4 : 빈 자기; 3 : 이웃 없음; 2 : 수평 이웃 없음; 1 : 수직 없음; 0 : 둘 다

'+-|+'↓⍨ 이 문자열에서 많은 요소를 삭제
  하십시오 . 즉 빈 self : ; 혼자 : +; 수직 이웃 만 : |+; 가로 : -|+; 양자 모두:+-|+

 첫 번째 요소 (사용할 수없는 경우 공간이있는 패드)를 선택하십시오.
  즉 비어있는 self : ; 혼자 : +; 수직 이웃 만 : |; 가로 : -; 양자 모두:+


오래된 솔루션

문자 행렬을 인수로 사용하는 익명의 암묵적 함수.

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

온라인으로 사용해보십시오!

{}⌺3 3 각 3x3 이웃에 다음 기능을 적용하십시오.

,⍵ 라벨 (평평하게)

()/ 다음 마스크를 사용하여 필터링합니다.

  9⍴0 1[0,1]길이 9로  주기적으로 모양 변경 (N, W, E, S 선택)

' '≠ 공백이 아닌 부울

1⌽ 한 단계 왼쪽으로 회전; [W,E,S,N]

2 2⍴ 2x2 매트릭스로 재구성; [[W,E],[S,N]]

∨/ 행 단위 OR 감소 : [horizontal,vertical]

() 다음 암묵적 기능을 적용하십시오.

   정체성; [horizontal,vertical]

  ∧/, AND 감소가 선행됩니다. [both,horizontal,vertical]

(), 다음을 추가하십시오.

  ,⍵ 동네를 평평하게하다

  5⊃ 다섯 번째 요소를 선택하십시오 (자체)

  ' '= 공백 인 경우 부울 (예 : 비어 있음)

 이제 우리는 [empty,both,horizontal,vertical]

1⍳⍨ 가장 왼쪽에있는 인덱스 1 (이웃이 없으면 5를 제공)

' +-|+'⊃⍨ 그것을 사용하여 기호를 선택하십시오

   




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)

입력을 논리로 변환하고 수평 및 수직으로 컨벌루션을 적용하고 출력을 결합하여 해당 문자를 만듭니다.

PPCG에서 출력을 막을 수 있다고 알려주기 위해 @Adriaan이 3 바이트를 절약했습니다. : P

수많은 @flawr 주석 덕분에 9 바이트가 절약되었습니다!



2

레티 나 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

같은 열에서 바로 위 또는 아래에있는 0다른 모든 항목을 0찾아서 1로 변경하십시오. 1이제 세로 이웃이있는 장소가되고 세로 이웃 0이 없습니다.

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

이웃이없는 모든 숫자를 찾으십시오. 0가 될 수 있도록들, 하나 더 수직 이웃이 없습니다 +s를하는 동안 1의 수직 이웃이가 될 수 있도록, |의.

T`d`-+

나머지 자릿수에는 가로 이웃이 있습니다. 는 1그들이 될 수 있도록 또한, 수직 이웃이 s의 +s를가하면서, 0단지이야 수평 이웃이가 될 수 있도록, -의.


1

파이썬 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는 문자열 배열을 제자리에서 수정합니다. 배열 주변 영역에는 공백이 채워 져야합니다 (비트가 제한됨). 이것이 대부분의 솔루션이 사용하는 요구 사항을 정확하게 충족 시키지는 않지만 두 개의 공백이있는 줄 바꿈을 나타내며 줄 바꿈으로 끝나는 문자열 배열을 취한다고 말하는 경우 규칙을 준수합니다.

언 골프

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]합리적인 스타일로 날아 다니면서 글쓰기 가 잘못 되었다!


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.