编写一个在循环字符转换后有效的程序


17

可能非常困难,但是我已经看到一些令人惊奇的事情从该站点中出现。

目的是用任何语言编写一个可以执行您想要的任何程序。值得注意的是,在字符的任何循环移位之后,程序都必须有效。

圆形字符移是非常类似于一个循环移位。一些例子让我明白了。

对于程序 int main() { return 0; }

向左移动6个字符将产生: in() { return 0; }int ma

向左移动1个字符将产生: nt main() { return 0; }i

向右移动10个字符将产生: eturn 0; }int main() { r

但是,该程序显然不符合规则。

规则

  • 任何语言
  • 获胜者取决于投票数
  • 对于每次旋转执行相同或完全不同的操作的解决方案,将获得100个虚拟上投票给他们的分数。

更新我认为这已经持续了很长时间。得票最多(包括虚拟投票)的获胜者是马克·拜尔斯。做得好!


5
在int文字是有效程序的语言中,有一些非常无聊的潜在答案。他们收到虚拟的-100吗?
彼得·泰勒

1
@PeterTaylor我假设无聊的答案将获得较少的选票。
格里芬2012年

“可能非常困难”在以一般方式做出这种陈述之前,熟悉许多奇怪的语言总是有帮助的。当然,很难用c或java编写,但要使用具有1个字符命令和简单语法的语言?没那么多。
dmckee 2012年

@dmckee因此是“潜在的” ...
Griffin

@PeterTaylor也使用多种语言,空程序是有效的程序
jk。

Answers:


31

为任务使用正确的语言。在这种情况下,那就是Befunge

这种语言自然允许旋转,因为:

  • 所有命令都是单个字符。
  • 控件在到达程序末尾时从头开始重新缠绕。

无论您使用多少“圆形字符移位”,此Befunge程序都会打印出完全相同的输出(“ Hello”):

86*01p75*1-02p447**1-03p439**04p439**05p455**1+06p662**07p75*1-08p645**2-09p69*4+019+p57*029+p59*1-039+p555**1-049+p88*059+p86*01p75*1-02p447**1-03p439**04p439**05p455**1+06p662**07p75*1-08p645**2-09p69*4+019+p57*029+p59*1-039+p555**1-049+p88*059+p645**2-00p645**2-00p

它在Befungee运行。它要求增加木板(不是默认的80个字符)。可以这样运行:

python befungee.py -w400 hello.bef

它的工作方式是首先动态生成并存储打印“ Hello”的程序,然后覆盖第一个字节以将控件重定向到新编写的程序中。程序被写入两次,因此,如果第一次未正确写入字节,则第二次将对其进行更正。

这个想法可以扩展到产生任意复杂性的任何程序。


很好的入门!
ChristopheD

22

Brainf * ck

选择合适的工具来完成这项工作,这句话比以往任何时候都更加重要!

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++++++++++++++++.>+++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++++++++++++++.+.>++++++++++++++++++++++++++++++++++
++++++++++++++++++++++++++++++++++++.++++++++++++++.>++++++++++.+

您在此处看到的未移位程序仅打印SHIFT(加上换行符)。任意循环移位将产生其他各种输出,尽管它将始终输出六个ASCII字符。


我读了这个问题,然后想到,Brainfuck,那是票,但是您击败了我。
jmoreno 2012年

12

Commodore 64 BASIC

?是的缩写PRINT:是语句分隔符,因此:

?1:?2:?3:          // prints 1, 2, and 3
:?1:?2:?3          // prints 1, 2, and 3
3:?1:?2:?          // adds a program line 3 :PRINT1:PRINT2:PRINT
?3:?1:?2:          // prints 3, 1, and 2
:?3:?1:?2          // prints 3, 1, and 2
2:?3:?1:?          // adds a program line 2 :PRINT3:PRINT1:PRINT
?2:?3:?1:          // prints 2, 3, and 1
:?2:?3:?1          // prints 2, 3, and 1
1:?2:?3:?          // adds a program line 1 :PRINT2:PRINT3:PRINT

当然,更长的变化是可能的:

?1:?2:?3:?4:?5:?6:?7:?8:?9:?10:?11:

等等...


11

高尔夫脚本

不管程序如何移动,此程序都会打印一些总为2的数字:

10 2 base
0 2 base1
 2 base10
2 base10 
 base10 2
base10 2 
ase10 2 b
se10 2 ba
e10 2 bas

第一行打印1010(二进制为10),第二行打印02,其他所有行打印2

更新:

该程序可以在这里进行测试。请注意,我n仅在每一行的末尾添加了s,用于格式化输出;这些可以删除,该程序仍然可以运行。


10

Ruby,可能是最短的解决方案之一:

p

还有另一个稍微更长一点,更有趣的东西:

;;p";p;";p

9

x86 16位二进制

在这些(1 2)表nasm和ndisasm 的帮助下手动构建。这将始终返回而不会导致崩溃或无限循环,因为没有字节会跳转或更改堆栈,并且ret在任何情况下都将用NOP填充以单字节指令结尾。

在大多数情况下,这将输出FOO或该字符串的子字符串。如果AX被破坏,它将调用一个随机的int 10(这在我的一项测试中改变了光标的闪烁速度),但通常不会导致崩溃。

要进行尝试,请将hexdump放在文件中并使用xxd -r foo.hex > foo.com,然后在dos环境中运行(我使用过dosbox)。

这是此文件的十六进制转储:

0000000: b846 0d90 90fe c490 9090 bb05 0090 9043  .F.............C
0000010: 43cd 1090 b84f 0d90 90fe c490 9090 bb05  C....O..........
0000020: 0090 9043 43cd 1090 b84f 0d90 90fe c490  ...CC....O......
0000030: 9090 bb05 0090 9043 43cd 1090 9090 c3    .......CC......

还有一些有趣的反汇编偏移:

+0

00000000  B8420D            mov ax,0xd42
00000003  90                nop
00000004  90                nop
00000005  FEC4              inc ah
00000007  90                nop
00000008  90                nop
00000009  90                nop
0000000A  BB0500            mov bx,0x5
0000000D  90                nop
0000000E  90                nop
0000000F  43                inc bx
00000010  43                inc bx
00000011  CD10              int 0x10
00000013  90                nop
00000014  B84F0D            mov ax,0xd4f
00000017  90                nop
00000018  90                nop
00000019  FEC4              inc ah
0000001B  90                nop
0000001C  90                nop
0000001D  90                nop
0000001E  BB0500            mov bx,0x5
00000021  90                nop
00000022  90                nop
00000023  43                inc bx
00000024  43                inc bx
00000025  CD10              int 0x10
00000027  90                nop
00000028  B84F0D            mov ax,0xd4f
0000002B  90                nop
0000002C  90                nop
0000002D  FEC4              inc ah
0000002F  90                nop
00000030  90                nop 
00000031  90                nop
00000032  BB0500            mov bx,0x5
00000035  90                nop
00000036  90                nop
00000037  43                inc bx
00000038  43                inc bx
00000039  CD10              int 0x10
0000003B  90                nop
0000003C  90                nop
0000003D  90                nop
0000003E  C3                ret

(对于以下示例,二进制文件的其余部分仍然有效)

+1

00000000  42                inc dx
00000001  0D9090            or ax,0x9090
00000004  FEC4              inc ah
00000006  90                nop

+2

00000001  0D9090            or ax,0x9090
00000004  FEC4              inc ah
00000006  90                nop

+6

00000000  C4909090          les dx,[bx+si-0x6f70]
00000004  BB0500            mov bx,0x5
00000007  90                nop
00000008  90                nop
00000009  43                inc bx
0000000A  43                inc bx
0000000B  CD10              int 0x10

+11

00000000  050090            add ax,0x9000
00000003  90                nop
00000004  43                inc bx
00000005  43                inc bx
00000006  CD10              int 0x10

+12

00000000  00909043          add [bx+si+0x4390],dl
00000004  43                inc bx
00000005  CD10              int 0x10

+18

00000000  1090B84F          adc [bx+si+0x4fb8],dl
00000004  0D9090            or ax,0x9090
00000007  FEC4              inc ah
00000009  90                nop

(其他偏移量只是上述内容的重复)

+58

00000000  10909090          adc [bx+si-0x6f70],dl
00000004  C3                ret

7

一元答案:

000000 ... 00000

^ 44391零

猫程序。无论您如何旋转,它都是相同的程序。


6

的PHP

这里是一个有效的PHP程序:

Is this still funny?

2
您应该使用“ ate”之类的词(我敢肯定还有更长的词),这样每个字符移位仍然是一个真实的词。
彼得(Peter

10
我不确定是+1还是-1
Lie Ryan

6

斯卡拉

嵌套的引号:

""""""""""""""""""""""""""""""""

C ++ / Java / C#/ Scala

评论:

///////////////////////////////////

空命令:

;;;;;;;;;;;;;;;

重击

Comment,Whitespace和Shell内置组合:

#

:

塞德

独立的有效命令:

p P n N g G d D h H

以上各项的组合:

p;P;n;N;g;G;d;D;h;H;

AWK

要打印文件的每一行:

1

要么

//

不要打印任何内容:

0

佩尔

abcd

在我看来,SED在任何奇怪的旋转下都会失败?是否;P;n;N;g;G;d;D;h;H有效?
captncraig 2012年

@CMP:是的,它是有效的。
约翰·卫斯理亲王

5

Ĵ

首先,一个脚本来检查程序的有效旋转s

check =: 3 :'((<;(". :: (''Err''"_)))@:(y |.~]))"0 i.#y'

例如,程序+/1 5(1和5的总和)给出:

 check '+/1 5'
┌───────┬───┐
│┌─────┐│6  │
││+/1 5││   │
│└─────┘│   │
├───────┼───┤
│┌─────┐│Err│
││/1 5+││   │
│└─────┘│   │
├───────┼───┤
│┌─────┐│Err│
││1 5+/││   │
│└─────┘│   │
├───────┼───┤
│┌─────┐│6  │
││ 5+/1││   │
│└─────┘│   │
├───────┼───┤
│┌─────┐│6  │
││5+/1 ││   │
│└─────┘│   │
└───────┴───┘

然后,一个无聊的有效程序:

check '1x1'
┌─────┬───────┐
│┌───┐│2.71828│ NB. e^1
││1x1││       │
│└───┘│       │
├─────┼───────┤
│┌───┐│       │ NB. Value of variable x11
││x11││       │ 
│└───┘│       │
├─────┼───────┤
│┌───┐│11     │ NB. Arbitrary precision integer
││11x││       │
│└───┘│       │
└─────┴───────┘

2

直流电

dc程序很容易在任何循环中有效。例如:

4 8 * 2 + p  # 34
8 * 2 + p 4  # stack empty / 10
...

1

机器码

Z80 / Intel 8051 NOP的机器代码如何?

当然,它不执行任何操作,但确实需要一个或两个周期...您可以根据需要选择任意多个。

而且我不同意上面的Ruby回答-我认为单个字节00h比Ruby短p


1

ķ

.""

评估一个空字符串

"."

返回句点字符

"".

返回“。”的部分应用。(深红色形式)为空字符列表。


1

cc
cc: no input files

cc再次旋转为cc,但是如果这样裸着,它不是非常友好。

dh 
dh: cannot read debian/control: No such file or directory
hd 

dh debhelper也不太配合,而hexdump只是在等待输入。

gs
sg 

Ghostscript启动交互模式,而交换机组显示用法消息-此处也是一个有效的解决方案,恕我直言。

这是查找此类程序候选人的脚本:

#!/bin/bash
for name in /sbin/* /usr/sbin/* /bin/* /usr/bin/*
do 
    len=${#name}
    # len=3 => 1:2 0:1, 2:1 0:2
    # len=4 => 1:3 0:1, 2:2 0:2, 3:1 0:3
    for n in $(seq 1 $((len-1)))
    do
        init=${name:n:len-n}
        rest=${name:0:n}
        # echo $init$rest
        which /usr/bin/$init$rest 2>/dev/null >/dev/null && echo $name $init$rest $n
    done 
done

如果还发现更长的序列,例如(arj,jar)或(luatex,texlua),它们在每个班次之后都是无效的,但是仅在某些班次之后才有效,我一开始就误读了,但是很少,所以很容易用手将它们过滤掉。


超过两个字母的示例无效。OP表示“程序必须在任何循环移位后才有效”。因此,arj/ jar无效,因为没有rja命令(尽管我喜欢此示例)。脚本的+
1-

由于我不确定,而不是说英语的母语人士,因此我查阅了词典,发现该词典是含糊不清的,无论是意思every还是意思a random one。用这个例子shift left by 6left by 1right by 10保证我的解释,我只需要找到一个转变的可能性。
用户未知

这不是模棱两可的。如果某个程序在随机移位后必须有效,那么它对于每个可能的移位也必须有效。
格里芬2012年

@格里芬:好的-你写了这个问题。我删除了较长的示例;幸运的是,在gs和sg之类的unix中有足够的crptc abbrv prgnms。:)顺便说一句:您是母语为英语的人吗?在前面的句子中,您写道... in any language ... -我的解决方案仅适用于bash(以及sh,zsh,ash和其他一些语言),但是所有其他解决方案也都采用程序名称。
用户未知

0

简单的Python示例:

"a""b""c""d""e""f""g""h""i""j""k""l""m""n""o""p""q""r""s""t""u""v""w""x""y""z""";print

可能会反复移动三个字符以显示越来越多的字母。


抱歉,我应该把问题弄清楚。任何班次必须产生一个有效的程序。我已经更新了问题。
格里芬


0

dc已经被使用,但是下面的程序总是输出相同的,无论旋转:D

d

输出

dc: stack empty
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.