用于打印* any *字符串的程序模板


40

编写具有以下属性的程序:

  • 按原样运行时,程序不产生任何输出(即0字节的输出)。

  • 程序中有一个位置(您可以选择在其开头,结尾或中间的某个位置),并具有以下属性:通过在其中放置任何字符串来修改程序,将导致生成的程序在以下情况下打印该字符串:被执行。

    无论字符串是否包含引号,反斜杠,注释标记,定界符,NUL字节等,此方法都必须起作用。无论您将其放置在哪里,该字符串仍会被解释为字符串,并完全逐字打印。但是,如果很长的字符串会导致编译器用尽内存或类似内容,则可能无法处理它们(准确地说,您至少应能够处理最大1000字节长或三倍于字符串的字符串)。程序长度,以较长者为准)。

无效解决方案的一个示例是

print("");
#      ^ text goes here

在Python,Perl,Ruby等中;尽管它适用于许多字符串,但不适用于包含双引号的字符串或包含子字符串的字符串\n(将其解释为换行符)。

请注意,在大多数语言中,这个问题可能是不可能的。挑战至少部分地在于找到一种可行的语言。您选择的语言必须是该站点定义下的编程语言,例如,不要以Text提交解决方案。

因为这是,所以最短的程序模板将获胜。但是,即使他们不能击败当前的赢家,也不要气from提交解决方案!您仍然可以争夺第二,第三等位置,或者只是在可行的地方找到尽可能多的答案。但是,在提交程序之前,应确保程序符合整个规范。近似解决方案将遗漏问题的重点。


有关沙盒的帖子在这里

您能否阐明我们需要为插入的字符串支持的字符范围?ASCII?ASCII +无法打印?所有的unicode?
DJMcMayhem

3
全部256个八位位组。您将这些解释为字节还是Unicode取决于您;打印时不会有太大区别。

1
这个问题的目的(以及它目前的用词方式)是您不能有任何其他输出。您是否有无法避免的解决方案?(使用额外的字节以避免杂散输出比创建杂散输出更不符合规范。)

1
如果这并不需要更改代码,这会是琐碎AWK,只是1会做。
罗伯特·本森

Answers:


37

Excel,1个字节

'

非高尔夫版本

'        <-- print the following text,
             and exit the current formula

我认为这不能接受换行符。
科纳·奥布莱恩

3
@ ConorO'Brien可以执行shift + enter
Adam

2
@MrPaulch这是很多复古工程。我很确定此命令会隐藏其他一些未知的功能,例如使系统崩溃。
亚当

1
这也适用于OpenOffice Calc。将单元格设置为format时,将自动使用它@
Ismael Miguel

1
我个人认为这个答案很好。@Dennis删除了我使用相同概念的Mathematica帖子。excel的前端会将测试// //“”“ ///作为非普通字符串存储,因此按照他的逻辑,应将其删除。这是它的存储方式<Row> <Cell> <Data ss:Type =” String“ x:Ticked =” 1“> test // //”&quot;“ /// </ Data> </ Cell> </ Row>
Kelly Lowder

20

Jolf,6个字节

