탭 대 우주 전쟁


24

탭 대 우주 전쟁

따라서 코드를 들여 쓰기 / 포맷하기 위해 탭을 사용할지 공백을 사용할 지에 대한 많은 논쟁이있었습니다. 엄청나게 미친 독특한 형식 지정 방법으로 이동하여 대학이 분쟁을 해결하도록 도울 수 있습니까?


당신의 임무는 모든 탭을 네 개의 공간으로 확장하는 전체 프로그램이나 기능을 작성하는 것입니다. 그런 다음 n 개의 선행 공백을 "/ (n-two stars) /"로 바꿉니다. 합리적인 형식으로 여러 줄에 걸쳐 입력을받습니다 (각 줄마다 줄을 배열하는 문자열, 열 배열 등).

부끄럽게 도난당한 샘플 입력 . SE에서는 탭이 자동으로 4 개의 공백으로 확장되므로 탭을 "^"문자로 나타내지 만 탭 (코드 포인트 0x09)도 처리해야합니다. 모든 "^"문자는 표를 나타냅니다.

Calculate the value 256 and test if it's zero
If the interpreter errors on overflow this is where it'll happen
++++++++[>++++++++<-]>[<++++>-]
+<[>-<
    Not zero so multiply by 256 again to get 65536
    [>++++<-]>[<++++++++>-]<[>++++++++<-]
    +>[>
        # Print "32"
        ++++++++++[>+++++<-]>+.-.[-]<
    <[-]<->] <[>>
        # Print "16"
        +++++++[>+++++++<-]>.+++++.[-]<
<<-]] >[>
    # Print "8"
    ++++++++[>+++++++<-]>.[-]<
<-]<
# Print " bit cells\n"
+++++++++++[>+++>+++++++++>+++++++++>+<<<<-]>-.>-.+++++++.+++++++++++.<.
>>.++.+++++++..<-.>>-
Clean up used cells.
[[-]<]l
^this is preceded by a tab
^^two tabs
^^^three tabs etcetera! 

샘플 출력

Calculate the value 256 and test if it's zero
If the interpreter errors on overflow this is where it'll happen
++++++++[>++++++++<-]>[<++++>-]
+<[>-<
/**/Not zero so multiply by 256 again to get 65536
/**/[>++++<-]>[<++++++++>-]<[>++++++++<-]
/**/+>[>
/******/# Print "32"
/******/++++++++++[>+++++<-]>+.-.[-]<
/**/<[-]<->] <[>>
/******/# Print "16"
/******/+++++++[>+++++++<-]>.+++++.[-]<
<<-]] >[>
/**/# Print "8"
/**/++++++++[>+++++++<-]>.[-]<
<-]<
# Print " bit cells\n"
+++++++++++[>+++>+++++++++>+++++++++>+<<<<-]>-.>-.+++++++.+++++++++++.<.
>>.++.+++++++..<-.>>-
Clean up used cells.
[[-]<]l
/**/this is preceded by a tab
/******/two tabs
/**********/three tabs etcetera! 

대학에 Vim과 Emacs를 모두 다운로드 할 공간이 필요하기 때문에 코드 저장 공간이 거의 없습니다. 따라서 이것은 이며 가장 짧은 코드가 승리합니다. 입력이 올바르게 구성되어 있고 탭을 교체 한 후 공백이 4 개 미만인 줄은 동작이 정의되지 않을 수 있습니다.

기권

이 "우수한"형식화 전략은 Geobits에 의해 제공되었으며 그의 허가에 따라 재생산됩니다. 이 도전 과제를 제작하는 동안 프로그래머는 해를 입지 않았습니다.


1
탭은 줄의 시작 부분에서만 나타 납니까? 줄을 들여 쓰기 할 수 있습니까 (탭 + 공백)?
— Lynn

20
누군가는 공백으로 작성된 답변을 제출하십시오 .
— GuitarPicker

