이 코드 설명을 다시 예쁘게 만드십시오.


17

소개

대부분의 코드 골퍼는 제출에 설명을 추가하므로 진행 상황을 이해하기가 더 쉽습니다. 일반적으로 코드 라인은 왼쪽에 있으며 해당 설명은 오른쪽에 일종의 구분 기호가 있습니다. 예쁘게 보이도록 구분 기호는 모두 같은 열에 있습니다. 또한 긴 설명 텍스트는 일반적으로 다음 줄로 줄 바꿈되므로 독자는 모든 내용을 읽기 위해 가로로 스크롤 할 필요가 없습니다.

그러나 당신이 미친 골프를했기 때문에이 설명을 편집하고 싶을 때 종종 설명을 다시하기 위해 시간을 소비하게됩니다. 이것은 매우 반복적 인 작업이므로이를위한 프로그램을 작성하려고합니다.

도전

설명과 구분 기호가있는 몇 줄의 코드가 주어지면 멋진 형식의 코드를 설명과 함께 출력하십시오.

입력

shM-crz1dc4. "ANDBYOROF #z = 입력

     rz1 # 입력을 대문자로 변환
    공백으로 cd # split 입력
         c4. "ANDBYOROF # 묶음 문자열에서 무시할 단어 목록을 만듭니다.
   -단어를 걸러 내십시오
 hM #은 모든 단어의 첫 글자 만받습니다
# 하나의 문자열로 결합

산출

shM-crz1dc4. "ANDBYOROF #z = 입력

     rz1 # 입력을 대문자로 변환
    공백으로 cd # split 입력
         c4. "ANDBYOROF # 압축 된 문자열에서 단어 목록을 만듭니다.
                           # 무시
   -단어를 걸러 내십시오
 hM #은 모든 단어의 첫 글자 만받습니다
# 하나의 문자열로 결합

이 코드의 기능을 알 수있는 첫 번째 쿠키입니다.

포맷 알고리즘

  • 가장 긴 코드 행을 찾습니다 (설명과 코드와 구분 기호 사이의 공백 제외).
  • 이 코드 라인 뒤에 5 개의 공백을 추가하고 해당 구분 기호를 설명과 함께 추가하십시오. 이것은 이제 참 조선입니다.
  • 분리자가 모두 같은 열에 있도록 다른 모든 줄을이 참 조선으로 조정하십시오.
  • 다음과 같은 방법으로 93 자보다 긴 모든 줄을 줄 바꿈으로 묶습니다.
    • 끝이 93 열 이하인 마지막 단어를 찾으십시오.
    • 이 단어 다음에 나오는 모든 단어를 가져 와서 선행 구분 기호와 올바른 간격으로 새 줄로 줄 바꿈하십시오. 이 두 단어 사이의 공백은 삭제해야하므로 첫 번째 줄은 단어 문자로 끝나고 두 번째 줄은 구분 기호 뒤에서 시작합니다.
    • 결과 행이 여전히 93 자보다 긴 경우 모든 행이 94 자 미만이 될 때까지 동일한 행을 다시 수행하십시오.

노트

  • 단어는 공백이 아닌 문자로 구성됩니다. 단어는 하나의 공백으로 구분됩니다.
  • 단어 줄 바꿈은 항상 가능합니다. 이것은 단어가 너무 길어서 포장이 불가능하다는 것을 의미합니다.
  • 입력은 인쇄 가능한 ASCII 만 포함하며 후행 공백은 없습니다.
  • 구분 기호는 한 줄에 한 번만 나타납니다.
  • 설명은 길이에 제한이 없지만 구분 기호와 코드는 최대 길이의 93 - 5 = 87문자 만 결합 할 수 있습니다 . 5 문자는 코드와 구분 기호 사이의 공백입니다. 코드와 구분 기호는 항상 하나 이상의 문자입니다.
  • 입력에 빈 줄이 포함될 수 있습니다. 그것들은 어떤 문자도 포함하지 않을 것입니다 (여러 줄 문자열로 입력을 받으면 줄 바꿈 제외). 빈 줄도 출력에 있어야합니다.
  • 모든 줄에는 코드, 구분 기호 및 설명이 있습니다. 빈 줄은 예외입니다.
  • 사전 처리되지 않은 한 합리적인 형식으로 입력 할 수 있습니다. 어떤 것을 사용하는지 답을 명확하게하십시오.
  • 출력은 여러 줄 문자열이거나 문자열 목록 일 수 있습니다.

