生成/ *行号注释* /


12

您的任务是编写一个程序(或函数),该程序将字符串作为输入并将文本追加到满足以下规则的每一行的开头:

  • 附加的文本必须包含行号。您可以使用基于0或1的索引。
  • 文字必须是您所用语言的注释。注释定义为语法上有效的一段代码,不更改程序状态。删除注释不应更改程序。
  • 注释的末尾只能包含换行符。
  • 您不必为仅包含空格和注释的行添加行号。

技术指标

  • 您可以假定输入将是您所用语言的有效程序。
  • 在缩进敏感的语言(如Python)中,您可以在所有缩进之后放置行号注释。您可以选择制表符或空格作为缩进字符,但必须在帖子中指定。
  • 您可以假设代码中的每个语句最多占用1行的全部内容;即没有多行字符串或反斜杠继续。

测试用例

蟒蛇:

#0
a = int(input())
#1
while a:
    #2
    print(a)

C :(老实说,我对此编译感到惊讶)

/*0 */#include <stdio.h>
/*1 */int main()
/*2 */{
/*3 */    char c;
/*4 */    c = getchar();
/*5 */    do
/*6 */    {
/*7 */        putchar(c);
/*8 */    }
/*9 */    while (c);
/*10*/}

这是,因此最短的答案(以字节为单位)获胜。


7
使注释依赖于语言会使事情变得复杂。您已经必须为Python创建一条特殊规则。没有其他多行注释的所有其他语言呢?那根本没有注释的语言呢?在没有副作用的情况下不能放置注释的多行字符串呢?
丹尼斯

4
有趣的事实:“删除注释不应更改程序”规则立即取消了任何Python答案的资格,因为可以在运行时自检代码(包括注释)。我已经在生产系统中看到了这一点:AssertionError除非堆栈跟踪中包含短语foo.py,否则一段代码会引发an ,这应该来自文件名,但也可能在上下文中显示为行注释。
wchargin '16

2
注释的末尾只能包含换行符 ”,与C“ 测试用例 ” 不一致。
彼得·泰勒

2
没有评论的语言呢?
NoOneIsHere

4
编辑不能解决不一致问题。
彼得·泰勒

Answers:


5

Pyke,7个字节

o\Kz++r

在这里尝试!

o       -  o++
 \K     -  "K"
   z    -  input()
    ++  - sum(^)
      r - while no errors: GOTO start

我将整数注释声明为整数,然后是字符K,然后是行。多余的字节用于阻止换行操作码插入并打印多余的内容。


16

Perl,8 + 1 = 9个字节

say"#$."

运行-p(1个字节的罚款)。(请注意对PPCG规则不熟悉的人;您还需要使用来指定现代版本的Perl语法-M5.010,但是我们决定选择语言版本的选项是免费的,不会产生字节损失,因此我没有在其中提及此帖子的原始版本。)

-p将程序置于隐式循环中;它基本上会使程序成为分别处理每一行的过滤器(即,整个程序在第一行,第二行,第三行等等上运行)。Perl还跟踪称为的行号,该行号$.记录了已读取的输入行数。因此,程序的全部工作就是-p读取一行输入。输出a #,当前行号($.)和换行符(say默认情况下添加换行符,在这种情况下非常有用,并且比更常见的短print)。然后-p输出读取的原始代码行(通常是使用-p会在输入上进行某种处理,但由于我们没有这样做,所以它只是输出不变)。Perl中的注释从开始#到换行符(#程序本身不会在注释中开始注释,因为它位于字符串文字中),因此,我们基本上要做的就是趁机在文件中写入注释行,而不会干扰的“自然”读写周期-p


您能解释一下这是如何工作的吗?
亚当

当然。鉴于它是一个非常基本的Perl程序,并没有真正利用该语言的强大功能,因此我已经以教程的方式说明了相关Perl语言功能的操作。我需要记住,并不是每个人都知道-p循环或自动更新的行号是如何工作的。

请注意,这say"$.;"也将起作用,因为问题指定“您可以假设代码中的每个语句最多占用1行的全部”。
msh210 '16

不过,这并不是真正的评论。尽管它没有任何用处,但它最终会出现在AST中(并且由于Perl的优化器有点烂,我认为实际上最终会使程序变慢,这是您不希望执行的操作)。

不适用于规则您不必为仅包含空格和注释的行添加行号。
Denis Ibaev

9

Javascript,43个 39字节

a=>a.replace(/^/gm,_=>`/*${++b}*/`,b=0)

感谢ETH和Conor节省了4个字节。


41个字节:a =>(b = 0,a.replace(/ ^ / gm,_ => /*${++b}*/))(使用格式字符串)
Conor O'Brien

