您的任务是编写一个由一些字节序列组成的非空计算机程序。如果我们在程序中选择一个特定的字节并将其所有实例从程序中删除,则修改后的程序应输出删除的字节。
例如,如果我们的程序是
aabacba
然后bcb
将输出a
,aaaca
将需要输出b
并且aababa
将输出c
。
未经修改的程序做什么无关紧要。
答案将以字节计分,目标是最大程度地减少字节数。
您的任务是编写一个由一些字节序列组成的非空计算机程序。如果我们在程序中选择一个特定的字节并将其所有实例从程序中删除,则修改后的程序应输出删除的字节。
例如,如果我们的程序是
aabacba
然后bcb
将输出a
,aaaca
将需要输出b
并且aababa
将输出c
。
未经修改的程序做什么无关紧要。
答案将以字节计分,目标是最大程度地减少字节数。
Answers:
ec
ho \\n;ca t<<<$'\x20';exi t
d$c -e8BC6P
d0c -eKp
$'\172\163\150' $'\055\143' $'\146\157\162 v \151\156 \173\043\056\056\134\175\175\073\173 \146\147\162\145\160 \055\161 $\166 '$0$'\174\174\074\074\074$\166\073\175'
$'\145v\141\154' $':\073\072\046\046\145\170\151\164';#%&()*+,/9=>?@ADEFGHIJLMNOQRSTUVWXYZ[]^_`jklmsuwy
0# $#;for b in {$..z};{ fgrep -q $b $0||<<<$b;}
取决于coreutils + dc
。
那是一次旅程。
这个答案分为三个部分。前4行处理某些特殊情况,以简化随后的代码。接下来的2行和最后一行基本上都完成了相同的操作,但是在除去任何给定字符的情况下,仅运行了一行。它们是用大多数互补的字符集编写的,因此删除任何字符最多只会破坏一个字符,从而使另一个字符继续起作用。
看第一部分,我们先处理
ec\nho \\n
ca t<<<$'\x20'
(其后exi t
为避免运行以后的代码,这将导致多余的输出)$
用d$c -e8BC6P
(8BC6
= 9226
是36*256 + 10
,和36和10分别是$
和和换行符的字节值;使用十进制的十六进制数字来避免必须将它们包括在第6行的大注释中)0
用d0c -eKp
(K
进行删除)获取小数精度,0
默认情况下为在下一部分中,除了第二行末尾的垃圾外,其余唯一的字符是$'\01234567v;
,空格和换行符。其中,已经考虑了四个,因此其余('\1234567v
)不能出现在最后一行。扩展八进制转义$'\123'
符(表示值为123 8的ASCII字符),我们得到:
zsh -c 'for v in {#..\}};{ fgrep -q $v '$0'||<<<$v;}'
eval ':;:&&exit'
第一行循环遍历程序中使用的所有字符,并在其自己的源代码($0
正在运行的脚本的文件名)中搜索每个字符,并打印未找到的任何字符。
第二行看起来有些奇怪,并且看起来exit
和一堆点子一样。但是,编码exit
为八进制会直接导致$'\145\170\151\164'
,其中不包含2
或3
。我们实际上需要使它对清除的适应性降低。这是因为,如果'\014567v
删除了其中任何一个,则中断第一行,第二行也中断,从而允许其余代码执行。但是,我们需要它也要断开2
或断开,3
以便3和4行可以运行。这可以通过在:
和中的鞋拔来实现;
,它们的八进制表示分别为2和3。
第2行末尾的垃圾只是在那里,以确保每个可打印的ASCII字符至少出现一次,因为通过遍历每个字符进行检查的方式需要这样做。
如果exit
在第一部分中未调用(即已通过删除其中一个进行了修改'\01234567v
),则继续进行第二部分,在第二部分中,我们必须完成相同的操作而不使用任何这些字符。最后一行与解码后的第一行相似,不同之处在于我们可以缩小循环范围以节省一些字节,因为我们已经知道除以外的所有字符'\01234567v
都已被覆盖。它也有0# $#
在它之前,该评论出来并防止其产生,如果无关的输出0
或$
除去。
216173027061157310 = (144115617572598740 + 144115241762960340 + 144115194786755540) / 2
。有216173027061157310 - 144115617572598740
$
s,216173027061157310 - 144115241762960340
#
s和216173027061157310 - 144115194786755540
空格。
144115617572598740 #
s和空格编码以下BF程序:
++++++[>++++++<-]>.
144115241762960340 $
s和空格编码以下BF程序:
+++++++[>+++++<-]>.
144115194786755540 $
s和#
s编码以下BF程序:
++++++++[>++++<-]>.
编辑:由于@Nitrodon,节省了72057832274401770字节。
U
是可以输出的最短可打印ASCII字节。我不想使用不可打印的字节。
00000000: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000010: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000020: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000030: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000040: 0000 0000 0000 0000 0000 0000 0000 0000 ................
00000050: 0000 0000 0101 0101 0101 0101 0101 0101 ................
这是xxd
转储。
一元语言的更广泛定义允许其源代码中包含任何字符。但是我没有找到可以使用的编译器或解释器。因此,我将此答案标记为非竞争性。如果您能找到一个在问这个问题之前发布的内容,我会链接到它。