테이블이 주어지면 의자에 놓으십시오.


41

도전

ASCII |및로 그려진 표가 입력으로 제공됩니다 _. 당신의 임무는 주위에 의자를 설정하는 것입니다.

입력:

 ____
|    |
|    |
|    |
|    |
|____|

산출:

 _^_^_
<     >
|     |
<     >
|     |
<_ _ _>
  v v

그 의자는와로 구성 <>되어 v^있습니다.

또 다른 예:

라인에는 가능한 한 많은 의자가 있어야합니다.

  _____
 |     |_____
 |           |
 |           |
 |           |
 |      _____|
 |_____|


  _^_^_
 <     |_^_^_
 |           >
 <           |
 |           |
 <      _ _ _>
 |_ _ _| v v
   v v

모든 의자 사이에 공간이 있어야합니다. 그리고 >_^_^_<유효하지 않습니다 |_^_^_|.

  _____       _____
 |     |_____|     |
 |                 |
 |                 |
 |                 |
 |      ___________|
 |_____|


  _^_^_       _^_^_
 <     |_^_^_|     >
 |                 |
 <                 >
 |                 |
 <      _ _ _ _ _ _>
 |_ _ _| v v v v v
   v v

"도넛 형"내부에는 의자가있을 수 없습니다.

  _________________
 |      _____      |
 |     |     |     |
 |     |     |     |
 |     |_____|     |
 |_________________|


  _^_^_^_^_^_^_^_^_
 <      _____      >
 |     |     |     |
 <     |     |     >
 |     |_____|     |
 <_ _ _ _ _ _ _ _ _>
   v v v v v v v v

^v우선 순위 <>. 자체 의자가 없습니다 (적어도 하나 |이상 _있어야합니다).

  _________________
 |      _____      |
 |     |     |     |
 |     |     |_____|
 |     |_____
 |___________|


  _^_^_^_^_^_^_^_^_
 <      _ _ _      >
 |     | v v |     |
 <     >     <_ _ _>
 |     |_^_^_  v v
 <_ _ _ _ _ _|
   v v v v v

이것은 코드 골프이므로 가장 짧은 코드가 승리합니다.


2
혼란 스러워요. 의자가 측면에서 테이블에 묻혀 있습니까?
Optimizer

내가 정확하게 기억한다면, 원래 샌드 박스 포스트는 수직 테이블 라인과 의자 라인 사이에 공백이있었습니다. 수평 테이블 라인과 의자 사이에 약간의 공간이있는 것처럼.
최적화 도구

1
의자가 서로 1 거리 떨어져있는 것처럼 보이지만 입력 주변은 2로 나눌 수 없습니다. 프로그램이 어떻게 의자를 놓아야하는지. 시계 방향 또는 시계 반대 방향? 오른쪽 상단, 왼쪽 상단 등에서?

1
또한 세 번째 샘플에 문제가 있다고 생각합니다. 두 번째와 세 번째 "상단"의자 사이에 여분의 공간이 있으며 마지막 예에서 오른쪽 아래 모서리

1
첫 번째 테스트 사례가 깨진 것 같습니다. 입력은 4
Wheat Wizard

답변:


34

파이썬 (2) 1,033 1,007 924 879 829 787 713 699 692 691 688 687 672 670 664 659 654 648 643 642 630 625 623 620 570 560 554 545 518 514 513 510 505 492 476 454 451 443 바이트

Riley 덕분에 6 바이트 절약

Adnan 덕분에 6 바이트 절약

이 질문은 1 년이 지났지 만 여전히 대답이 없으므로 시도해 볼 것이라고 생각했습니다.