1
39个字节:a=>a.replace(/^/gm,_=>`/*${++b}*/`,b=0)
ETHproductions 2016年


3

批处理,91字节

@set n=
@for /f "delims= tokens=*" %%a in (%1) do @set/an+=1&call echo @rem %%n%%&echo %%a

在EOF之前,Batch无法读取STDIN,因此必须将文件名作为命令行参数传递。


3

Lua,80 75字节

通过滥用语言节省了一些字节。

x=1print("--[[1]]"..(...):gsub("\n",load('x=x+1return"\\n--[["..x.."]]"')))

足够简单的入门答案。

无高尔夫球,+

x=1                                                     -- Assign x to 1...
print(                                                  -- Print...
      "--[[1]]"                                         -- The first line number comment...
      ..                                                -- With...
      (...):gsub(                                       -- The input, replacing all...
                 "\n",                                  -- Newlines...
                    load                                -- with a string compiled function...
                    (' \
                    x=x+1                               --Increment x by one... \
                    return"\\n--[["..x.."]]"            -- And return the new linecomment. \
                    ')
                 )
      )

我不知道Lua,但是您确定它会始终生成相同长度的注释吗?例如,如果一个程序比最后一个注释长10行,那么最后一个注释将比最后一个注释长--[[10]]1个字符,--[[9]]除非您正确地用空格填充它。
硕果累累

1
哦,我没注意到那个规则。似乎……有点多余……
ATaco

1
是。也许我将其删除... [编辑]:已删除。
硕果累累

3

Gema,16个 15个字符

*\n=\!@line\n$0

在Gema中,仅以开头的行注释!

样品运行:

bash-4.3$ cat l33t.gema 
e=3
g=9
i=1
o=0
t=7

bash-4.3$ gema -f l33t.gema <<< 'Hello World!'
H3ll0 W0rld!

bash-4.3$ gema '*\n=\!@line\n$0' < l33t.gema > l33t-nr.gema

bash-4.3$ cat l33t-nr.gema
!1
e=3
!2
g=9
!3
i=1
!4
o=0
!5
t=7

bash-4.3$ gema -f l33t-nr.gema <<< 'Hello World!'
H3ll0 W0rld!

以下是回答Adám的问题,是否可以用一种被忽略的代码添加行号。

Gema代码本质上是Gema术语中 = 转换规则或template = action的集合。我看不到定义永远不会匹配任何内容的模板的方法,仅此一种似乎不是这样。

Gema,18个字符

*\n=c:\=@line\;:$0

转换e=3c:=1;:e=3

幸运的是,在Gema中有domains,一种名称空间。上面的代码定义了我们从未使用过的命名空间c中的伪规则。不幸的是,提到的域在行尾之前一直有效,因此我们必须明确地切换回默认域。

Gema,18个字符

*\n=@line\=\$0\;$0

转换e=31=$0;e=3

一种更简单的选择是使用无效代码而不是被忽略的代码。我的意思是确切地放回匹配的内容。


但是您不能插入一个字符串并在其周围添加一些代码以使其被忽略吗?
亚当

您是说要e=3转换成某种形式,if (false) { 1 }; e=3而不是转换成当前形式!1␤e=3?是的,将有一个19个字符长的解决方法。
manatwork '16

2

Qbasic,91 89字节

OPEN"I",1,"i"
OPEN"O",2,"o"
DO UNTIL EOF(1)
i=i+1
INPUT#1,a$
PRINT#2,STR$(i)+"'"+a$
LOOP

输入:

CLS
PRINT "Hello!"
a$="Welcome"
INPUT "Type your name: ", b$
PRINT a$; ", "; b$
END

输出:

 1'CLS
 2'PRINT "Hello!"
 3'a$="Welcome"
 4'INPUT "Type your name: ", b$
 5'PRINT a$; ", "; b$
 6'END

1
自从我使用QBasic以来已经有一段时间了,但是这不是使程序文本全部是注释,而不是行号吗?还是我记错了什么?

感谢您的输入!实际上,'仅注释行中的内容。
匿名

