세상에, 그것은 탭으로 덮여 있습니다!


26

공간 들여 쓰기 사용자, 단결 ! 우리는 모든 탭 사용자들 과 싸워야 합니다 !

당신의 임무는 (당신이 그것을 받아들이도록 선택해야합니다) 두 가지 주장을 취하는 프로그램이나 함수를 작성하는 것입니다 :

  • 문자열 : 입력입니다.
  • 양의 정수 : 탭당 공백 수입니다.

문자열의 모든 줄을 통과하고 들여 쓰기에 사용 된 모든 탭을 지정된 수의 공백으로 바꾸고 들여 쓰기 에 사용되지 않은 모든 탭 (예 : 줄 중간)을 한 칸의 공백으로 바꿔야 합니다.

같은 행 \t \tabc은 정의되지 않은 동작입니다. 그들은 사악한 탭 사용자에 의해 삽입되어 프로그램을 복잡하게합니다.

탭 다이 소 소사이어티 (Tabs Must Die Society)에 따르면, 악의 탭 사용자가 감지하지 못하도록 프로그램은 가능한 짧아야합니다.

\t 여기서 탭을 나타내는 데 사용됩니다.

입력 문자열 :

a
\t\tb\tc
d

입력 번호 :

4

산출:

a
        b c
d

가운데 줄은 탭당 4 개씩 8 개의 공백으로 들여 쓰기되었습니다 (주어진 숫자는 4이므로).

입력 문자열 :

\ta\t\tb

입력 번호 :

4

산출:

    a  b

참고 : 이것은 탭 확장 문제 와 중복 되지 않습니다 . 매우 다른 입력 형식과 약간 다른 요구 사항이 필요합니다.


1
, 질문에서 명시 적으로 십진수를 요구하지 않는 한 (그렇지 않습니다).
마틴 엔더


1
입력에 인쇄 가능한 ASCII, 탭 및 줄 바꿈 만 포함되어 있다고 가정 할 수 있습니까?
Dennis

2
제안 된 테스트 사례 : \ta\t\tb, 4(이전 개정판이 실패했습니다)
Dennis

2
공백에 답이 필요합니다.
Kaz Wolfe

답변:


7

CJam, 30 24 23 바이트

q{_9=NA=Seasi*' ?@?:N}/

인터넷에 악성 코드를 게시하는 것을 거부합니다.

STDIN에서 문자열과 숫자를 명령 줄 인수로 읽는 전체 프로그램입니다.

CJam 통역사 에서 온라인으로 사용해보십시오 .

작동 원리

q                        Read all input from STDIN.
 {                   }/  For each character C in the input:
  _9=                      Push 1 if C is a tab and 0 otherwise.
     NA=                   See below.
        Seasi*             Push a string of W spaces, where W is the integer from
                           the command-line arguments.
              '            Push a spaces character.
                ?          Select the string if NA= pushed a truthy value, the
                           single space otherwise.
                 @         Rotate C on top of the stack.
                  ?        Select the string of spaces or the single space if _9=
                           pushed 1, the character C otherwise.
                   :N      Save the result in N.

무엇을 하는가 NA=:

  • 첫 번째 문자의 경우 N기본값 인 문자열이 포함 "\n"됩니다.

    모든 후속 문자 N의 경우 마지막 반복 결과, 즉 입력의 마지막 문자, 공백 문자 또는 하나 이상의 공백 문자열이 포함됩니다.

  • N문자열 인 경우 NA=N의 인덱스 10에서 요소를 선택합니다 (랩핑). 결과는 공백 또는 줄 바꿈 문자입니다. 둘 다 진실입니다.

    N이 문자이면 NA=줄 바꿈을 위해 1을, 그렇지 않으면 0을 누릅니다.

  • 위의 때문에 NA=첫 번째 문자, 줄 바꿈 문자 앞에 오는 문자 또는 공백 문자열 앞에 오는 문자 (이미 대체 된 들여 쓰기)에 대해 진실한 값을 푸시합니다.

    다른 모든 경우 (공백 문자 로 대체 된 tabulator 포함 ) NA=는 잘못된 값을 푸시합니다.


6
악성 탭을 제거하여 인터넷에 서비스를 제공하는 것이 좋습니다. ;)
Alex A.

19

K5, 53 45 바이트