n,i,o,u="\nI _";R=lambda x:range(1,x-1)
b=open(i).read()
s=b.split(n)
z=max(map(len,s))+3
a=[list(i+x.ljust(z,i))for x in[i]+s+[i]]
for x in R(len(a))*len(b):
 A=a[x];B=a[x+1];C=a[x-1]
 for y in R(z):
    D=A[y-1:y+2];k=B[y];j=A[y+1]
    if(i in[C[y],k]+D+(k==u)*B[y-1:y+2]or"V"==j)&(A[y]==o):A[y]=i
    if"|"==A[y]==C[y]:A[y]={i:"|",j:">",A[y-1]:"<"}[i]
    if[u]*3==D:A[y],B[y]={i:u+k,C[y]:"^"+k,k:" V"}[i]
print n.join(`y`[2::5]for y in a).replace(i,o)

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

프로그램은 파일 이름이 지정된 테이블을 읽고 I테이블을 의자와 함께 인쇄합니다 std::out. 나는 많은 최첨단 사례에 대해 확신하지 못했기 때문에 최선의 판단 (최소한 노력을 기울인 것)을 취했지만 모든 테스트 사례를 통과 한 것으로 보입니다. 일부 출력은 정확히 일치하지 않지만 모두 동일한 수의 의자가 있습니다.

설명

첫 번째 줄은 미래에 바이트를 절약 할 몇 가지 정의를 설정합니다.

(나중에 읽을 수 있도록이 매크로의 압축을 풉니 다.)

n,i,o="\nI ";R=lambda x:range(1,x-1)

그런 다음 I이미 짧은 변수가 있으므로 몇 바이트를 절약하기 때문에 이름이 지정된 파일을 열 것 입니다.

b=open("I").read().split("\n")

줄 바꿈으로 분할하여 문자열 목록 (이미지의 행)을 만듭니다.

s=b.split(n)

그런 다음 가장 긴 줄의 길이를 찾아서 모든 줄을 해당 길이로 채울 수 있습니다. (우리는 약간의 추가 패딩이 필요하기 때문에 3을 추가합니다)

 z=max(map(len,s))+3

그런 다음 실제 패딩을 수행 I하고 가장자리 주위 에 문자 테두리를 만듭니다 . 나중에 모양의 내부와 외부의 차이를 알려야하기 때문입니다. 또한 데이터 유형을 문자열 목록에서 문자 목록 (길이 1 문자열)으로 변경합니다.

a=[list("I"+x.ljust(z,"I"))for x in["I"]+s+["I"]]

다음 줄은 또 다른 바이트 절약 정의입니다.

(나는 또한 이것을 풀 것이다)

B=R(len(a))

이제 I캐릭터를 도형 외부의 모든 곳에 퍼 뜨리고 싶습니다 . 우리는 유사 세포 오토 마톤으로 이것을 할 수 있습니다. 각각 I은 인접한 문자로 퍼 집니다. 오토 마톤이 안정화 될 때까지 반복 할 수 있지만, 문자보다 더 많은 반복을 할 수 없으므로 b(원래 입력)의 모든 문자를 반복합니다.

for _ in b:

반복 할 때마다 2D리스트의 모든 문자를 넘기려고합니다 (가장 바깥 쪽 패딩 제외)

 for x in range(1,len(a)-1):
    A=a[x]  #<--Another definition I will fill in for clarity
    for y in range(1,z-1):

각 위치에 대해 다음 코드를 실행합니다.

if("I" in[a[x+1][y],a[x-1][y]]+a[x][y-1:y+2])&(a[x][y]==" "):a[x][y]=" "

이것을 분해하자.

우리는 &(비트 단위 and)로 구분 된 두 개의 조건이있는 if

첫 번째 I셀은 인접한 셀이 있는지 확인하고 두 번째 셀은 현재 셀이 a인지 확인합니다 " ". 이러한 조건을 통과하면 현재 셀을로 설정합니다 I.


모양의 바깥 쪽과 안쪽을 결정 했으므로 의자를 테이블 주위에 놓을 수 있습니다.

다시 한번 우리는 모든 셀을 반복합니다 (그리고 더 많은 속기를 설정합니다)