2
로 시작하는 줄을 고려해야합니까 /*, 아니면 "잘 구성된 입력"이 아닌 것으로 간주 될 수 있습니까? C ++ 소스 파일은 여러 /* */줄 주석 이 선행 및 마지막 공백을로 대체 /하고 다음으로 공백을 채우는 일부 답변을 깨뜨릴 수 있기 때문에 더 나은 테스트 였습니다 *.
— seshoumara

1
전쟁은 끝났습니다 : medium.com/@hoffa/… (C로 프로그래밍하지 않는 한)
— 비커

1
@RohanJhunjhunwala 이제 컴파일 가능한 코드가 아니기 때문에 첫 번째 질문을 다시합니다. 동일한 /* */C ++ 코드를 상상해보십시오. 이번에는 줄의 시작 부분에 있습니다. 귀하의 사양에 따라 그대로 유지해야합니다. 여기서 함정은 이미 잘못된 답변을 발견했습니다. 정말과 같은 정규 표현식 /\** /이 별표로 //를 채우는 데 사용 된 것과 같은 정규 표현식 은 줄을로 바꿉니다 /***/. 이 전환도 보았습니다 /*//*/. 나는 둘 다 틀렸다고 가정한다.
— seshoumara

답변:


2

V , 21 , 20 바이트

Íô/    
Î^hr/hv0r*r/

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

이것은 말 그대로 내 vim 답변의 직접적인 포트입니다. 주목할만한 차이점 :

  • Í(글로벌 대체)를 자동으로 채 웁니다 명령 /g2 바이트를 저장 플래그,

  • ô ~와 동일하다 \t

  • Î의 니모닉이며 :%norm, :%norm키 스트로크 사이 와 필요한 키 사이를 채 웁니다 .

  • 끝에 후행 캐리지 리턴이 내재적으로 추가됩니다.


27

Vim, 37, 34, 33, 32 바이트

:%s/\t/    /g|%norm ^hr/hv0r*r/

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

온라인 통역사에는 없지만 vim에는 후행 캐리지 리턴 (입력)이 필요합니다.

이전 버전과 호환되기 때문에 V 인터프리터를 사용합니다. 매우 간단한 솔루션입니다.

솔루션이 실시간으로 발생하는 것을 확인할 수있는 gif입니다. 이것은 약간 오래된 버전을 사용하며 약간의 키 입력을 추가하여 느리게 실행하여 결과를 확인할 수 있습니다.

enter image description here

작동 방식에 대한 설명은 다음과 같습니다.

:%s/\t/    /g           "Replace every tab with 4 spaces
|                       "AND
%norm                   "On every line:
      ^                 "  Move to the first non-whitespace char
       h                "  Move one character to the left. If there is none, the command will end here.
         r/             "  Replace it with a slash
           h            "  Move to the left
            v0          "  Visually select everything until the first column
              r*        "  Replace this selection with asterisks
                r/      "  Replace the first character with a slash

나는 사용하기 위해 +1 g하려고했지만 g : / +1을 사용하지 않도록 편집했다 : D
— Downgoat

@ downgoat Haha, 감사합니다! 실제로 :g알려지지 않은 기능을 남용하기 때문에 버전을 자랑스럽게 생각 합니다. 실패하면 norm명령이 취소됩니다 ^F<space>. 그래서 :%norm ^F<space>foo본질적으로 같은 일이 :g/^ /norm foo재미 빔 해킹. : D
— DJMcMayhem

허, 나는 ^ F가 스크린을 위치 시키는데 사용되었다고 생각했다. 내부에 다른 동작이 norm있습니까?
— Downgoat

1
@ downgoat Haha, ^F아닙니다. <C-f>Silly Vim 키 표기법이 아닙니다 . 이 경우에는 ^공백이 아닌 첫 번째 문자로 F<space>이동하고 커서 뒤의 첫 번째 공백을 찾습니다.
— DJMcMayhem

아, 이제 훨씬 더 의미가 있습니다> _>
— Downgoat

11

펄, 41 바이트

s,␉,    ,g;s,^  ( +),/@{[$1=~y| |*|r]}/,

다음과 같이 -p플래그로 실행하십시오 .

perl -pe 's,␉,    ,g;s,^  ( +),/@{[$1=~y| |*|r]}/,'
#     ↑   └───────────────────┬───────────────────┘
#     1 byte               40 bytes

