탭을 반으로 나누기


31

스페이스와 탭 사이에서 거룩한 전쟁이 벌어졌습니다. (물론 객관적으로 우월한 공간도 승리했습니다.) — Alex A.

S는 오메 PEO의 P 르가 여전히 거부 에 것을 ccept WHI C의 H는 Cl이고 , E는 흘리 이야 upreme한다. 당신은받은 incor을 사용하여 파일을 CT를, B의 광고 및 INF 전자 WHI의 rior 양식 t 이스 페이스를 지금 마에 그에게 계속 전자 파일의 국세청 r에 전자가 오염과 파괴를.

귀하는 파일을 보낸 사람에게 자신이 얼마나 잘못되었는지 보여줄 수도 있습니다.

기술

제목에서 알 수 있듯이 하나 이상의 탭이 포함 된 파일을 가져와야합니다.

this is an evil tab    onoes

무자비하게 조각으로 산산이 부서집니다.

this is an evil tab

                     o
                     n
                     o
                     e
                     s

Stack Exchange 소프트웨어는 리터럴 탭을 네 개의 공백으로 변환하므로 (올 바르기 때문에)이 게시물 내의 탭은 네 개의 공백으로 표시됩니다. 그러나 프로그램 입력에는 실제 탭이 포함됩니다.

도전

솔루션은 단일 문자열을 입력으로 사용해야하며 인쇄 가능한 ASCII, 줄 바꿈 및 탭이 포함될 수 있습니다. 입력에는 항상 하나 이상의 탭이 있습니다.

다음 규칙이 적용되는 출력은 동일한 문자열이어야합니다.

  • 좌표 (0,0)에서 오른쪽 방향으로 커서를 시작하십시오. 좌표는 (열, 행), 인덱스가 0이며 방향은 문자를 인쇄 한 후 커서를 움직여야하는 방향입니다.

  • 문자열의 각 문자에 대해 :

    • 줄 바꿈 인 경우 좌표 (0, n)으로 이동하십시오. 여기서 n은 문자열의 줄 바꿈 수입니다 (이 것을 포함하여). 방향을 오른쪽으로 재설정하십시오.

    • 탭인 경우 두 공간을 출력 하고 커서 방향을 시계 방향으로 90도 회전 한 다음 두 공간을 더 출력하여 탭을 효과적으로 "반으로 나누십시오". 다음은 탭이 다음과 같이 표시되는 시각적 예입니다.---> 되고 공백을· .

      foo--->bar--->baz
      

      된다

      foo···
           ·
           b
           a
           r
           ·
           ·
       zab··
      
    • 그렇지 않으면 커서에서 문자를 출력하고 커서를 현재 방향으로 한 단계 이동합니다.

문자열을 처음부터 끝까지 읽고 있기 때문에 기존 문자의 "맨 위에"를 써야 할 수도 있습니다. 예를 들어, 입력

foo--->bar


spaces are superior

의 결과를 산출해야한다

foo

     b
spaces are superior
     r

"깨진 탭"이 다른 문자를 덮어 쓸지 여부를 선택할 수 있습니다. 원래 의도는 그렇지 않았지만 사양이 모호했기 때문에 이것이 귀하의 결정입니다.

또한 이러한 규칙을 적용한 후에도

  • 원하는만큼 후행 공백을 추가하거나 제거하십시오.

  • 최대 하나의 후행 줄 바꿈을 추가하십시오.

입력은 절대 공백이 포함 되지 않습니다 . 또한 선행 또는 후행 줄 바꿈이 포함되지 않습니다. 또한 열이나 0보다 작은 행에 쓸 필요가 없다고 항상 가정 할 수도 있습니다 (예 : 화면 밖).

테스트 사례

이 테스트 사례의 탭은 ---> SE가 그렇지 않기 때문에 .

입력:

Test case. Here's a tab--->there's a tab--->everywhere a tab--->tab--->this is some more text
blah
blah
blah blah blah blah blah blah--->blaah--->blaah--->blah--->blaaaaah--->blah--->blah--->blah--->blah--->blah

산출:

Test case. Here's a tab
blah
blah                     t
blah blah blah blah blah blah
                        blaablah
                         r     b
                         e     l  b
                      h  'h    a  l
                      a  sa    a  a
                      l   l    h  h
       this is some mobe tbxt

                         haalhalb
     b                   a
     a                   b
     t

        bat a erehwyreve