a Lq6(

说明

a Lq6(
a       print
  L 6   all but the first 6 characters of
   q    the source code
     (  and exit

15

Perl 5中30 21 19个字节

打印<DATA> __ END__

在线尝试!

尾随换行符。这利用了Perl功能,该功能允许将任意数据附加到源文件,然后可以通过DATA文件句柄读取该数据。当我们给filehandle作为的参数时print,会得到一个列表上下文,这会导致filehandle返回文件中所有行的列表,包括换行符(同样,最后一行的换行符将被省略)。然后print隐式地将它们全部连接起来,取消拆分成几行,并给我们确切的原始字符串,而不管换行符在哪里。

感谢@Dada,他意识到不需要手动处理换行符,而@ninjalj和@b_jonas都发现了可以打高尔夫球的角色。


2
我认为您不需要undef$/。作为的参数print<DATA>在列表上下文中被调用,因此它应该读取其中的每一行。
达达

你是对的。它一次读取输入一行,保留行分隔符,然后在打印时将它们隐式连接起来,因此一开始就无需进行草率处理。同样,这也节省了8个字节。我去修这个职位。

4
您可以使用__END__代替__DATA__
ninjalj

@ninjalj所说的话,加上您可以在大于号后省略换行符(但在程序末尾确实需要换行符)。
b_jonas

14

Zsh,6个字节

<<'
'

有尾随换行符。该字符串将插入程序的末尾。

重击 20 17字节

感谢亚当删除3个字节。

exec sed 1d "$0"

* nix shell脚本, 21 14字节

感谢Adam删除了7个字节。

#!/bin/sed 1d

1
@Copper 尾随换行符。此后将插入字符串。
jimmy23013 '16

知道了 感谢您纠正我!

6/9字节的解决方案似乎对我来说是在利用解释器中的错误(当然,这不是不允许的)。(AFAICT一些实验,他们正在寻找对自身一行换行,但行通过换行分裂定义,因此其本身线路上的新行可能不会发生。)的zsh解决方案似乎是正确的; 但是,9字节的bash解决方案是错误的(如果文件没有1,则添加尾随换行符)。

@ ais523似乎也是我的一个错误。我没想到口译员会允许他们。删除了Bash解决方案。
jimmy23013 '16

1
可以使用bash sed 1d代替tail -n+2
Adam

13

brainfuck(不可读的Brainfuck),9个字节

,+[-.,+]!

将输入追加到末尾。这次没有尾随换行符了。

在寻找可以接受附加在程序末尾的输入的语言时,动脑子似乎是一种明显的可能性。许多用esolangs编写的笨蛋口译员从标准输入中同时获取程序和程序的输入,因此需要某种方式在它们之间进行区分。在这种情况下,有一个约定,即!字符区分程序和输入,这种技巧通常用于编写诸如“ ,[.,]!Hello, world!; 这基本上创建了一个不同的Brainfuck方言,其!含义与正常情况不同。

因此,从理论上讲,我们只能找到这些解释器之一,并为其提供cat程序以符合规格要求。但是,这里有一个很大的微妙之处。brainfuck通常为每个单元格使用256个值,有256个八位位组,其中一个需要用于EOF。因此,如果我们希望能够从字面上回显所有256个八位位组,则根本无法检测到EOF,因此需要以其他方式结束程序。换句话说,我们需要找到一个实现,该实现要么提供256个八位位组和257个不同的值,要么在EOF上崩溃。

输入不可读。在《不可读》中有一个脑力激荡的解释器,它早于这项挑战,并且在!; 之后接受输入。另外,与大多数“笨蛋”解释器不同,它使用bignum单元格和-1表示EOF,从而使EOF与其他256个八位位组区分开。因此,通过使用不可读的Brainfuck作为程序的特定解释器,我们可以通过编写cat在EOF = -1时暂停的Brainfuck程序,仅用9个字节来解决挑战。

有可能做得更好吗?好吧,我们可以尝试下面的7字节程序,该程序尝试在退出循环之前在字符串的末尾输出 EOF:

+[,.+]!

该程序的行为取决于Unerror解释器在错误情况下的行为(因此,它不仅取决于Brainfuck的实现,还取决于用于运行 Brainfuck的实现的实现)。不幸的是,我使用的不可读解释器在标准输出上输出错误,这意味着这种保存不起作用。如果有人知道一个不可读的解释器试图输出EOF而退出,或者无声地跳过了该尝试,请告诉我;那将是一个七字节的解决方案。


1
,[.,]!工作在这里,是6个字节(只需选中标记的方框!)。它也终止。
FinW

@FinW:我不知道如何在该网站中输入一个NUL字节,但是如果看到该代码,它肯定会提前终止。

当我这样做时,它没有NUL字节就可以正常工作。
FinW

1
从字面上看,您有一个,(读取当前磁带元素的标准输入),然后是](如果当前磁带元素为0,则退出循环)。因此,读取值为0的输入字节(即NUL)会破坏循环。

但是,如果解释器未读取任何输入(例如,字符串的末尾!),它将自动将当前的tape元素设置为0,从而结束循环。
FinW

9

Dyalog APL,11 个字节

以下是函数f的主体:

2↓⎕CR'f'⋄→

尾随换行符,之后可以插入任何内容。

2↓ 删除的前两行(标题和此行)

⎕CR'f'fC形容词R表示

然后

放弃


9

Ruby,20个字节

打印*数据
__结束__

输入在末尾(在换行符之后)。这个DATA成语是Ruby 从Perl窃取的众多习语之一。

在eval.in上尝试:https ://eval.in/684370


1
它不仅偷了它,而且还更短……
simbabque

9

JavaScript + HTML5 DOM,163字节

<html><body><script>fetch(location).then((r)=>r.text().then((t)=>console.log(t.slice(145,t.lastIndexOf("</b")))));document.body.remove()</script></body></html>

您可以在结束body标记之前直接插入任何您喜欢的内容。这可以通过获取页​​面源并剥离开始代码和结束标记来实现。

真正的踢手正在弄清楚如何摆脱无限循环。将while(true){}页面放入页面会永久阻止所有回调,从而冻结执行,JavaScript无法暂停主线程。但是,不再存在的代码永远不会运行,因此文档主体在最后一条命令中提交seppuku,并在等待其克隆加载之前删除自身。

是的,这是漫长而又回旋的,但是事实证明,在JS中可能实现这一点实在令人惊奇。


1
Chrome最近对解析器阻止脚本感到非常恼火,并抱怨它们很多。我喜欢故意阻止解析器以防止其中的任何脚本破坏打印尝试的想法。

7

PHP,46字节

(包括结尾的换行符)

<?=join([""]+file(__FILE__));halt_compiler();
STRING HERE

是的:即使该file函数也是二进制安全的。

[""]+ 用空字符串替换0索引(文件的第一行)


6

gs2,4个字节

╥¶=☼

使用CP437编码。字符串在末尾。获取源代码,按4,=删除那么多个前导字符,然后退出。

在线尝试!


5

PHP 94字节

<?$f=fopen(__FILE__,'rb');fseek($f,93);while(false!==($c=fgetc($f)))echo$c;__halt_compiler();

将字符串放在最后的分号之后。

是的,我猜是模糊功能吗?__halt_compiler()完全符合您对名称的期望。先前的代码只是打开文件,并将最后一个分号之后的所有字节写入stdout。NUL,BEL等都很好。Unicode字面量(♪)在Windows上搞砸了,但我认为这只是Windows cmd不能在unicode上使用。


1)我计数93个字节,而不是94个字节。2)false!==$c=...不需要括号。3)rb不需要引号。4)您可以保存一个字节,其中for($f=fopen(...),fseek($f,88);false!==(...);)echo$c;5)可以再短两个字节:<?for($f=fopen(__FILE__,rb);false!==$s=fgets($f,86);)echo$i++?$s:"";__halt_compiler();
Titus