for x in range(1,len(a)-1):
 A=a[x]
 for y in range(1,z-1):
        k=a[x+1][y]

이제 내가 가장 좋아하는 부분이 있습니다. 만약 당신이 나의 지루하고, 주로 정의에 기초한, 골프를 겪었다면, 나는 당신에게 멋진 영리한 골프의 좋은 보상을 줄 것입니다 (내가 그렇게 말하면).

파이썬에서 약간의 배경 :

파이썬에서는 사전 키를 두 번 할당하려고하면 후자가 할당됩니다. 예를 들어

>>> {1:"a",1:"b"}[1]
'b'

이 속성을 남용하여 현재 셀을 특정 문자에 할당합니다.

첫 번째 조건은

if["_"]*3==a[x][y-1:y+2]:a[x][y],a[x+1][y]={"I":"_"+a[x+1][y],a[x-1][y]:"^ ",a[x+1][y]:" V"}["I"]

셀이 가장자리가 3 _자인 경우 현재 셀과 그 아래의 셀을 다시 할당합니다. 로 오버로드 된 사전을 색인화 한 결과에이를 할당합니다 I. 먼저 기본값을 쌍으로 설정합니다. "I":"_"+a[x+1][y]변경 사항이 없으면 두 셀을 원래 값으로 다시 할당합니다. 다음으로 쌍을 추가합니다 a[x-1][y]:"^ ". 현재 셀 ( a[x-1][y]) 위의 셀 이로 채워져 있지 않으면 아무 것도하지 않습니다 (중요) I. 그 I안에 들어 있으면 현재 셀에 의자를 놓으라는 기본 설정을 무시합니다. 다음으로 현재 셀 아래에있는 셀로 이동합니다. 만약 그 셀이 I우리가 현재 지점 아래에 위로 향한 의자를 놓기 위해 다시 오버라이드 된다면 .

다음 조건은 조금 더 간단합니다

if"|"==a[x][y]==a[x-1][y]:a[x][y]={"I":"|",A[y+1]:">",A[y-1]:"<"}["I"]   

현재 셀과 그 위의 셀이 모두 있는지 확인합니다 |. 그렇다면 사전을 설정했습니다.

사전의 첫 번째 쌍이 "I":"|"기본값을 설정합니다. 우리는 키에 액세스하려고하기 때문에 I경우 I는 다시 기본값으로 재 할당되지 않습니다 |(문자가 이미) 아무것도하지 않습니다.

우리는 두 개의 키를 추가합니다 A[y+1]:">",A[y-1]:"<". 두 셀 중 하나가 왼쪽과 오른쪽에 I있으면 현재 셀을 외부 방향을 가리키는 의자에 다시 할당합니다.


이제 출력 만하면됩니다. 그러나 우리는 단지 인쇄 할 수 없으며, 우리가 먼저해야 할 몇 가지 정리 작업이 있습니다. 우리는 문자열로 다시 변환하고 I우리가 만든 모든 것을 제거해야합니다 . 이것은 한 줄로 이루어집니다.

print "\n".join(`y`[2::5]for y in a).replace("I"," ")

첫 번째 들여 쓰기 수준에 공백, 탭 2, 탭 3, 공백을 사용할 수 없습니까? 몇 바이트를 절약 할 수 있습니다.
Riley

3
이것은 가장 재 골프 된 답변 일 수 있습니다.
매직 문어 Urn

2
합니까 i,o="I "대신 i="I";o=" "사용할 수 있습니까?
Adnan

1
@ErikGolferE リ ッ ク ゴ ル フ ァ ー 만들기 n비용 4 바이트 및 저를 저장합니다 6. 자주 사용하지는 않지만 2 바이트를 절약합니다.
밀 마법사

1
@ Pietu1998 지적 해 주셔서 감사합니다. 나는 문제를 수정했다
밀 마법사
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.