확장 탭 (구현 확장 (1))


10

이번 작업은 expand(1)탭을 공백으로 확장 하는 POSIX 유틸리티 의 변형을 구현하는 것 입니다.

프로그램은 tabstop 사양을 취한 다음 표준 입력읽고 입력의 탭 문자를 적절한 양의 공백으로 바꾸어 다음 tabstop에 도달합니다. 결과는 표준 출력 으로 작성 해야합니다 .

탭 스톱 사양

탭 위치 지정은 단일 번호 또는이 tab stop 쉼표로 구분하거나 구성된다. 단일 숫자의 경우 쉼표로 구분 된 목록에서 여러 번 발생한 것처럼 반복됩니다 (예 :로 4작동 4,8,12,16,20,...). 쉼표로 구분 된 목록의 각 항목은 선택적으로 접두사가 붙은 양의 정수 +입니다. +프리픽스는 콤마로 분리 목록의 이전 값에 대한 상대적인 차이를 나타낸다. 목록의 첫 번째 값은 절대적이어야합니다 (예 : 접두사 없음). tabstops는 공백이 아닌 다음 문자 (확장 된 탭 다음)의 열을 지정하며 가장 왼쪽 열은 숫자 0으로 설정됩니다. 탭은 항상 최소한 하나의 공백으로 확장되어야합니다.

입출력

tabstop 사양은 프로그램에 대한 첫 번째 명령 줄 매개 변수로 사용되거나 재량에 따라 표준에서 첫 번째 입력 행 (줄 바꿈으로 종료)으로 읽습니다. tabstop을 읽은 후 EOF가 처리되고 확장 될 때까지 나머지 입력 (이전의 경우 모든 입력). 확장 된 출력은 표준 출력으로 작성해야합니다.

확장 된 모든 탭 스탑 및 모든 입력은 최대 80 열로 가정합니다. 확장 된 모든 탭 스톱이 엄격하게 증가하고 있습니다.


탭 스톱 사양은와 4,6,+2,+8동일 4,6,8,16하며 입력이 모두

ab<Tab>c
<Tab><Tab>d<Tab>e<Tab>f

로 확장 됨 ( 공백을 나타냄)

ab␣␣c
␣␣␣␣␣␣d␣e␣␣␣␣␣␣␣f

01234567890123456   (Ruler for the above, not part of the output)
          1111111

스코어링은 순수한 . 가장 짧은 코드가 승리합니다.

답변:


2

GolfScript ( 77 75 자)

n/(','/{'+'/{~t++}*~:t}%81,{t*}%+:T;{[0\{.9={;T{1$>}?(.)@-' '*}*\)}/;]n+}/;

tabspec 파싱에 매우 만족합니다.

# Split on commas
','/
# For each element:
{
    # Split on '+'
    '+'/
    # We now have either ["val"] or ["" "val"]
    # The clever bit: fold
    # Folding a block over a one-element array gives that element, so ["val"] => "val"
    # Folding a block over a two-element array puts both elements on the stack and executes,
    # so ["" "val"]{~t++}* evaluates as
    #     "" "val" ~t++
    # which evaluates val, adds the previous value, and concatenates with that empty string
    {~t++}*
    # Either way we now have a string containing one value. Eval it and assign to t
    ~:t
}%

그런 다음 80 열의 끝에 도달 할 수있을 때까지 마지막 요소의 배수를 추가합니다.

81,{t*}%+

이것은 탭 스탑을 하나만 지정한 경우 원하는 동작을 제공하며, 사양이 언급되지 않은 경우에만 관련이 있습니다. (NB는 탭 중지 목록을 다시 0으로 설정 한 다음 마지막 구문 분석 된 요소를 반복하지만 목록을 사용할 때 현재 위치보다 큰 첫 번째 요소를 찾기 때문에 관련이 없습니다.)

나머지는 매우 간단합니다.


2

루비 161 145

입력의 첫 번째 줄에서 탭 중지 사양을 읽습니다.

i=t=[]
gets.scan(/(\+)?(\d+)/){t<<i=$2.to_i+($1?i:0)}
81.times{|j|t<<j*i}
while gets
$_.sub!$&," "*(t.find{|s|s>i=$`.size}-i)while~/\t/
print
end

편집 : 단일 숫자의 탭 스톱 사양도 올바르게 작동하도록 마지막 읽기 탭 스톱을 반복하는 두 줄 추가

i마지막 구문 분석 된 탭 스톱을 보유하기위한 임시 변수입니다. 줄 t에서 구문 분석 된 탭 목록입니다 gets.scan. 좋은 측정을 위해 마지막으로 파싱 된 탭 스톱의 81 배수를 추가합니다. while gets더 이상 입력이 없을 때까지 루프가는 유지합니다. 각 입력 줄에 대해 공백을 추가 할 때 문자열이 이동하기 때문에 한 번에 한 탭씩 공백 대신 탭을 대체합니다. 올바른 탭 스톱을 다시 계산해야합니다.


나는 루비를 잘 모르지만 x+($1?i:0)더 짧게 쓸 수 $1?x+i:x있습니까?
Timwi

@Timwi Nope! 루비는 삼항 연산자에 약간 이상합니다. 보통 콜론 (때문에 당신은 어딘가에있는 공간을 둘 필요 :) 또한의 시작 부분에 표시 할 수 기호를 하지만 기호가 숫자로 시작 할 수 없기 때문에, :0확인을 공백없이입니다. 또는 뭔가. 이상하다. 괄호도 중요합니다.
daniero

그 tabstop 스캐닝은 나에게 버그로 보인다. 에서 t<<x+($1?i:0);i=x첫 번째 문은 변경되지 않습니다 x, 그것을합니까? 나는 당신이 그것을 역 필요가 있다고 생각i=x+($1?i:0);t<<i
피터 테일러

1
실제로 처음 두 줄을 바꾸면 16을 절약 할 수 있습니다 i=t=[]( i처음에 필요하지 않기 때문에 ). 탭 중지 구문 분석을 단순화하고 완전히 {t<<i=$2.to_i+($1?i:0)}제거합니다 l( i이미 해당 값을 보유 함). 그러나 탭 스톱이 엄격하게 증가하는 것에 대해 신경 쓰지 않는 것에 대한 좋은 점은 4 문자를 절약하고 2를 절약하기 위해 빌릴 수 있다는 것입니다.
Peter Taylor

@PeterTaylor 입력 해 주셔서 감사합니다! 직접 버그가 없었지만 확실히 부풀어 오른 것입니다. 나는 이런 코드에 자신을 맹목적으로 응시하는 것이 너무 쉽다는 것을 안다.
daniero jan.

1

C, 228 자

다음은 일을 시작하는 C 솔루션입니다. 여기에서 할 수있는 골프의 많은 (보기는 모든 여전히있다 ifs와 fors와 putchar... s) 등이 있습니다. 동일한 테스트 입력 48탭 스펙에 대한 예제 테스트 케이스로 테스트했습니다 .

S[99],i;L,C;main(v){for(v=1;v;)v=scanf("+%d",&C),v=v>0?C+=L:scanf("%d",&C),
v&&(S[L=C]=++i,getchar());for(;i==1&&C<80;)S[C+=L]=1;for(C=L=0;C=~getchar();)
if(C+10)putchar(~C),L+=C+11?1:-L;else for(putchar(32);!S[++L];)putchar(32);}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.