再次使这段代码说明


17

介绍

这里的大多数代码高尔夫球手在其提交的内容中添加了解释,因此更容易理解正在发生的事情。通常,代码行在左侧,相应的说明在右侧,带有某种分隔符。为了使外观漂亮,分隔符都在同一列上。同样,较长的说明文字通常也包含在下一行,因此读者不必水平滚动即可阅读所有内容。

但是,当您由于疯狂打高尔夫球而想要编辑此说明时,通常会花时间来重新整理您的说明。由于这是一项非常重复的任务,因此您需要为此编写一个程序。

挑战

给定几行带有说明的代码和一个分隔符,输出格式正确的带有说明的代码。

输入项

shM-crz1dc4。“ ANDBYOROF#z =输入

     rz1#将输入转换为大写
    cd#在空格处分割输入
         c4。“ ANDBYOROF#从打包字符串中创建单词列表,该列表将被忽略
   -#过滤掉那些词
 HM#只取所有单词的首字母
s#将它们连接成一个字符串

输出量

shM-crz1dc4。“ ANDBYOROF#z =输入

     rz1#将输入转换为大写
    cd#在空格处分割输入
         c4。“ ANDBYOROF#从打包字符串中创建单词列表,该字符串应为
                           #被忽略
   -#过滤掉那些词
 HM#只取所有单词的首字母
s#将它们连接成一个字符串

第一个可以找到该代码功能的cookie。

格式化算法

  • 找到最长的代码行(不包括解释以及代码和分隔符之间的空格)。
  • 在此代码行后添加5个空格,并在相应的分隔符后附加说明。现在这是参考线。
  • 将每隔一行调整到该参考线,以使分隔符都在同一列中。
  • 通过以下方式将所有超过93个字符的行换行:
    • 找到最后一个单词,该单词的末尾位于第93列或更低的列。
    • 将这之后的所有单词都包含在内,并用前导分隔符和正确的间距将其换行。这两个单词之间的空格必须删除,因此第一行以单词字符结尾,第二行以分隔符之后的一个字符开头。
    • 如果结果行仍然超过93个字符,请再次执行相同操作,直到每行低于94个字符。

笔记

  • 单词由非空格字符组成。单词由单个空格分隔。
  • 自动换行始终是可能的。这意味着没有一个单词太长以至于不可能包装。
  • 输入将仅包含可打印的ASCII,并且没有任何结尾的空格
  • 分隔符每行只会出现一次。
  • 尽管说明的长度可以是无限的,但分隔符和代码只能具有最大93 - 5 = 87字符长度的组合。5个字符是代码和分隔符之间的空格。代码和分隔符将始终至少一个字符长。
  • 输入中可能包含空行。这些字符将永远不包含任何字符(如果将输入作为多行字符串,则换行符除外)。这些空行也必须出现在输出中。
  • 每行都会有一些代码,分隔符和说明。空行例外。
  • 您可以采用任何合理的格式输入,只要未经预处理即可。在您的答案中清楚说明您使用的是哪个。
  • 输出可以是多行字符串或字符串列表。

规则

测试用例

这里的输入格式是代表行的字符串列表和分隔符的单个字符串。两者都用逗号分隔。输出是字符串列表。

['shM-crz1dc4。“ ANDBYOROF#z =输入','','rz1#将输入转换为大写','cd#在空格处分割输入','c4。” ANDBYOROF#从打包的单词中创建单词列表应该忽略的字符串','--#过滤掉这些单词','hM#只接受所有单词的首字母','s#将它们连成一个字符串'],“#”-> ['shM-crz1dc4 “ ANDBYOROF#z = input','','rz1#将输入转换为大写','cd#在空格处分割输入','c4。” ANDBYOROF#从打包字符串中创建单词列表,应为' ,'#已忽略','-#过滤掉这些单词','hM#只接受所有单词的第一个字母','#将它们连成一个字符串']
['codecodecode e#Explanation','sdf dsf sdf e#A非常非常非常非常非常非常非常非常长很长很长很长很长很长很长很长很长的解释,并且它会越来越长','','一些更多编码和更多解释'],“ e#”-> ['codecodecode e#Explanation','sdf dsf sdf e#A非常非常非常非常非常非常非常非常非常长很长很长很长很长''''e#long很长很长很长很长的解释,并且它会越来越长','e#和更长','','一些更多的代码e#和一些更多的解释']

编码愉快!


1
@Matt所有分隔符始终位于column length of the longest code-line + 5。这也适用于仅包含说明的行,因为它们已被包装。
丹克

噢,天哪,最近3个小时我一直在做错事。我正在尝试包装长代码,并长时间保留解释.....从头开始。至少现在更容易了。谢谢。你说的很好。。。我只是傻。
马特

将所有超过93个字符的行换行是否表示代码(包括前导空格)的长度永远不会超过87个字符?
马特

@Matt代码分隔符的总和永远不会超过87个字符,因为我们在代码和分隔符之间需要5个空格,并需要一个字符进行解释。
Denker

1
Pyth代码找到任何给定字符串的缩写。我会知道,因为那是我的问题的答案。
Aplet123 '16

Answers:


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}*"
"}

变更日志:

  • 利用输入中的某些promise节省了一些字节,尤其是所有非空行都具有分隔符和说明的promise。
  • 通过保存第一次map通话中的分割字符串并strip基于一些保证,即解释中的单词之间始终始终有一个空格,从而消除了一些不必要的功能,从而使高尔夫活动更加有效。另外," "由于我经常使用它,因此现在将其分配给常数。
  • map通过利用高阶函数的功能将两个调用链接在一起,这意味着l即使在helper函数声明之后调用了第一个map调用,也会正确设置length变量s。-4字节。
  • 滥用的多行字符串替换\n为实际的换行符,以及使用的一些技巧if三元运算符的(在join具有nil值的数组上调用时,它们将成为空字符串)
  • .join显然可以用替换*

我认为现在应该解决?
价值墨水

94时该如何包装?
2016年

好吧,既然我有更多的时间来处理代码,它可以正确包装。
价值墨水

“虽然说明的长度可以是无限的,但分隔符和代码只能有一个最大93 - 5 = 87字符长度的组合。5个字符是代码和分隔符之间的空格。代码和分隔符将始终至少一个字符长。” 您的代码段超出了限制,可以包含97个字符,因此该程序具有未定义的行为。
价值墨水

啊,很好发现,很有道理!
2016年

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式的层叠结构:对于该块的其余部分,=>可以访问的左侧..;并将返回。在这里,它是在k上分割的元素。注意:我使用的是字符串插值,因为这/仅意味着用文字字符串“分割”。

LS也允许我们a-=/regexp/在此lambda中使用(也适用于字符串文字):它只是.replace调用的糖。

最后,>?=是组合式>?-assin运算符,它返回两个操作数中较大的一个。

LS具有Python / Haskell风格的理解能力,除了“ string * times”可以重复足够长的时间之外,它们没有其他花哨的内容。

理解这一点作为主题(请参阅有关级联级联的块)。

然后,我们循环到数组的每个元素(我们刚刚用理解构建的那个元素),如果有任何行大于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
拒绝投票的人:答案是固定的。
2016年

2
当说明溢出时,您需要新行将其分隔符与其余的IIRC对齐。
价值墨水

@KevinLau被发现,固定!
2016年

您还可以更新示例输出吗?
价值墨水

@KevinLau完成。
2016年

6

Java,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输液的样本输出

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希望现在的更新可以提供更好的解决方案。
马特

@nimi您还发现其他错误吗?最近几天,我显然遇到了问题。
马特

不,现在有一个+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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.