멋진 애니메이션 :

규칙

  • 이것은 이므로 바이트 단위의 가장 짧은 코드가 이길 것입니다!

커서가 시작해야한다고 말하면 (0,0)먼저 콘솔을 지우 야합니까, 아니면 커서의 기본 위치를 의미합니까?
마틴 엔더

18
나는 증오와 신성 모독으로 가득차 있기 때문에이 질문을 주 제외로 마무리하려고 투표하고 있습니다.
aditsu

1
여러분의 애니메이션은> <> 인터프리터와 매우 흡사하여 이제 자동 수정> <> 항목을보고 싶습니다.
Sanchises

1
첫 단락에서 숨겨진 메시지를 좋아했지만 동의하지 않아야합니다.
wf4

@ MartinBüttner 기본 위치를 의미합니다.
Doorknob

답변:


8

MATLAB, 144 바이트

현을 다루기 위해 선택하는 무기는 물론 숫자를 조작하기 위해 고안된 언어입니다 [표창장 필요]. 키랩을 제외하고 Matlab의 가장 큰 장점은 '범위를 벗어난'배열에 할당하더라도 신경 쓰지 않는다는 것입니다. 단순히 더 큰 행렬을 만듭니다. 또한 기본 행렬 요소 0인은 (가) 대신 공백으로 렌더링됩니다.null 인는 ASCII 문자 .

탭은 단순히 좌표의 점프이므로 탭에 공백이 출력되지 않습니다.

function o=q(t)
u=2;v=0;x=1;y=1;n=1;for s=t
if s==9 x=x+u-v;y=y+v+u;a=v;v=u;u=-a;elseif s<11
n=n+1;x=1;y=n;else
o(y,x)=s;x=x+u/2;y=y+v/2;end
end

나는 209 바이트로 시작했지만 좀 더 신중한 골프는 대부분을 제거했다. 이 코드에는 많은 반복이 있으므로 대안이 가장 효과가 좋은 시행 착오를했습니다. 이 코드로 더 많은 최적화를위한 공간이 충분하지 않다고 생각하지만 항상 틀렸다는 것이 기쁘다. 편집 : 톰 카펜터는 나를 잘못 증명했다; 그는 무려 29 바이트를 절약하도록 최적화 한 9 바이트를 절약 할 수있었습니다. 입력에 제어 문자 (ASCII <9)가 없다고 가정하여 저장 한 마지막 바이트 null-MATLAB 문자열은 종료되지 않습니다 .


작동하지 않는 것 같습니다. 나는 이것을 시도 q('hello<tab>my name<tab>is tom<tab>c')했지만 그것의 라인을 따라 뭔가 Attempted to access o(11,-2); on line 7. 이것은 문제의 문제와 관련이있을 수 있지만 커서가 뒤로 향하고 첫 번째 열을 넘어 서면 나머지 줄에 발생하는 일이 있습니다.
Tom Carpenter

그렇다, 나의 나쁜 나는 그 비트를 놓쳤다. 나는 지금 가버
톰 카펜터

1
당신은 제거하여 다른 9 개 문자를 저장할 수 있습니다 d: 변수를 대신 등과 같이 루프에 대해 [1 0 -1 0] 패턴을 할 4 개 변수를 가진 function o=q(t) u=1;v=0;w=-1;z=0;x=0;y=1;n=1;for s=t if s==9 x=x+2*u-2*v;y=y+2*v+2*u;a=z;z=w;w=v;v=u;u=a;elseif s==10 n=n+1;x=0;y=n;else x=x+u;y=y+v;o(y,x)=s;end end 당신이해야합니다, 그래서 (분명히 코멘트에있는이 모든 라인을 제거 당신은) 내가 한 일을 볼 수 있도록처럼 포맷
톰 목수

@TomCarpenter 그건 .. 정말 못 생겼어 나는 그것을 좋아한다.
Sanchises

5

파이썬 3 272 270 266 262 255 253 244 바이트

I=[]
try:
 while 1:I+=[input()]
except:r=m=0
M=sum(map(len,I))
O=[M*[' ']for _ in[0]*M]
for l in I:
 x=b=0;y=r;a=1;r+=1
 for c in l:
  if'\t'==c:a,b=-b,a;x+=a+2*b;y+=b-2*a
  else:O[y][x]=c
  x+=a;y+=b;m=max(m,y)