6)和另外两个字节(如果您省略了第二个参数,fgets并在模板中添加尾随换行符)。
泰特斯(Titus)


3

PHP,48 60字节

<?=substr(file_get_contents(__FILE__),60);__halt_compiler();STRING HERE

刚意识到关闭PHP不会阻止包含该字符串<?


您的右括号未正确放置。虽然比我的尝试更整洁的文件转储,但我认为substr()会阻塞空字节-猜不出来。
ToXik-yogHurt '16

试试这个:<?die(substr(file_get_contents(__FILE__),48))?>STRING HERE。应该管用。我试过了<?die('a')?>,它起作用了。
Ismael Miguel

@IsmaelMiguel将不起作用。die不打印其参数,而是将其作为退出代码发送。那将不得不是die(print ...)
泰特斯(Titus)

@ ToXik-yogHurt大多数字符串函数都是二进制安全的。甚至file。实际上,我目前无法想到的不是。
泰特斯

@Titus Trydie('text');
Ismael Miguel

2

二进制Lambda微积分,1个字节

 [text goes here]

这是文本前的单个空格(0x20)。

在线尝试!

这个怎么运作

0x20 = 00100000 2被解析为

00    λx.
01        x
0000  (ignored, can be anything)

(因此,实际上,任何字符!"#$%&\'()*+,-./都可以很好地工作。)

由于这是一个完整的表达式,因此该程序的其余部分将被解释为输入数据,并且在二进制Lambda演算I / O约定下,其标识函数为λx。 x将输入直接复制到输出。


出于兴趣,为什么不回显身份函数和插入之间的结尾零位?

@ ais523解释器一次读取一个字节,一旦λ Xx已被解析,填充已被占用。
Anders Kaseorg



1

Excel VBA,6字节

这主要是为了回答有关如何打印VBA环境中亚当的《对即时窗口的回答》中所保存文本的问题。

基本设置:

在活动表的A1单元格中,使用以下公式保存要打印的字符串。为了字节计数,这应加上1个字节

'[Your Text Here]

例如:

'Hello 
World

立即窗口功能,5 +1 = 6字节

?[A1]

'单元格A1中+1字节


0

Vim(在ex模式下),28个字节

#!/bin/ex -c ':1d' -c ':wq'
[string]

28个字节包括最后一个换行符。


0

Vim,738个字节

:imap <esc> <c-v><esc>
:imap <c-a> <c-v><c-a>
:imap <c-b> <c-v><c-b>
:imap <c-c> <c-v><c-c>
:imap <c-d> <c-v><c-d>
:imap <c-e> <c-v><c-e>
:imap <c-f> <c-v><c-f>
:imap <c-g> <c-v><c-g>
:imap <c-h> <c-v><c-h>
:imap <c-i> <c-v><c-i>
:imap <c-j> <c-v><c-j>
:imap <c-k> <c-v><c-k>
:imap <c-l> <c-v><c-l>
:imap <c-m> <c-v><c-m>
:imap <c-n> <c-v><c-n>
:imap <c-o> <c-v><c-o>
:imap <c-p> <c-v><c-p>
:imap <c-q> <c-v><c-q>
:imap <c-r> <c-v><c-r>
:imap <c-s> <c-v><c-s>
:imap <c-t> <c-v><c-t>
:imap <c-u> <c-v><c-u>
:imap <c-v> <c-v><c-v>
:imap <c-w> <c-v><c-w>
:imap <c-x> <c-v><c-x>
:imap <c-y> <c-v><c-y>
:imap <c-z> <c-v><c-z>
:imap <c-@> <c-v><c-@>
:imap <c-\> <c-v><c-\>
:imap <c-]> <c-v><c-]>
:imap <c-^> <c-v><c-^>
:imap <c-?> <c-v><c-?>
i

将插入模式下的所有控制字符重新绑定到<c-v>,然后是该控制字符,它将按字面意义输入它们。^ _(单元分隔符)似乎不需要重新绑定,因为默认情况下它实际上是输出的。

当然,可变文本位于结尾。

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.