4
是的,这就是为什么我认为它将程序变成注释的原因。它不只是添加行号,还可以将含义更改为不执行任何操作的程序。(老实说,BASIC方言中的一个条目添加实线编号并重新编号该程序(如果它已经有编号的话,这很酷,但这可能并不是真正需要的。)

2

BASH(+ GNU sed)27字节

sed 'i#
='|sed 'N;s/\n//;N'

第一部分(i# \n =)几乎可以在GNU sed中使用(4字节),但是它在之后放置了换行符#


2

awk(19 13字节)

19个字节:在每行代码上方插入“#” +行号

{print"#"NR"\n"$0}

13字节:感谢并感谢@manatwork提供了两个13字节的解决方案

作为1默认使用print $0

{print"#"NR}1

或通过替换$0内容

$0="#"NR RS$0

{print"#"NR}1还是$0="#"NR RS$0
manatwork '16

@manatwork我非常as愧和感激,发现这些实用工具
Adam

2

Kotlin扩展功能,69 60字节

fun String.a()=lines().mapIndexed{i,s->"/*$i*/$s"}.joinToString("\n")

fun String.a(){lines().mapIndexed{i,s->println("/*$i*/$s")}}

用法示例:

fun main(args: Array<String>) {
  //language=kotlin
  val code = """fun main(args: Array<String>) {
  println("Hello world!")
}"""
  code.a()
}

输出:

/*0*/fun main(args: Array<String>) {
/*1*/  println("Hello world!")
/*2*/}

1

CJam,21字节

我一点都不精通CJam,但事实上我知道它有评论:)

qN%ee{"e#"o(oNo(oNo}/

解释即将推出。


oNo可以替换为nTIO。
硕果累累

1

Mathematica,58个字节

i = 1; StringReplace[#, StartOfLine :> "(*" <> ToString@i++ <> "*)"] &

1

jq,31个字符

(27个字符的代码+ 4个字符的命令行选项。)

"#\(input_line_number)\n"+.

在jq中,仅以开头的行注释#

样品运行:

bash-4.3$ cat l33t.jq 
gsub("e";"3")|
gsub("g";"9")|
gsub("i";"1")|
gsub("o";"0")|
gsub("t";"7")

bash-4.3$ jq -Rr -f l33t.jq <<< 'Hello World!'
H3ll0 W0rld!

bash-4.3$ jq -Rr '"#\(input_line_number)\n"+.' l33t.jq > l33t-nr.jq

bash-4.3$ cat l33t-nr.jq 
#1
gsub("e";"3")|
#2
gsub("g";"9")|
#3
gsub("i";"1")|
#4
gsub("o";"0")|
#5
gsub("t";"7")

bash-4.3$ jq -Rr -f l33t-nr.jq <<< 'Hello World!'
H3ll0 W0rld!

尊敬的Perl和Ruby编码人员,请注意jq的input_line_number。作为感恩节,有什么特别的感觉要表达$.吗?
manatwork '16

1

GolfScript,23字节

n/0:i;{"#"i):i+n+\+}%n*

只有行注释以“#”开头。

取消说明:

           # the input is pushed on the stack automatically
n          # n is a predefined variable for "\n"
/          # splits the input string with the previously pushed "\n" as delimiter
0:i;       # i = 0
{          # A code block: It is used for map here (going through the input)
    "#"    # push a "#" onto the stack
    i):i  # save i + 1 in i, the value is again not popped from the stack
    +      # implicitly converts the number i to a string and concatenates "#" with it
    n      # newline
    +      # add a newline (# introduces a *line* comment)
    \      # switch the top to elements (-> yields the comment as the bottom, and the line as the top element on the stack)
    +      # concatenate them
}          # end of the code block
%          # map
n          # newline
*          # join the list with newlines between them
           # outputs are done implicitly

我敢肯定,这可以进一步简化,尤其i是可以省略。

您可以在此处进行测试:https : //golfscript.apphb.com/ 由于此站点不支持添加输入,因此您必须在代码前放置一个字符串,并在双引号中将其引起来。'\n'将是换行符。请注意,还有其他转义序列。用户'\\'如果不确定。


1

C#6,66 61字节

感谢CSharpie

(666,恶魔代码^^)不再...

这适用于所有使用“ C样式注释”的语言(C,C ++,C#,Java等)。

它只是将字符串分割成几行,在每行前加上索引,然后再用新的行字符将编辑过的行连接起来。

s=>string.Join("\n",s.Split('\n').Select((l,i)=>$"/*{i}*/"+l));

旧版:

s=>string.Join("\n",s.Split('\n').Select((l,i)=>$"/*{i,3}*/{l}"));

1
从技术上讲64,因为op没有提到任何零填充。另外,您还可以通过输入以下命令来节省1个字节:$“ / * {i} * /” + 1。(将L参数从插值中
删除

你是对的^^,但是那摧毁了我的“邪恶分数”,呵呵
Stefan

0

Python 2,82个字节

适用于仅空格的缩进

for i,l in enumerate(input().split('\n')):print l.split(l.lstrip())[0]+'#%d\n'%i+l

56字节的无缩进版本

for x in enumerate(input().split('\n')):print'#%d\n%s'%x
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.