규칙

  • 기능 또는 전체 프로그램이 허용됩니다.
  • 입 / 출력의 기본 규칙 .
  • 표준 허점이 적용됩니다.
  • 이것은 이므로 바이트 수가 가장 적습니다. Tiebreaker는 이전에 제출되었습니다.

테스트 사례

여기에 입력 형식은 행을 나타내는 문자열 목록과 구분 기호에 대한 단일 문자열입니다. 둘 다 쉼표로 구분됩니다. 출력은 문자열 목록입니다.

[ 'shM-crz1dc4. "ANDBYOROF # z = 입력', '', 'rz1 # 입력을 대문자로 변환', 'cd # 공백으로 입력 입력', 'c4."ANDBYOROF # 묶음에서 단어 목록을 만듭니다. 무시 될 문자열 ','-# 해당 단어를 걸러냅니다 ','hM # 모든 단어의 첫 글자 만 가져옵니다 ','# 하나의 문자열로 묶습니다 '', "#"-> [ 'shM-crz1dc4 . "ANDBYOROF # z = 입력 ',' ','rz1 # 입력을 대문자로 변환 ','cd # 공백에서 입력 분리 ','c4."ANDBYOROF # 압축 문자열에서 단어 목록을 작성합니다. ' , '# 무시 됨', '-# 단어를 걸러냅니다 ','hM # 모든 단어의 첫 글자 만 가져옵니다 ','# 한 줄로 묶습니다 ']
[ 'codecodecode e # Explanation', 'sdf dsf sdf e # A 매우 매우 매우 매우 매우 매우 긴 매우 긴 매우 긴 매우 긴 매우 긴 긴 긴 설명과 계속 점점 길어짐', '', '일부 더 많은 코덱 번호와 더 많은 설명 '], "e #"-> ['codecodecode e # Explanation ','sdf dsf sdf e # A 매우 매우 매우 매우 매우 매우 긴 매우 긴 long long long ','e # long long long long long long 설명과 계속 길어짐 ','e # and long ',' ','일부 더 많은 코드 e # 및 더 많은 설명 ']

행복한 코딩!


1
@Matt 모든 분리기는 항상 열에 length of the longest code-line + 5있습니다. 이것은 설명이 포함 된 줄에도 적용되었습니다.
Denker

오 마이 갓 지난 3 시간 동안이 일을 잘못하고 있습니다. 나는 긴 코드를 감싸고 설명을 길게 남기려고했습니다. 적어도 지금은 더 쉽습니다. 감사. 당신은 잘 말 했어요 .. 난 그냥 바보 야.
Matt

93 자보다 긴 모든 줄 바꿈 앞 공백을 포함하여 코드의 길이가 87자를 넘지 않습니까?
Matt

@ 매트는 코드 우리가 코드 구분자 및 설명에 대한 하나 개의 문자 사이의 5 개 공간을 필요로하기 때문에 구분자의 함께는 이상 87 자하지 않습니다.
Denker

1
Pyth 코드는 주어진 문자열의 약어를 찾습니다. 그게 내 질문에 대한 답변 이었기 때문에 알고 싶습니다.
Aplet123

답변:


3

루비 245 237 220 216 212 209 205 바이트

익명의 기능. 매우 기본적인 접근 방식 (최대 길이 찾기, 5 추가, 줄 바꾸기 처리를 위해 재귀와 함께 각 줄에서 처리) 및 더 많은 바이트를 절약하는 다른 접근 방법이있을 수 있습니다.

모든 요구 사항을 충족하지 못하는 답변을 이전에 삭제했습니다. 나는 반 답변 코드를 답으로하고 싶지 않았지만 (불완전한 것에 대한 공감대를 얻었습니다) 지금은 질문이 요구하는 모든 것을해야합니다.

->x,d{l,S=0," "
s=->n{m,q=n.size,94-l-d.size
m>q ?(i=n.rindex(S,q)
n[0,i]+"
"+S*l+d+s[n[i+1,m]]):n}
x.map{|n|c,t=n.split d
c=(c||S).rstrip
l=[l,5+c.size].max
[c,t]}.map{|c,t|c+S*(l-c.size)+d+s[t]if t}*"
"}

변경 로그:

  • 입력의 일부 약속, 특히 비어 있지 않은 모든 행에 구분 기호 문자와 설명이 있다는 약속을 활용하여 일부 바이트를 절약했습니다.
  • 첫 번째 map호출 에서 스플릿 스트링을 저장 strip하고 설명의 단어가 항상 그들 사이에 정확히 하나의 공백을 가지고 있다는 약속에 따라 불필요한 기능을 취 함으로써 조금 더 골프를 쳤 습니다. 또한 " "너무 많이 사용하기 때문에 상수에 할당되었습니다.
  • map고차 함수의 힘을 활용하여 두 호출을 연결했습니다. 즉, 첫 번째 맵 호출은 l도우미 함수 선언 후 호출 된 경우에도 length 변수를 올바르게 설정합니다 s. -4 바이트.
  • \n실제 줄 바꿈 으로 대체하기 위해 여러 줄로 묶인 문자열 과 if삼항 연산자를 사용하는 약간의 트릭 ( 값이 join있는 배열에서 호출 되면 nil빈 문자열이 됨)
  • .join분명히로 대체 될 수 있습니다 *.

지금 수정해야한다고 생각합니까?
Value Ink

이것은 94에서 어떻게 랩핑됩니까?
Ven

좋아, 이제 코드 작업에 더 많은 시간이 있었으므로 제대로 포장되었습니다.
Value Ink

"설명은 무제한 길이를 가질 수 있지만 구분자와 코드는 최대 길이의 93 - 5 = 87문자 만 결합 할 수 있습니다 . 5 문자는 코드와 구분 기호 사이의 공백입니다. 코드와 구분 기호는 항상 1 자 이상이어야합니다." 코드 섹션이 한도를 초과하여 97 자이므로 프로그램에 정의되지 않은 동작이 있습니다.
Value Ink

아, 잘 발견되었습니다.
Ven

9

는 LiveScript, 243 236 233 228 219 225 바이트

f = (x,k,m+5)->l=(.length);x.=map(->it/"#k"=>..0-=/ +$/;m>?=5+l ..0);i=0;[..0&&..0+' '*(m- l ..0)+k+..1 for x]=>while i<(l ..),++i=>j=(s=..[i])lastIndexOf ' ' 93;(..splice i+1 0 ' '*m+k+s[j to]*'';s.=substr 0 j) if 94<l s;..[i]=s

작동 방식 : 주로 Java 코드와 유사합니다. 앨리어싱 길이로 시작합니다 (LiveScript를 사용하면 괄호를 사용하여 연산자에서 함수를 만들 수 있습니다). .=입니다 a = a.b- 우리는지도를 여기에 사용하는.

=> blabla ..Smalltalk-ish 캐스케이드 구성은 다음과 같습니다. 나머지 블록 =>은 왼쪽에 액세스 할 수 있습니다 ... 반환됩니다. 여기, k에서 분할 된 요소입니다. 참고 : /리터럴 문자열로 "분할"만 의미 하기 때문에 문자열 보간을 사용 하고 있습니다.

LS는 우리 a-=/regexp/가이 람다에서도 사용할 수있게합니다 (문자열 리터럴과도 작동합니다) : 그것은 .replace전화를 위한 설탕 일뿐 입니다.

마지막으로, >?=조합 >?-assin 연산자는 두 피연산자 중 큰 것을 반환합니다.

LS는 공간을 충분히 길게 반복 할 수있는 "문자열 * 시간"을 제외하고는 이해하기 쉬운 파이썬 / 하스켈 스타일을 가지고 있습니다.

이것은 이해를위한 주제입니다 (캐스케이드 anove에 대한 블록 참조).

그런 다음 배열의 각 요소 (방금 이해하여 만든 요소)로 루프하고 93chars보다 큰 행이 있으면 마지막 인덱스를 찾아서 분할 한 다음이 현재 반복 직후에 분리 된 줄을 밀어 넣습니다 ( ... 라인이 너무 크면 다음 반복이 다시 분할되도록).

마지막으로 멋진 a[j to]것은 범위 (j에서 끝까지)이지만 Array 메서드를 사용하기 때문에 오버로드를 사용하여 문자열에 다시 결합해야합니다.* : *''.

s = """this is kod # Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
d # y

efgh # z"""

f = (x,k,m=5)->l=(.length);x.=map(->it/"#k"=>..0-=/ +$/;m>?=5+l ..0);i=0;[..0&&..0+' '*(m- l ..0)+k+..1 for x]=>while i<(l ..),++i=>j=(s=..[i])lastIndexOf ' ' 93;(..splice i+1 0 ' '*m+k+s[j to]*'';s.=substr 0 j) if 94<l s;..[i]=s

console.log (f s / '\n', '#') * \\n

산출:

this is kod     # Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
                # tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
                # veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
                # commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
                # velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
                # cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id
                # est laborum.
d               # y

efgh            # z

1
downvoted 누구에게 : 대답은 고정되어 있습니다.
Ven

2
설명이 오버플로되면 구분 기호 문자를 나머지 IIRC에 맞추려면 줄 바꾸기가 필요합니다.
Value Ink

@KevinLau 잘 발견 고정!
Ven

예제 출력도 업데이트 할 수 있습니까?
Value Ink

@KevinLau가 완료했습니다.
Ven

6

자바, 347 + 19 = 366 바이트

필요

import java.util.*;

따라서 +19 바이트입니다.

(c,s)->{int p=0,i=0,t;String l;for(;i<c.size();i++){l=c.get(i);l=l.replaceAll(" *"+s,s);p=Math.max(l.indexOf(s),p);c.set(i,l);}p+=5;for(i=0;i<c.size();i++){l=c.get(i);t=l.indexOf(s);while(t>-1&t<p)l=l.substring(0,t)+" "+l.substring(t++);t=93;if(l.length()>t){while(l.charAt(t)!=' ')t--;c.add(i+1,s+l.substring(t));l=l.substring(0,t);}c.set(i,l);}}

형식을 취합니다 f.accept(List<String> code, String seperator). 내부 형식. 새로운 것을 생성하고 반환하는 버전은 List<String>구현하기가 쉽지만 약간의 비용이 듭니다.

들여 쓰기 + 사용 예 :

static BiConsumer<List<String>, String> prettify = (code, seperator) -> {
    int space = 0, i=0, t;
    String line;
    for (; i<code.size(); i++) { // for each line
        line = code.get(i); // get line
        line = line.replaceAll(" *" + seperator, seperator); // strip space before seperator
        space = Math.max(line.indexOf(seperator), space); // save biggest space until seperator
        code.set(i, line); // save line
    }
    space += 5;
    for (i=0; i<code.size(); i++) { // for each line
        line = code.get(i); // get line
        t = line.indexOf(seperator); // get index of seperator
        while (t>-1&t<space) // while the seperator exists and is further left than desired
            line = line.substring(0,t) + " " + line.substring(t++); // move it right by adding a space before it
        t = 93; // get desired line length
        if (line.length()>t) { // if the line is longer than that
            while (line.charAt(t)!=' ') t--; // scan backwards for a space
            code.add(i+1, seperator + line.substring(t)); // add a line after this one with seperator and the rest of the line
                                                          // the next pass will space it correctly
            line = line.substring(0,t); // cut off this line at that point
        }
        code.set(i, line); // save edited line back to List
    }
};

public static void main(String[] args) {
    List<String> code = new ArrayList<>();
    code.add("shM-crz1dc4.\"ANDBYOROF  # z = input");
    code.add("");
    code.add("     rz1      # convert input to uppercase");
    code.add("    c   d        # split input on spaces");
    code.add("         c4.\"ANDBYOROF        # create a list of the words from a packed string which shall be ignored");
    code.add("   -          # filter those words out");
    code.add(" hM                # only take the first letter of all words");
    code.add("s                   # join them into one string");
    prettify.accept(code, "#");
    code.stream().forEach(System.out::println);
}

... 아마 이것을 통해 스스로를 실행해야합니다 : P


누군가 왜 replace(" *"+s)작동하지 않는지 알아낼 수 는 있지만 replaceAll(" *"+s)듣고 싶지만 알아낼 수 없습니다.
CAD97

<badguess> replace는 문자열을 replaceAll사용 하지만 정규식을 사용 합니다. </ badguess>
CalculatorFeline

@CatsAreFluffy 잘, 당신은 맞습니다 ! 내가 어떻게 몰랐는지 모르겠다 : P
CAD97

줄 바꿈을 제거 할 수 없습니까?
CalculatorFeline

필요한 semi : s (.s이지만 무엇이든) 때문에 개행을 제거 할 수 있습니다
CalculatorFeline

2

PowerShell을 224 217 235 바이트

param($d,$s)$d=$d-split"`r`n";$p="\s+\$([char[]]$s-join"\")\s";$m=($d|%{($_-split$p)[0].Length}|sort)[-1];$d|%{$l,$c=$_-split$p;$c=if($c){"$s "+(("$c "-split"(.{1,$(87-$m)})\s"|?{$_})-join"`n$(" "*($m+5))$s ")}$l.PadRight($m+5," ")+$c}

최대 코드 문자열 길이를 결정하도록 논리를 업데이트했습니다. 정규식 메타 문자를 포함하는 여러 구분 기호를 허용하도록 업데이트되었습니다.


작은 설명

이것은 입력을 위해 전체 줄 바꿈으로 구분 된 문자열을받습니다.

param($d,$s)
# $d is a newline delimited string. $s is the separator.
# Take the string and turn it into a string array. Stored as $d
$d=$d-split"`r`n"
# Save a regex pattern as it is used more than once
$p="\s+\$([char[]]$s-join"\")\s"
# Get the longest string of code's length
$m=($d|%{($_-split$p)[0].Length}|sort)[-1]
# Split each line again into code and comment. Write out each line with formatted explanations based on separator column position $m
$d|%{
# Split the line
$l,$c=$_-split$p
# Build the comment string assuming there is one.
$c=if($c){"$s "+(("$c "-split"(.{1,$(87-$m)})\s"|?{$_})-join"`n$(" "*($m+5))$s ")}
# Pad the right amount of space on the code and add the comment string.
$l.PadRight($m+5," ")+$c
}

Lorem Ipsum을 사용한 샘플 출력

shM-crz1dc4."ANDBYOROF     # z = input

     rz1                   # convert input to uppercase
    c   d                  # split input on spaces
         c4."ANDBYOROF     # But I must explain to you how all this mistaken idea of
                           # denouncing pleasure and praising pain was born and I will give
                           # you a complete account of the system, and expound the actual
                           # teachings of the great explorer
   -                       # filter those words out
 hM                        # only take the first letter of all words
s                          # join them into one string

@nimi 이제 업데이트가 더 나은 솔루션이되기를 바랍니다.
Matt

@nimi 다른 문제가 있습니까? 지난 며칠 동안 읽는 데 문제가있는 것 같습니다.
Matt

아니요. 이제 +1이 있습니다.
nimi

1

MATLAB, 270 265 262 바이트

function d=f(I,s);S=@sprintf;R=@regexprep;m=regexp(I,['\s*\',s]);L=max([m{:}])+4;a=@(x)S('%-*s%s',L,x,s);b=@(x)R(R(x,S('(.{1,%d}(\\s+|$))',93-L),S('$1\n%*s ',L+1,s)),['\n\s*\',s,' $'],'');c=R(I,['(.*?)\s*\',s,'\s*(.*$)'],'${a($1)} ${b($2)}');d=S('%s\n',c{:});end

프로그램은 I셀 배열의 각 요소가 입력의 개별 행인 문자열의 셀 배열 양식으로 입력 을 승인합니다 . 또한 주석 문자가 무엇인지 나타내는 (즉 #) 두 번째 입력도 허용합니다 . 이 함수는 올바른 형식의 여러 줄 문자열을 반환합니다.

간단한 설명

function d = f(I,s)
    %// Setup some shortcuts for commonly-used functions
    S = @sprintf;
    R = @regexprep;

    %// Find the location of the space AFTER each code block but before a comment
    m = regexp(I, ['\s*\',s]);

    %// Compute the maximum column location of the code and add 4 (5 - 1)
    L = max([m{:}]) + 4;

    %// This is a callback for when we detect code
    %// It left justifies and pads the string to L width
    a = @(x)S('%-*s%s', L, x, s);

    %// This is a callback for when we detect a comment.
    b = @(x)R(...
            R(x, ...
                S('(.{1,%d}(\\s|$))', 93 - L), ... Regex for wrapping text to desired width
                S('$1\n%*s ', L+1, s)), ... Append a newline and padding for next line 
            ['\n\s*\',s,' $'], ''); ... Remove the trailing newline (to be improved)

    %// Perform replacement of everything.
    c = R(I, ...
            ['(.*?)\s*\',s,'\s*(.*$)'], ... Match "code comment_char comment"
            '${a($1)} ${b($2)}');   ... Replace using the output of the callbacks

    %// Concatenate all of the strings together with a newline in between
    d=S('%s\n',c{:});
end

입력 예

I = {
    'shM-crz1dc4."ANDBYOROF  # z = input'
    ''
    '     rz1      # convert input to uppercase'
    '    c   d        # split input on spaces'
    '         c4."ANDBYOROF        # create a list of the words from a packed string which shall be ignored'
    '   -          # filter those words out'
    ' hM                # only take the first letter of all words'
    's                   # join them into one string'
};

disp(f(I,'#'));

출력 예

shM-crz1dc4."ANDBYOROF     # z = input

     rz1                   # convert input to uppercase
    c   d                  # split input on spaces
         c4."ANDBYOROF     # create a list of the words from a packed string which shall be
                           # ignored
   -                       # filter those words out
 hM                        # only take the first letter of all words
s                          # join them into one string
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.