容错Hello World(又名采访)


66

面试结束时,邪恶面试官告诉您:“我们让所有申请人进行简短的编码测试,以查看他们是否真的知道自己在说什么。不用担心;这很容易。如果您创建了一个工作程序,我会立即为您提供工作。” 他示意您坐在附近的计算机旁。“您要做的就是创建一个可正常运行的Hello World程序。但是,”-他大笑着说-“有一个陷阱。不幸的是,我们在这台计算机上拥有的唯一编译器存在一个小错误。它会从该计算机中随机删除一个字符。源代码文件,然后再编译。好的,五分钟后见!” 然后他走出房间,开心地吹口哨。

您能保证得到这份工作吗?

任务

编写一个程序,Hello, world!即使从文件中的任何位置删除了单个字符,也可以打印到标准输出。或者尽可能接近这个。

规则

没有多余的输出 - Hello, world!必须是打印到标准输出的唯一实质性内容。如果其他字符是由您选择的语言自然产生的,则可以包含其他字符,例如尾随换行符,甚至类似的字符[1] "Hello, world!"(例如,如果您使用的是R),但每次都必须打印完全相同的字符 它不能打印Hello, world!Hello, world!Hello world!" && x==1在某些时候,例如。但是,允许警告。

测试为了测试以确定您的分数,您必须测试程序的每个可能排列:在删除每个字符的情况下对其进行测试,并查看其是否产生正确的输出。为此,我在下面提供了一个简单的Perl程序,该程序应适用于多种语言。如果它对您不起作用,请创建一个测试程序并将其包含在您的答案中。

计分您的分数是程序失败的次数。换句话说,文件中删除字符的各个位置数量使程序无法运行。最低分获胜。如果出现平局,则以最短的代码为准。

诸如"Hello, world!"多种语言(15种分数)之类的简单解决方案是可以接受的,但它们不会赢。我至少找到了一个Perl解决方案,其得分为4,我将最终发布它。

更新: 官方优胜者将使用图灵完备的编程语言,并且不会使用任何预定义的打印机制Hello, world!。所使用的任何外部资源(语言的标准库除外)都被视为程序的一部分,并且会被相同的1个字符删除。 这些要求贴在桌子上的便签纸上。抱歉,如果您最初没有看到它们。

更新2:是的,您的程序必须实际完成上述任务才能获得分数!意味着它应该Hello, world!至少成功打印一次。这应该是显而易见的。命令行开关和其他添加功能的设置也算作程序的一部分,并且必须删除单个字符。该程序必须在没有任何用户输入的情况下完成其任务。编译失败包括在您的失败计数中。

祝您编程愉快,并祝您工作顺利。但是,如果您失败了,您可能还是不想为那个邪恶的老板工作。

Perl测试脚本:

use warnings;
use strict;

my $program   = 'test.pl';
my $temp_file = 'corrupt.pl';
my $command = "perl -X $temp_file"; #Disabled warnings for cleaner output.
my $expected_result = "Hello, world!";

open my $in,'<',$program or die $!;
local $/;           #Undef the line separator   
my $code = <$in>;   #Read the entire file in.

my $fails = 0;
for my $omit_pos (0..length($code)-1)
{
    my $corrupt = $code;
    $corrupt =~ s/^.{$omit_pos}\K.//s;  #Delete a single character

    open my $out,'>',$temp_file or die $!;
    print {$out} $corrupt;  #Write the corrupt program to a file
    close $out;

    my $result = `$command`;    #Execute system command.
    if ($result ne $expected_result)
    { 
        $fails++;
        print "Failure $fails:\nResult: ($result)\n$corrupt";
    }
}

print "\n$fails failed out of " . length $code;

1
删除的字符会导致程序无法编译吗?仍然算不上吗?
lochok

@lochok,是的,那将视为失败。任何导致Hello, World!无法打印的已删除字符都是失败的。


@Walkerneo,谢谢!我搜索了类似的问题,但没有找到那个问题。我认为这是明显不同的。特别地,该问题保证仅必须处理导致句法有效的代码的修改。

您能否举一个“命令行开关和其他增加功能的设置”的例子?您是指赋予程序本身的开关和设置,还是在构建环境中使用开关和设置?
CasaDeRobison

Answers:


129

Befunge,得分0

我想我破解了它-没有单个字符删除将更改输出。
从第1行删除任何字符不会改变任何内容-它仍然在同一位置掉线。
第2和3行是多余的。通常执行第2行,但是如果您从其中删除一个字符,<则会错过,第3行负责。
删除换行符也不会破坏它(确实破坏了我以前的版本)。
没有测试程序,对不起。

编辑:简化了很多。

                              vv
@,,,,,,,,,,,,,"Hello, world!"<<
@,,,,,,,,,,,,,"Hello, world!"<<

流程的简短说明:

  1. Befunge从左上方开始执行,向右移动。空间什么都不做。
  2. v 将执行流程下移,因此它向下一行。
  3. < 将执行流向左移,因此它以相反的顺序读取第2行。
  4. "Hello, world!"将字符串压入堆栈。它以相反的顺序推送,因为我们正在从右到左执行。
  5. ,弹出一个字符并打印。首先打印最后输入的字符,这将再次反转字符串。
  6. @ 终止程序。