␉탭으로 교체하십시오 Control-V Tab. Bash에서을 입력하십시오 .


1
perl그 역 참조를 그 자리에서 대체 한 방법도 그랬 으면 좋겠다 sed.
— seshoumara

7

체다 , 60 57 56 바이트

@Conor O'Brien 덕분에 3 바이트 절약

@.sub(/\t/g," "*4).sub(/^ +/gm,i->"/"+"*"*(i.len-2)+"/")

체다가 더 나은 문자열 형식을 갖기를 바랍니다.

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

설명

이것은 기능입니다. `ar.map (@. head (-1)) 같은 기능을 수행 할 수있는 @기능화 된 속성 (예 : ruby ​​'s &:)을 나타냅니다 .

@                      // Input
 .sub( /\t/g, " "*4)   // Replace tabs with four spaces
 .sub(
   /^ +/gm,            // Regex matches leading spaces
   i ->                // i is the matched leading spaces
     "/"+              // The / at the beginning
     "*"*(i.len-2)+    // Repeat *s i-2 times
     "/"                // The / at the end
 )

정규식에 익숙하지 않은 경우 다음을 수행하십시오.

/^ +/gm

이것은 기본적으로 모든 ( ) 의 시작 ( ) 에서 하나 이상의 +공백 ( ) 과 일치 합니다 ( ).^gm


체다 탭에서 리터럴 탭이 작동합니까? 또한 /^ +/선행 공간의 길이가 4 이상이라고 가정 할 수 있기 때문에 정규 표현식으로 충분합니다.
— 코너 O'Brien

@ ConorO'Brien 나는 그들이 믿지만 테스트하지 않았습니다
— Downgoat

변환 전에 탭을 교체해야합니다.
— 코너 O'Brien

@ ConorO'Brien oh> _> 나는 원래 그런 식으로 그것을 가지고 그것을 변경
— Downgoat

6

수학, 97 바이트

a=StringReplace;a[a[#,"\t"->"    "],StartOfLine~~b:" "..:>"/"<>Table["*",StringLength@b-2]<>"/"]&

익명의 기능. 문자열을 입력으로 받아서 문자열을 출력으로 반환합니다.


5

파이썬 3, 124 바이트

좋은 ol '정규식을 사용합니다.

import re
lambda I:re.sub('^\s*(?m)',lambda m:'/'+'*'*len(m.group()[:-2])+'/',re.sub('\t+',lambda g:' '*4*len(g.group()),I))

무시 했어!


4

자바 (210) 207 바이트

이것이 순진하게 구현하는 참조 솔루션입니다.

void a(String[]a){for(String s:a){s=s.replaceAll("\t", "    ");String x,y="";int j,i=s.length()-(x=s.replaceAll("^\\s+", "")).length();if(i>3){y="/";for(j=0;j++<i-1;)y+="*";y+="/";}System.out.println(y+x);}}

6
Vim : 37 바이트, 체다 : 65 바이트, JavaScript : 75 바이트, 210 바이트에 Java가 있습니다 : P 왜 놀랍지
— 않습니까

1
자바에서 매우 간결한 코드 : P
— 로한 Jhunjhunwala

1 바이트를 저장하기 위해 마지막 for-loop를 변경할 수 있습니다 for(int j=0;++j<i-1;). 또한 int before 를 제거하고 j이미 존재하는 int 뒤에 넣을 수 있습니다.int i=s.length()-(x=s.replaceAll("^\\s+", "")).length(),j;
— Kevin Cruijssen

(a)-> {...}를 사용하여 바이트를 면도하는 람다가 될 수 없습니까?
— bunyaCloven

적어도 그것은 여전히 ​​읽을 수 있고 더 이상의 주석이 필요하지 않습니다 : o)
— René

3

자바 스크립트 ES6, 75 바이트

s=>s.replace(/\t/g,"    ").replace(/^ +/gm,k=>`/${"*".repeat(k.length-2)}/`)

교체 \t코드에서 문자 탭.


3

자바 185 184 167 152 바이트

S->S.map(s->{s=s.replace("\t","    ");String t=s.replaceAll("^ +","");int n=s.length()-t.length();if(n>3){s="/";for(;n-->2;)s+="*";s+="/"+t;}return s;})

초기 게시물에서 주어진 문자열 배열의 정의가 매우 느슨 Stream<String>하기 때문에 결과적으로 바이트를 절약 할 수 있습니다.

같은 목표를 달성하기 위해 RI와 다른 기술을 사용했습니다. 알고리즘 자체는 다소 동일합니다.

테스트 및 ungolfed :

import java.util.Arrays;
import java.util.stream.Stream;

public class Main {

  public static void main(String[] args) {
    StringStreamTransformer sst = lines -> lines.map(line -> {
      line = line.replace("\t","    ");
      String trimmed = line.replaceAll("^ +", "");
      int startingSpaces = line.length() - trimmed.length();
      if (startingSpaces > 3) {
        line = "/";
        for(;startingSpaces > 2; startingSpaces--) {
          line += "*";
        }
        line += "/" + trimmed;
      }
      return line;
    });


    Stream<String> lines = Arrays.stream(new String[]{
      "lots of spaces and tabs after\t\t    \t\t         \t\t\t\t\t",
      "no space",
      " 1 space",
      "  2 spaces",
      "   3 spaces",
      "    4 spaces",
      "     5 spaces",
      "      6 spaces",
      "       7 spaces",
      "        8 spaces",
      "\t1 tab",
      "\t\t2 tabs",
      "\t\t\t3 tabs"
    });
    sst.map(lines).map(s -> s.replace(" ", ".").replace("\t","-")).forEach(System.out::println);


  }
}

2

망막 , 25 바이트

는 \t실제 탭 문자 (은 0x09)로 교체해야합니다.

\t
4$* 
%`^  ( +)
/$.1$**/

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