for l in O[:m+1]:print(*l,sep='')

\t실제 탭 문자이어야한다.

코드는 먼저 생성, 다소 자크 게이츠의 대답처럼 작동 M에 의해 M그리드 M라인의 길이의 합이다. (매우 많은 양이지만 초과하는 코드를 만듭니다.) 그런 다음 문자를 반복하여 가장 낮은 방문 행을 추적하여 올바른 지점에 배치합니다. 마지막으로 모든 행을 해당 행까지 인쇄합니다.

출력에는 (대개 방대한 양의) 후행 공백과 1 개의 후행 줄 바꿈이 포함됩니다.


3

자바 스크립트 (ES6), (264) 245 바이트

"거대한 공간 그리드 채우기, 채우기 및 자르기"접근 방식을 시도했는데, 이는 다른 것보다 19 바이트 더 짧았습니다.

a=t=>(o=`${' '.repeat(l=t.length)}
`.repeat(l).split`
`.map(q=>q.split``),d=x=y=z=0,s=c=>o[d>2?y--:d==1?y++:y][d?d==2?x--:x:x++]=c,[...t].map(c=>c=='\t'?(s` `,s` `,++d,d%=4,s` `,s` `):c==`
`?(x=d=0,y=++z):s(c)),o.map(p=>p.join``).join`
`.trim())

마지막에서 두 번째 행까지 수정하면 모든 행에서 많은 양의 후행 공백을 제거 할 수 있습니다.

...o.map(p=>p.join``.trimRight())...

여기에서보십시오 :

곧 설명; 제안을 환영합니다!


3

자바 스크립트 (ES6), 180 183

템플릿 문자열을 사용하면 중요하고 계산되는 줄 바꿈이 있습니다.

요청 된 출력을 반환하는 함수입니다 (후행 공백으로 채워짐)

설명 할 것이 거의 없습니다. 줄이 필요에 따라 만들어집니다. 시계 방향 회전에서는 쉽게 관리 할 수 ​​있으므로 방향 변수가없고 x 및 y에 대한 2 오프셋 만 있습니다.dx <= -dy, dy <= dx

Firefox에서 스 니펫을 아래에서 실행 테스트

f=s=>[...s].map(c=>c<`
`?(x+=2*(d-e),y+=2*(e+d),[d,e]=[-e,d]):c<' '?(y=++r,e=x=0,d=1):(t=[...(o[y]||'')+' '.repeat(x)],t[x]=c,o[y]=t.join``,x+=d,y+=e),o=[r=x=y=e=0],d=1)&&o.join`
`

// TEST  

// Avoid evil tabs even in this source 
O.innerHTML = f(`Test case. Here's a tab--->there's a tab--->everywhere a tab--->tab--->this is some more text
blah
blah
blah blah blah blah blah blah--->blaah--->blaah--->blah--->blaaaaah--->blah--->blah--->blah--->blah--->blah`
 .replace(/--->/g,'\t'))
<pre id=O></pre>


모든 언어에 [x, y] = [expr1, expr2]가
있었으면 좋겠습니다

1

파이썬 2, 370 369 368 바이트

각 바이트를 저장 하는 @sanchises@ edc65 에게 감사드립니다 .

J=''.join
u=raw_input().replace('\t','  \t  ')
w=u[:]
G=range(len(u))
d,r=0,[[' 'for _ in G]for _ in G]
u=u.split('\n')
for t in G:
 x,y=0,0+t
 for c in u[t]:
  if c=='\t':d=(d+1)%4
  if c!='\t':
   if c.strip():r[y][x]=c
   if d<1:x+=1
   if d==1:y+=1
   if d==2:x-=1
   if d>2:y-=1
r=r[:max(i for i,n in enumerate(r)if J(n).strip())+1]
for i in r:print J(i).rstrip()

가능한 가장 큰 그리드를 생성 한 다음 문자별로 순환하며 각 탭에서 방향을 전환합니다.


힌트 : if !dif d>2
Sanchises

!d유효한 구문이 아닙니다. @sanchises d>2팁을 주셔서 감사합니다 .
Zach Gates

죄송합니다, 나는 실제로 파이썬을 모른다 :) 그냥 그런 식으로 작동한다고 가정했다.
Sanchises

나도 파이썬을 이해하지 못하지만 d in 0 ... 3, d==0->d<1
edc65

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