2
+1,很好的解决方案。我认为不需要测试程序,因为很明显只有少量潜在的重要删除。

4
如此容易验证,无需讨论。天才!
Karma Fusebox

恭喜您获得了出色的解决方案。

2
我知道这不是代码高尔夫,但这是66个字节的版本。
MD XF

42

Perl,得分0

(147个字符)

这是我的解决方案,我设法将其从4降至0:

eval +qq(;\$_="Hello, world!";;*a=print()if length==13or!m/./#)||
+eval +qq(;\$_="Hello, world!";;print()if*a!~/1/||!m/./#)##)||
print"Hello, world!"

它必须全部显示在一行上才能起作用;换行符仅用于“可读性”。

它受益于Perl的病理允许语法。一些重点:

  • 无法识别的裸词被视为字符串。因此,当eval变为时evl,如果此时允许使用字符串,这不是错误。
  • 一元+运算符,除了在某些情况下消除语法歧义外别无其他。上面的代码很有用,因为当函数名变形并变成字符串时,function +argument(其中+是一元)变成string + argument(加法)。
  • 声明字符串的方法很多:双引号字符串qq( )可以变成单引号字符串q();用括号分隔的字符串qq(; ... )可以变成用分号分隔的字符串qq; ... ;#内部字符串可以通过将事物转换为注释来消除平衡问题。

尽管我怀疑ugoren的解决方案是否可行,但其长度可能可以减少一些。


13
+1 换行符是可读性只是 ...
Bakuriu

40

HQ9 +

当删除字符时,这将永远不会产生预期的结果,因此得到零分。

HH

我什么时候开始?


1
它会产生“你好,世界”,而不是“你好,世界!” 作为指定。
Paul R

16
废话,只是在esolang Wiki上错误地指定了该语言;)
skeevey 2013年

11
如果他们在采访计算机上有HQ9 +编译器,则对您有好处... :)

您可以编写自己的错误编译器。
PyRulez 2014年

2
@ mbomb007 此解释器Hello, world!H命令打印。
丹尼斯

12

Befunge-98,得分0,45个字节

20020xx""!!ddllrrooww  ,,oolllleeHH""cckk,,@@

在线尝试!

尽管已经找到了最佳解决方案(并且没有打破常规的决定),但我认为我可以证明使用Befunge 98可以大大简化此过程。

说明

所述20020xx可靠地设置为增量(蜱之间的指令指针的步骤:a)(2,0)使得从第一个x时,执行仅每隔命令。请参阅此答案以详细了解其工作原理。之后,代码仅仅是:

"!dlrow ,olleH"ck,@

我们首先使用将所有相关的字符代码压入堆栈"!dlrow ,olleH"。然后ck,意味着打印纸堆的顶部(,),打印13(c加1)次(k)。@终止程序。


11

J,7分

选择每个具有奇数位置的字母:

   _2{.\'HHeellllo,,  wwoorrlldd!!'
Hello, world!

5
在golfscript同样的事情会是4点:'HHeelllloo,, wwoorrlldd!!'2%
cardboard_box

@cardboard_box随时提交。:)
randomra

投票是因为我理解它,而且感觉不像是作弊。
Michael Stern

3

Befunge-93,得分0(63字节)

我知道这不是一个代码挑战,但是我认为如果可以在大小方面改进现有的Befunge-93解决方案,将是一件很有趣的事情。我最初开发此技术是为了在类似的Error 404挑战中使用,但是在这种情况下,由于需要包装有效载荷,因此三线解决方案更加理想。

这虽然不如Martin的Befunge-98回答,但与获胜的Befunge-93解决方案相比仍是一个相当大的减少。

<>>  "!dlrow ,olleH">:#,_@  vv
  ^^@_,#!>#:<"Hello, world!"<<>#

在线尝试!

说明

有效负载有两种版本。对于未<更改的程序,第一个导致程序从右到左执行,环绕到该行的末尾,直到到达v将其向下引导到第二行,然后<将其向左引导到左至右版本为止的有效载荷。

第二行出现错误会导致决赛<向左移动,而改为由>指挥流向右移动。该#(桥)命令无关跳过,所以代码只是继续进行,直到它环绕并达到^在该行的开始,引导其到第一线,然后>将其引导到正确的从右至左有效载荷。

第一行中的大多数错误只会使最终v命令移一个,但这并不会改变代码的主要流程。但是,删除第一个<略有不同-在这种情况下,执行路径仅直接流入第一行中从左到右的有效负载。

另一个特殊情况是删除换行符。当代码回绕到行的末尾时,在这种情况下,它现在是第二行的末尾。当它#从右边遇到命令时,它会跳过>并因此直接进入从右到左的有效负载。

如果有任何疑问,我还对perl脚本进行了测试,它确认“ 63中的0失败”。


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.