설명

\t
4$* 

각 탭을 4 개의 공백으로 바꾸십시오.

%`^  ( +)
/$.1$**/

줄 의 시작 부분에 공백을 %일치 2+N시키고를 사본이 /.../있는 위치 ...로 바꾸어 각 줄을 개별적으로 변환하십시오 ( ) .N*



2

SED (-r의 경우 56 + 1) 57

s/⇥/    /g;tr;:r;s,^ ( *) ,/\1/,;T;:l;s,^(/\**) ,\1*,;tl

어디 ⇥탭입니다
공백 1. 대체합니다 탭.
2. 첫 번째와 마지막 선행 공간을로 바꿉니다 /.
3. /및 0+ *s 이후의 첫 번째 공백 *이 일치하지 않을 때까지 대체합니다 .


sed가 지정되었으므로 다른 sed 답변에서 -r ''을 제거하는 것과 마찬가지로 코드 주위에 작은 따옴표가 필요하지 않습니다. 스크립트는 -f. n 또는 r과 같은 추가 플래그는 각각 1 바이트로 계산해야합니다. 따라서 여기에서는 2 바이트를 저장합니다.
— seshoumara

그것이 제가 생각한 것이지만 확실합니다. 감사.
— 라일리

;T 명령 후 어느 필요가 없습니다. 코드 자체는 세 번째 s명령 의 시작 부분에 ^가 필요합니다 . 그렇지 않으면 "3/5"와 같은 입력이 "3 / * 5"로 바뀝니다. 첫 번째 s명령 에는 실제로 탭이 있지만 올바르게 표시되지 않고 오도되기 때문에 \ t를 사용하거나 이후에 지정하면 해당 문자는 탭이었습니다.
— seshoumara

@seshoumara 고마워, 내 휴대 전화에서 게시하려고합니다 ... 가장 쉬운 방법은 아닙니다.
— 라일리

다른 답변을 합한 것 보다이 답변을 편집하는 데 더 많은 시간을 보냈다고 생각합니다. 도와 주셔서 감사합니다!
— 라일리

1

대학은 Emacs Lisp (또는 기본적으로 tabify또는 untabify단독으로) 프로그램 이 Java보다 훨씬 장황하므로 프로그램을위한 더 많은 공간을 허용해야합니다 . 또한 식별 크기가 4보다 작거나 C와 유사한 언어로 코딩하는 학생 (또는 교사)에게 세심한주의를 기울여야합니다.

다음 솔루션은 206 바이트입니다.

(lambda (b e)(let((tab-width 4))(untabify b e)(goto-char b)(while(re-search-forward"^ +"e t)(replace-match(format"/%s/"(apply'concat(mapcar(lambda(x)"*")(number-sequence 1(-(length(match-string 0))2)))))))))

tab-width명시 적으로 설정할 필요가 없다고 가정하면 20 개를 절약 할 수 있습니다.

(lambda(b e)(untabify b e)(goto-char b)(while(re-search-forward"^ +"e t)(replace-match(format"/%s/"(apply'concat(mapcar(lambda(x)"*")(number-sequence 1(-(length(match-string 0))2))))))))

그리고 ungolfed 버전은 다음과 같습니다

(defun end-tab-war (beg end)
  (let ((tab-width 4))
    (untabify beg end)
    (goto-char beg)
    (while (re-search-forward "^ +" end t)
      (replace-match
       (format
        "/%s/"
        (apply 'concat
               (mapcar (lambda(x) "*")
                       (number-sequence 1
                                        (- (length (match-string 0))
                                           2)))))))))

우리는 먼저 untabify 는 시작하기 전에 지역을 시작합니다. 그런 다음 줄의 시작 부분에 공백이있는 반면 공백이있는 주석으로 대체합니다. 정확히 말하면 삽입되는 주석은 다음과 같이 구성됩니다.

 (format"/%s/"(apply'concat(mapcar(lambda(x)"*")(number-sequence 1(-(length(match-string 0))2)))))

자체는 97 바이트를 차지합니다. 일부 문자열을 n 번 복사하는 더 짧은 솔루션이 높이 평가됩니다.


1

루비, 52 47 + 1 (p 플래그) = 48 바이트

편집 : Value Ink 덕분에 전체 5 바이트 저장

ruby -pe 'gsub ?\t," "*4;sub(/^ +/){?/+?**($&.size-2)+?/}'

1
p플래그를 사용하여 (g) sub $_가 인쇄 된 값을 수정 하여 변경 한다는 사실을 이용할 수 있습니까 ? ruby -pe 'gsub ?\t," "*4;sub(/^ +/){?/+?**($&.size-2)+?/}'
— Value Ink

고마워, 나는 (g)subbang 이 없으면 $_여기서 수정할 수 있다는 것을 몰랐다 .
— michau

1

GNU sed, 66 64 + 1 (r 플래그) = 65 바이트

편집 : Riley 의 제안 덕분에 1 바이트가 적습니다 .

s/\t/    /g
s,^ ( *) ,/\1\n,
:
s,^(/\**) ( *\n),\1*\2,
t
s,\n,/,

운영: sed -rf formatter.sed input_file

로 분리하는 이유는 \n그렇지 않으면 C ++ 라인이 같은 코멘트로 시작하기 때문에 그 행의 텍스트의 나머지 부분에서 최고의 공간입니다 /* */으로 회전을 것 /*****/같은 단순한 라인 4 s,^(/\**) ,\1*,또는 s,^(/\**) ( */),\1*\2,. sed는 각 입력 라인에 대해 스크립트를 실행하므로 \n읽을 때 패턴 공간에 no 가 도입 되지 않습니다 .


/를 교체 할 때까지 닫기를 넣지 않으면 바이트를 절약 할 수 있습니다 \n. 4 번 라인에서 일치시킬 필요가 없습니다.
— Riley

@Riley 잘 잡아라. 코드를 업데이트했습니다.
— seshoumara

\t탭 문자 로 바꾸어 다른 문자를 저장할 수 있습니다 .
— 라일리

@Riley 사실이지만 탭으로 인쇄되지 않기 때문에 의심 스럽다. 바이트 수를보다 경쟁력있는 미래의 sed 답변에 대해이 점을 명심하십시오.
— seshoumara
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.