{{,/(b+a&~b:x*&\a:9=y){$[x;x#" ";y]}'y}[x]'y}

실제로 :

  {{,/(b+a&~b:x*&\a:9=y){$[x;x#" ";y]}'y}[x]'y}[4;(,"a";"\t\tb\tc";,"d")]
(,"a"
 "        b c"
 ,"d")

나는 단지이 질문이 도덕적으로 이해할 수 있음을 보여주는 기록을 원한다.


11
의 경우 -21346106841... this question is morally reprehensible.
TheNumberOne

3
이것은 사람들이 각주를 볼 수 있도록 가장 많이 투표 된 답변을 끝내야합니다.
Geobits

3 바이트 인쇄하지 않고 결과를 반환 할 수 있습니다.
kirbyfan64sos

1
@ kirbyfan64sos : 줄을 연결하지 않아도되도록 결과를 인쇄하고 있습니다. 결과를 각 줄마다 하나씩 문자열 목록으로 받아들이고 반환 할 수 있으면 저장 `0:하고` "\ n"\`할 수 있습니다.
JohnE

@JohnE 나는 할 수 없다는 규칙을 제시하지 않았으므로 할 수 있다고 추측합니다. :)
kirbyfan64sos

8

펄, 23 바이트

22 바이트 코드 + 1 바이트 명령 줄

숫자 입력이 -i 매개 변수를 통해 제공 될 수 있다고 가정하기에는 너무 건방진하지 않기를 바랍니다! 아래 코드에서 \ t를 실제 탭 문자로 바꾸십시오.

s/\G\t/$"x$^I/ge;y/\t/ /

사용 예 :

printf "a\n\t\tb\tc\nd" | perl -p entry.pl -i4

또는 편의상 :

printf "a\n\t\tb\tc\nd" | perl -pe 's/\G\t/$"x$^I/ge;y/\t/ /' -i4

설명:

-p인수를 사용하면 입력의 모든 행에 대해 프로그램을 실행 한 다음 끝에 결과를 인쇄합니다.

위의 예에서 정규식 대체는 (4 번 반복되는 공백)으로 대체 \G\t됩니다 " "x4. \G첫 번째 반복의 경우 첫 번째 일치 위치 또는 첫 번째 반복이 아닌 경우 이전 일치의 위치와 일치하는 잘 알려진 정규 표현식 구조입니다. 즉, 문자열의 시작 부분에서 모든 탭만 대체합니다. 하나씩 수행하십시오. 은 y/\t/ /단순히 공백으로 남아있는 모든 탭을 대체합니다.


2

줄리아, 69 59 바이트

f(s,n)=(r=replace)(r(s,r"^\t*"m,i->" "^endof(i)n),"\t"," ")

언 골프 드 :

function f(s::String, n::Int)
    # Replace the leading indentation tabs
    r1 = replace(s, r"^\t*"m, i -> " "^endof(i)n)

    # Replace any remaining tabs between words
    r2 = replace(r1, r"\t", " ")

    # Return
    r2
end

Glen O! 덕분에 10 바이트를 절약하고 문제를 해결했습니다.


선행 들여 쓰기 탭을 별도로 교체하면 어떤 이점이 있습니까? "나머지 탭"부분에서 직접 처리해야하는 것 같습니다. 또한 "텍스트 사이의 탭 교체"부분은 단일 탭과 만 일치합니다 "hello\t\t1".
Glen O

모든 들여 쓰기가 탭으로 수행되는 것으로 가정하면 ( "\t \t"상황 없음 ) 다음을 수행 할 수 있습니다.이 f(s,n)=(r=replace)(r(s,r"^\t*"m,i->" "^endof(i)n),"\t"," ")기능은 대체 기능을 사용하고 모든 들여 쓰기 탭을 한 번에 잡을 수 있습니다.
Glen O

@GlenO 와우, 정말 천재입니다. 정말 고마워!
Alex A.

내 답변이 다운 보이는 것을 알았습니다. 내가 잘못한 것이 있습니까? 문제를 해결해 드리겠습니다.
Alex A.

문제가 없습니다. 어쩌면 언어가 마음에 들지 않기 때문에 공감하는 그러한 판결 유형 중 하나일까요? 결함이 보이지 않습니다.
Glen O

2

하스켈, 82 바이트

n!('\t':x)=([1..n]>>" ")++n!x
n!x=f<$>x
f '\t'=' '
f x=x
g n=unlines.map(n!).lines

그런 다음 g 3 "a\n\t\tb\tc\nd"일을합니다.



2

수학, 42 37 바이트

여러 코드 절약 제안에 대한 @ LegionMammal978 덕분입니다. 첫 번째 매개 변수 #는 입력 텍스트, 두 번째 매개 변수 #2는 탭당 공백 수입니다.

StringReplace[#,"\t"->" "~Table~{#2}]&

또한, 변경 Table[" ",{#2}]하는 " "~Table~{#2}바이트를 저장합니다. StringJoin빈 줄을 왜 그 위에 꽂고 있습니까?
LegionMammal978

1

루비 49 바이트

def r s,t;s.gsub! /^\t/,' '*t;s.gsub!"\t",' ';end

2
줄의 시작 부분에 두 개의 탭이 있으면 작동하지 않습니다.
찰스

1

자바 스크립트 (ES6), 70

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

(s,n,r=n)=>[...s].map(c=>c<`
`?` `.repeat(r):(r=c<` `?n:1,c)).join``

Firefox에서 아래 스 니펫을 테스트하십시오.

F=(s,n,r=n)=>[...s].map(c=>c<`
`?` `.repeat(r):(r=c<` `?n:1,c)).join``

// TEST
out=x=>O.innerHTML+=x+'\n\n'

out('Input: "A\\n\\t\\tB\\tC\\nD" 4\nOutput:\n'+F('A\n\t\tB\tC\nD',4))

out('Input: "\\tA\\t\\tB" 4\nOutput:\n'+F('\tA\t\tB', 4))
<pre id=O></pre>


1
와우 하나 downvote! 'Firefox에서 테스트'를 읽거나 이해할 수없는 사람 일 수 있습니까?
edc65

언어 편견이 의심됩니다. Julia와 CJam도 다운 보트를 받았습니다.
Dennis

1

CoffeeScript, 72 바이트

(s,n)->s.replace(/^\t+/mg,(m)->" ".repeat(m.length*n)).replace /\t/g," "

(적어도 2 번 이상 골프를 치려고 시도하면 ES6 솔루션을 이길 것입니다.

용법:

f=(s,n)->s.replace(/^\t+/mg,(m)->" ".repeat(m.length*n)).replace /\t/g," "
str="""
My nice\tString
\tIndent <--
\t\tDouble
""" #\t is recognized as tab by CS
alert(f(str,4))

1

레티 나, 42 바이트

모든 항목 .은 공백이며 모두 \t리터럴 탭 (1 바이트)이며 <empty>빈 파일을 나타냅니다. 가독성을위한 것입니다. 또한 루프를 올바르게하고 있는지 완전히 확신하지는 못하지만 그렇게 생각합니다. 각 줄은 자체 파일에 있어야합니다. 추가 파일마다 1 바이트를 추가했습니다.

입력은 입력 끝에서 자체 행에 단항으로 가정됩니다.

(1*)$
_$1
m+`(?<!^|\t)\t
.
(`1$
<empty>
)`\t
\t.
\t|_
<empty>

설명

_대체 중에 입력을 구분하기 위해 단항 입력 앞에 a 를 추가 하여 입력 문자열에서 후행 입력을 제거하지 않습니다. 그런 다음 줄의 시작 부분이 아닌 모든 탭을 단일 공백으로 바꿉니다. 그런 다음 1입력이 부족해질 때까지 루프를 실행하여 단일 탭을 제거하고 각 탭 뒤에 단일 공백을 추가합니다. 마지막으로 탭과 밑줄을 제거하여 정리합니다.


1

파이썬, 72 68 바이트

탭은 리터럴 탭 (1 바이트)이므로 r'...'필요하지 않습니다. 불행히도, 파이썬은 "고정 너비"룩-비하인드 / 룩어 헤드가 필요하므로 사용할 수 없습니다 (?<!^|\t). Retina 솔루션과 거의 동일한 방법을 사용합니다.

import re
lambda s,n:re.sub('\t',' '*n,re.sub('(?<!^)(?<!\t)\t',' ',s))




0

하스켈 , 75 바이트

s#m|let('\t':r)#n=(' '<$[1..n])++r#n;(x:r)#n=x:r#(m^sum[1|x<' ']);e#_=e=s#m

온라인으로 사용해보십시오! 주석에 OP에서 허용하는대로 입력에 인쇄 가능한 문자와 탭 및 줄 바꿈 만 포함되어 있다고 가정합니다.

설명:

외부 #함수는 문자열 s과 숫자를 사용하고 동일한 인수를 사용하여 m로컬로 정의 된 내부 #함수를 호출합니다 . m내부 #함수가 숫자를 변경 함에 따라 원래 값을 추적하기 위해 수행됩니다 .

  • ('\t':r)#n=(' '<$[1..n])++r#n탭이 있으면 n공백으로 바꾸고 n변경하지 마십시오.
  • (x:r)#n=x:r#(m^sum[1|x<' '])x탭이 아닌 일부 가 발견되면 그대로 유지하지만 줄 바꿈 이면 n원래 번호로 설정 하십시오 . 이것은 다음에 의해 수행됩니다 : 공간보다 작을 때 (즉, 줄 바꿈) 평가 되는 힘을 가져옵니다 . 그렇지 않으면 그건 우리가 있습니다 .mx1m^sum[1|x<' ']msum[1|x<' ']1xm^1 = m0m^0 = 1

0

자바 11, 134 바이트

n->s->{var r="";for(var p:s.split("\n")){for(;p.charAt(0)==9;p=p.substring(1))r+=" ".repeat(n);r+=p+"\n";}return r.replace('\t',' ');}

온라인으로 사용해보십시오.
참고 : Java 11은 아직 TIO에 있지 않으므로 동일한 바이트 수로 대신 " ".repeat(n)에뮬레이션되었습니다 repeat(" ",n).

설명:

n->s->{                 // Method with integer & String parameters and String return-type
  var r="";             //  Result-String, starting empty
  for(var p:s.split("\n")){
                        //  Loop over the rows (split by new-lines)
    for(;p.charAt(0)==9;//   Inner loop as long as the current row starts with a tab
       p=p.substring(1))//     After every iteration: remove the first character (tab)
      r+=" ".repeat(n); //    Append `n` amount of spaces to the result-String
    r+=p+"\n";}         //   Append the rest of the row with a newline to the result
  return r.replace('\t',' ');} 
                        //   Replace any remaining tabs with a space, and return the result
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.