브레이스를 오른쪽 브레이스로 변환 (슬픈 브레이스)


26

오른쪽 괄호는 중괄호와 세미콜론이 모두 파일의 오른쪽에있는 단일 지점에 정렬되는 스타일의 코드 괄호입니다.

예시 이미지 여기로 이동

일반적으로 이것은 여러 가지 이유로 나쁜 습관으로 간주됩니다.

도전

모든 방법을 통해 여러 줄 문자열을 가져와 중괄호 스타일을 오른쪽 브레이스로 변환하십시오.

이 문제를 해결하려면 Java 코드 작업 만하면되지만 이론적으로 Braces와 Semicolon을 사용하는 모든 코드에서 작동해야합니다.

{};공백 사이에 공백이없는 한 행의 모든 문자를 가져와야합니다. EG. }},, ; } }\n\t\t}공백을 사용하여 파일의 오른쪽에 정렬하십시오.

예를 들면 다음과 같습니다.

a {
b;
{c

되어야한다

a {
b ;{
c

또는 더 추상적으로 모든 {};문자 의 왼쪽에서 오른쪽으로 공백을 밀어 넣으십시오 .

그렇지 않으면 줄 들여 쓰기를 유지해야합니다. 문자 이동 후 공백 만 포함 된 행 {};은 선택적으로 제거 할 수 있습니다.

예를 들면 다음과 같습니다.

a{
    b{
        c;
    }
}
d;

어느 쪽이든 될 수 있습니다

a        {
    b    {
        c;}}
d        ;

또는

a        {
    b    {
        c;}}


d        ;

오른쪽으로 밀면 모든 {};문자가 가장 긴 줄보다 짧은 지점에 정렬되는 것을 나타냅니다 . 그 이후의 모든 공간은 허용됩니다.

따라서 아래의 모든 것이 허용됩니다.

a {
bc;

a  {
bc ;

a   {
bc  ;

기타...

모든 코드의 행에는 {};다른 비월 공백 문자 사이의 문자 가 포함될 수 있지만이 경우를 처리 할 필요는 없지만 기울어지면 그대로 두어야합니다. 줄에는 {};문자가 전혀 포함되지 않을 수 있으므로 올바르게 처리해야합니다. 아래와 같이.

a {
b ;
c
d }

우리는 Code Review 가 끔찍한 일을보고 싶지 않기 때문에 코드를 최대한 작게 만들어야합니다.

예제 / 테스트 케이스

일반 자바

public class HelloWorld{
       public static void main(String[] args){
           System.out.println("Hello, World!");
       }
}

된다 ...

public class HelloWorld                        {
    public static void main(String[] args)     {
        System.out.println("Hello, World!")    ;}}

이미지 자체

public class Permuter{
    private static void permute(int n, char[] a){
        if (n == 0){
            System.out.println(String.valueOf(a));
        }else{
            for (int i=0; i<= n; i++){
                permute(n-1, a);
                swap(a, n % 2 == 0 ? i : 0, n);
            }
        }
    }
    private static void swap(char[] a, int i, int j){
        char saved = a[i];
        a[i] = a[j];
        a[j] = saved;
    }
}

된다 ...

public class Permuter                                {
    private static void permute(int n, char[] a)     {
        if (n == 0)                                  {
            System.out.println(String.valueOf(a))    ;}
        else                                         {
            for (int i=0; i<= n; i++)                {
                permute(n-1, a)                      ;
                swap(a, n % 2 == 0 ? i : 0, n)       ;}}}
    private static void swap(char[] a, int i, int j) {
        char saved = a[i]                            ;
        a[i] = a[j]                                  ;
        a[j] = saved                                 ;}}

그렇게 완전하지 않은 파이썬

대조적으로

def Main():
    print("Hello, World!");

Main();

된다 ...

def Main():
    print("Hello, World!")    ;
Main()                        ;

노트

  • 표준 허점 적용
  • 표준 IO 적용
  • 이것은 이므로 바이트 단위의 가장 짧은 프로그램이 승리합니다!
  • Right Brace 스타일의 프로그래밍과 관련된 손해에 대해 책임을지지 않습니다
  • 즐기세요!

메모 수정

나는 도전 세부 사항을 다시 말했지만, 규칙에 대한 다른 사람의 견해를 깨뜨리지 않기를 바랍니다. 이것은 훨씬 명확하고 덜 충돌하는 사양이어야합니다.


세미콜론이 여러 개인 라인에 대한 평결은 무엇입니까? 뭔가 같은int a=0;System.out.println(a);
값 잉크

2
샘플 이미지와 같이 루프를 처리 할 필요가 없다면 도전에 가장 적합한 이미지가 아닐까요?
데니스

1
질문의 이미지처럼 보인다는 온 이 예 에 의해 하였다, 이 후속 더 복잡한 예제를 가지고
레이 톨

2
;{}별도의 줄에있는 경우 문자를 모으는 것이 더 명확해질 수 있습니다 (규칙이 아닌 예제에서만 명확하며 실제로 줄 \t}이 들여 쓰기 를 유지하는 경우 끝까지 이동 하지 않음 을 의미 }합니다)
Chris H

2
좋은 신, 실제로 아무도 Java와 같은 장황한 언어에 대해 실제로 이것을하지 않는다고 말해주십시오.
Magic Octopus Urn

답변:


5

V + Bash 유틸리티, 64 62 61 60 62 바이트

ex 명령을 결합한 @DJMcMayhem 덕분에 1 바이트 절약

:se ve=all|%!wc -L
y$uò/^ *<93>[{};]
xk$pòò/<84> {};][{};]«$
lDî^R0|p

^R의 문자 리터럴 <C-r>( 0x12)하고 <84>있습니다 0x84<94>입니다 0x94.

wc -L대부분의 * nix 기반 시스템에서는 작동하지만 macOS에서는 작동하지 않습니다. macOS의 gwc -L 경우 아직 brew를 사용하여 coreutils를 가져온 후 수행해야 합니다.

온라인으로 사용해보십시오! (자바)

온라인으로 사용해보십시오! (파이썬)

온라인으로 사용해보십시오! (자바 다시)

이렇게하면 모든 빈 줄이 유지되고 탭은 처리하지 않고 공백 만 처리합니다.

16 진 덤프 :

00000000: 3a73 6520 7665 3d61 6c6c 7c25 2177 6320  :se ve=all|%!wc 
00000010: 2d4c 0a79 2475 f22f 5e20 2a93 5b7b 7d3b  -L.y$u./^ *.[{};
00000020: 5d0a 786b 2470 f2f2 2f84 207b 7d3b 5d5b  ].xk$p../. {};][
00000030: 7b7d 3b5d ab24 0a6c 44ee 1230 7c70       {};].$.lD..0|p

설명

먼저 버퍼의 아무 곳이나 커서를 움직일 수 있어야합니다.

:se ve=all|...

우리는 이것을 사용하여 다른 ex 명령과 연결합니다 |

입력에서 가장 긴 줄의 길이를 가져와야합니다. 쉘 명령으로 수행 할 수 있습니다 wc -L.

       ...|%!wc -L

현재 버퍼 (입력 포함)를 결과로 덮어 씁니다 wc -L. 다음과 같은 출력을 제공합니다.

            42

커서가 4in에 위치 42합니다. 그런 다음 y$커서 위치에서 줄 끝까지 : yank text를 사용하여이 숫자를 복사합니다. 이것은이 번호를 레지스터에 편리하게 저장합니다 0. 그러나 나중에 더. 입력은이 숫자로 대체되므로 되돌릴 수 u있습니다.

이제 입력이 다음과 같다고 가정하십시오.

public class HelloWorld{
    public static void main(String[] args){
        System.out.println("Hello, World!");
    }
}

}버퍼의 끝에서 println명령문 바로 뒤에 중괄호를 이동해야 합니다.

ò                  " recursively do this until a breaking error:
 /^ *<93>[{};]     "   this compressed regex becomes /^ *\zs[{};]
                   "   this finds any character from `{};` after leading spaces
                   "   the cursor then goes to the `{};`

x                  "   delete character
 k$                "   go to the end of the line above
   p               "   and paste
    ò

정규식을 찾을 수 없으면, 오류가 발생하여에 의한 재귀가 중단됩니다 ò.

이제이 프로그램의 주요 부분이 나오고 모든 중괄호와 세미콜론을 옮기고 질문에 명시된대로 정렬하십시오.

ò                  " starts recursion
 /<84> {};][{};]«$ "   compressed form of [^ {};][{};]\+$
                   "   finds a sequence of `{};`s at the end of the line with a non-`{};` char to preceding it
 l                 "   move the cursor 1 to the right (since we were on the non-`{};` char now)
  D                "   delete everything from this position to the end of line
                   "   the deleted text contains `{};`
   î               "   execute as normal commands:
    ^R0            "   contains what's in register `0`, ie the length of the longest line
       |           "   now go to the column specified by that number
        p          "   and paste the contents 
                   " implicit ending `ò`

다시,이 재귀는 정규식을 버퍼에서 찾을 수 없을 때 발생하는 중단 오류로 인해 중지됩니다.

편집

  • D대신에 사용됨 d$(처음에 왜 그것을 놓친 지조차 모르겠습니다)
  • [^(정규식에서) 압축<84>
  • 를 사용하여 \zs압축 <93>하고를 제거 하여 버그를 수정 $했습니다.$xk$pò
  • 쓸모없는 줄 바꿈 제거
  • 새로운 규칙을 준수하도록 제출을 변경하고 2 바이트를 얻었습니다.

ex 명령을 함께 결합하면 1 바이트를 절약 할 수 있습니다.:se ve=all|%!wc -L
DJMcMayhem

@DJMcMayhem 감사합니다, TIL
Kritixi Lithos

4

루비, 100 (114) 108 바이트

파일 이름을 명령 행 인수로 읽습니다. 파일 이름이 제공되지 않으면 STDIN에서 읽습니다. 탭을 처리하지 않습니다.

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

f=$<.read.gsub(/[\s;{}]*$/){$&.tr"
 ",''}
$><<f.gsub(/(.*?)([;{}]+)$/){$1.ljust(f.lines.map(&:size).max)+$2}




@Pavel에게 알려 주셔서 감사합니다. 파일로 파이핑 한 후 보았던 두 가지 문제 catch는 코드에서 가장 긴 줄에 A. 들여 쓰기 명령문과 B. 세미콜론이 너무 많이 들여 쓰기되었습니다. 나는 그것을 고칠 필요가있는 것을 알고 있다고 생각합니다. (또한 탭을 처리 할 수없고 파일에 탭이 있음을 언급하도록 사양을 업데이트했습니다.)
Value Ink

탭이 있습니까? 방금 찾아서 바꾸었고 0 번 변경했습니다.
Pavel

3

, 90 바이트

88 바이트의 코드 + -p0플래그

\@a[y///c]for/.*/g;s/(.*?)\K[{};]$/$"x(@a-$1=~y%%%c).$&/gme;1while s/ *
 *([{};]+)$/$1/m

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

간단한 설명 :
\@a[y///c]for/.*/g; 가장 긴 줄의 길이를 계산합니다. 각 줄 y///c에 대해 배열의 인덱스에있는 요소 (예 : 줄의 크기)를 정의합니다 @a. 끝에서 최대 색인 @a(즉, 크기 @a)은 가장 긴 선의 크기입니다. 줄 끝에 문자를
s/(.*?)\K[{};]$/$"x(@a-$1=~y%%%c).$&/gme배치합니다 {};.
1while s/ *\n *([{};]+)$/$1/m빈 줄의 괄호가 위의 줄로 이동합니다.

@primo 덕분에 가장 긴 줄의 길이를 계산하기 위해 여기 에서 코드의 시작 부분을 부분적으로 "훔친"사람이 있습니다.


괄호 앞에 공백 만 있으면 위의 줄로 되돌아 가야합니다.이 답변은 그렇지 않습니다.
Kritixi Lithos

@KritixiLithos는 실제로 도전 과제가 다시 제기되기 전에 괜찮아 보였습니다. 어쨌든, 이제 수정되었습니다 (알지 못하는 경우를 대비하여 이미 답변에 코드를 작성했습니다).
Dada

1

파이썬 2 : 228 바이트

import re
g=re.search
def b(a):
    s,l="",a.split('\n')
    r=max([len(k)for k in l]) 
    for k in l:
        n,m=g('[;}{]',k),g('[\w]',k)
        if n:n=n.start()
        if m:m=m.start()
        if n>m and m!=None:s+="\n"+k[:n]+" "*(r-n)
        s+=k[n:]
    print s

엄청나게 길다. 나는 ;{}이전 줄의 끝으로 가야 할 고독한 것을 깨달았을 때 처음부터 시작했을 것 입니다.
Chris H

1

스택 , 133 바이트

'\s+([;{}])' '$1'repl lines{!n'[\s;{}]+$'match''join:n\'$'+del\,}"!tr:$size"!$MAXmap@k{e i:e[' 'k i#rpad]"!}map tr[' 'join]map'
'join

온라인으로 사용해보십시오! 나는 이것을 너무 많이 생각할 수 있었지만 ... 나는 내일 다시 볼 것이다. 좋은 팁 :

  1. "!map다음 토큰이 단어로 시작하는지 여부에 따라, 대신 1 ~ 2 바이트를 절약 할 수 있습니다 . 그러나 배열의 각 아톰을 매핑하려는 경우에만 사용할 수 있습니다. 깊은지도와 비슷합니다.
  2. 공백이 인용 기능 후 필요하지 않은, 그래서 $MAXmap에 해당 $MAX map차례에 해당하는 [MAX] map. 각 배열을 최대 요소에 매핑합니다.

1

자바 스크립트 (ES 제안), 139121 바이트

f=
s=>s.replace(/^(.*?)\s*(([;{}]\s*)+)$/gm,(_,t,u)=>t.padEnd(Math.max(...s.split`
`.map(s=>s.length)))+u.replace(/\s/g,``))
<textarea rows=10 cols=40 oninput=o.textContent=f(this.value)></textarea><pre id=o>

Firefox 48 / Chrome 57 / Opera 44 / Safari 10 / Edge 15가 필요 padEnd합니다. 편집 : @ValueInk 덕분에 18 바이트가 절약되었습니다.


s.replace(r,`$1`)선 길이를 계산할 때 실제로 실행해야 합니까? 적당한 양의 오른쪽 패딩이면 충분하므로 세미콜론과 괄호로 줄 길이 세는 것이 좋습니다.
Value Ink

0

PHP, 201 194 185 172 167 바이트

foreach($f=file(f)as$s)$x=max($x,strlen($a[]=rtrim($s,"{} ;
")));foreach($a as$i=>$c)echo str_pad($c,""<$c|!$i?$x:0),trim(substr($f[$i],strlen($c))),"
"[""==$a[$i+1]];

파일 f에서 입력을받습니다. 단일 바이트 줄 바꿈을 가정하고 탭이없는 것으로 가정합니다. 빈 줄을 유지합니다.

  • 공백을 구분하기위한 +2 바이트 : +1두 번째 str_pad매개 변수에 추가하십시오 .
  • 그것이 어떤 코드 라인은 하나의 구성 없다는 것을 보장 경우 -6 바이트 0:
    제거 ""<및 교체 ""==와 함께 !.

고장

foreach($f=file(f)as$s)             // loop through file
    $x=max($x,strlen(                   // 3. set $x to maximum code length
        $a[]=                           // 2. append to array $a
            rtrim($s,"{} ;\n")          // 1. strip trailing whitespace and braces
    ));
foreach($a as$i=>$c)echo            // loop through $a
    str_pad($c,                         // 1. print code:
        !$i|""<$c                       // if first line or not empty
        ?$x                             // then padded to length $x
        :0                              // else unpadded (= print nothing)
    ),
    trim(substr($f[$i],strlen($c))),    // 2. print braces
    "\n"[""==$a[$i+1]]                  // 3. if next line has code, print newline
;

{}정규식 에서 중괄호 를 피해야 합니까?
Kritixi Lithos

@KritixiLithos 아마 아닙니다; 어쨌든 더 짧은 접근 방식을 찾았습니다.
Titus

0

자바 (8), (312) 305 바이트

s->{String t="([;{}]+)",z[],r="",a;s=s.replaceAll(t+"[\\s\\n]*","$1").replaceAll(t,"$1\n");int m=0,l;for(String q:s.split("\n"))m=m>(l=q.length())?m:l;for(String q:s.split("\n")){z=q.split("((?<="+t+")|(?="+t+"))",2);for(a="",l=0;l++<m-z[0].length();a+=" ");r+=z[0]+a+(z.length>1?z[1]:"")+"\n";}return r;}

설명:

여기에서 시도하십시오.

s->{                                  // Method with String parameter and String return-type
  String t="([;{}]+)",                //  Temp regex-String we use multiple times
    z[],a,                            //  Temp String-array and temp String
    r="";                             //  Result-String
  s=s.replaceAll(t+"[\\s\\n]*","$1")  //  We replace all ;{} in the input with zero or more whitespaces/newlines to just ;{}
     .replaceAll(t,"$1\n");           //  and then add a single newline after each group of ;{}
  int m=0,l;                          //  Two temp integers
  for(String q:s.split("\n"))         //  Loop (1) over the lines
    m=m>(l=q.length())?m:l;           //   To determine the longest line
                                      //  End of loop (1)
  for(String q:s.split("\n")){        //  Loop (2) over the lines again
    z=q.split("((?<="+t+")|(?="+t+"))",2);
                                      //   Split on groups of ;{}, but keep them in the array
    for(a="",l=0;l++<m-z[0].length();a+=" "); 
                                      //   Amount of spaces we should add
    r+=z[0]+a+(z.length>1?z[1]:"")+"\n"; 
                                      //   Append this line to the result-String
  }                                   //  End of loop (2)
  return r;                           //  Return the result-String
}                                     // End of method

이 답변에 대해 언급하고 있지만 많은 다른 사람들에게 적용됩니다. 우리는 현재 람다 매개 변수가 Java 형식을 갖도록 요구합니다 .
Nathan Merrill

1
@NathanMerrill 심판의 날이 올 것을 두려워했습니다. Jk, 지금부터 추가하고 답변을 편집했습니다. 감사합니다. ;)
Kevin Cruijssen
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.