用您喜欢的语言生成一个随机程序[关闭]


21

我们都听说过使用随机生成的输入来测试编译器。您的任务是编写一种程序,以您喜欢的语言生成一个有效的程序(不包括未定义的行为)。生成的程序语言不必与生成的程序语言相同。

您的程序将收到一个整数作为参数,您可以将其用作随机数生成器的种子。生成的程序在结构上应该不同(给定不同的种子),而不仅仅是不同的变量名或常量。

例子:

$ ./generate 1
int main() { return 0; }

$ ./generate 2
#include <math.h>
int main() { return (int) pow(4, 3); }

请在回答中包括几个输出。

最短的解决方案获胜。我会根据投票数提供少量奖金,因此请投票出最具创意的解决方案。


2
开发具有开放式进化的遗传算法的完美任务。我一直想知道怎么做。
mellamokb 2011年

1
我认为缺少固定的规范使这成为一个坏问题。“结构上不同”易于解释,在某些解释中,这是一个非常简单的问题。
Peter Taylor

1
一个人真正需要做的就是打高尔夫球,这个程序可以根据给定的BNF语法生成一个随机句子(这是微不足道的)。然后只需插入任何其他编程语言和poof的语法:该语言的有效程序。这将适用于任何无上下文的语言(不幸的是排除了Perl)。
ESultanik 2011年

2
main(seed) { return 4; // Chosen by dice roll - Guaranteed to be random } 参考
Neil

1
尼尔:只是要注意:这里的每个人大概都知道xkcd,尤其是链接的人。他们可能也知道Dilbert随机数。它与这里无关,因为它要求的程序具有随机结构,而不仅仅是一个随机数。
乔伊,

Answers:


18

蟒→Brainf * CK(185 223 233 255 285个 287个 303字符)

import random as r,sys
r.seed(int(sys.argv[1]))
c=list('<>.,+-')+['']
n=9/r.random()
def b():
 global n
 s=''
 while n>0:n-=1;o=r.choice(c);s+=o if o else'[%s]'%b()
 return s
print b()
  • 303→287字符:已删除math.ceil(并非必需)。
  • 287→285个字符:切换为空字符串以表示分支运算符。
  • 285→255个字符:在while循环中压缩if语句。
  • 255→233个字符:从注释中实施了JBernardo的建议。
  • 233→223角色:根据评论实施tjko的建议。
  • 223→185个字符:在注释中实施了一些减少空格的建议。

例子

$ python generate.py 1
-->,,+-<<-,-<,->[[<<,[.>.<>,,>>>,.<-,+>[[<.-+[.-+.+[-,+<>-.>,++.,,-,.,<<+[+]]]]]]]]
$ python generate.py 2
[<<--+.+++>]
$ python generate.py 3
,.++<<->>[,-,+>+[,-+<-+.<[,-[+[.-,[[<<>[,+.]]]]]]]]

实际上,要弄清楚最终的BF程序将什么,是读者的一项练习。


您也可以使用if o: s+=0(NL)else: s+='['+b()+']'
Alexandru

@Alexandru:谢谢!我错过了。您的代码似乎无法正常运行,但可以帮助我缩短代码长度。
ESultanik

3
这是否以某种方式意味着Brainfuck是您最喜欢的语言?
zneak

1
并不是说这是一个问题,但是输出的代码可能会导致无限循环。
彼得·奥尔森

6
@Peter,是的,但是避免使用这种随机生成方法可能等效于解决停止问题!
ESultanik 2011年

17

Python-> Piet,385 345个字符

可以生成任何Piet程序。我可以停在随机像素上,但是我想制作“有趣的”程序。该函数m为像素绘制颜色,然后递归地进入每个相邻的像素。有更好的绘制随机斑点的方法,但是此方法已调整为以合理的步数终止,因此对于高尔夫来说已经足够了。该函数R(w,h,n)n个随机斑点吸引到(w x h)白色图像上,并以PPM格式打印结果。

我为自己产生的颜色而感到特别自豪-随机选择0 <= c < 20

`[0,192,255][int(x)]`for x in'0002212220200101121100'[c:c+3]

是Piet调色板中有效颜色的十进制代码(通过单轨格雷代码)。即,每种颜色由3个相邻位'0003...0'[c:c+3]表示,并且每个条带表示不同的颜色。由于这不是3个字母上27个单词的完整列表,因此我非常幸运地找到了格雷码。

from random import*
r=randint
def R(w,h,n):
 M=[6]*h*w
 def m(x,y,c,d):M[y%h*w+x%w]=c;t=r(0,15)*(r(0,d)<2);t&8and m(x+1,y,c,d+1);t&4and m(x-1,y,c,d+1);t&2and m(x,y+1,c,d+1);t&1and m(x,y-1,c,d+1)
 while n:m(r(0,w),r(0,h),r(0,19),0);n-=1
 print"P3 %s %s 255 "%(w,h)+' '.join(`[0,192,255][int(x)]`for c in M for x in'0002212220200101121100'[c:c+3])

示例输出,由命令生成 R(30,40,500)

random Piet program

没有导入,我也可以将其编写为适当的(无分号)1-liner:

import random
R=(lambda P,I,E,T:lambda w,h,n:E(w,h,I(w,h,n,lambda z,c,d,t:sum((((z,c),)*t*T(0,1)or m((z[0]+a,z[1]+b),c,d+1,T(0,d)>1)for a,b in((0,1),(1,0),(-1,0),(0,-1))),()))))(range,lambda w,h,n,m:dict(sum((m((T(0,w),T(0,h)),T(0,19),0,0)for _ in P(n)),())),lambda w,h,M:"P3 %s %s 255 "%(w,h)+' '.join(' '.join(`(x&1)*255+(x&2)*96`for x in map(int,'0001121110100202212200'[c:c+3]))for c in(M[z]if z in M else 6for z in((x,y)for y in P(h)for x in P(w)))),random.randint)

但它是可笑的慢(几乎100个字符)......虽然我不完全知道为什么(而不是可怕的倾斜来查找出来)。


9

Python-> Python,135个字符

import random,sys
random.seed(int(sys.argv[1]))
R=range(9)
print'print 1'+''.join(random.choice('+*')+'%d'%random.choice(R)for x in R)

生成很少的随机表达式求值,如下所示:

> ./genprogram.py 1
print 1+7*2+4*7+0*3*0+6+8
> ./genprogram.py 2
print 1*8+0*6*2*5*1+3*8*4
> ./genprogram.py 3
print 1+4+5*0+7+2*4*4*1*7
> ./genprogram.py 4
print 1+0+1+3*7*1*2+0+8*7

8

Python-> HQ9 +:108个字符

import random
def g(): return ''.join([random.choice(['H','Q','9','+']) for x in range(random.randint(1,9))])

6

PHP,352个字符

在PHP中生成PHP代码。

我决定我不太在意长度,而是想要一套有趣且多样化的解决方案。这就是我的回答。

<?php mt_srand(0+$argv[1]);$r=mt_rand(1,100);$s="\$i=rand(1,$r);";while($r>0){$s.='$i';if(!($r%10))$s.='*=2;';if(!($r%9))$s.='++;';if(!($r%8))$s.='=pow($i,rand(1,$i));';if(!($r%7))$s.='--;';if(!($r%6))$s.='=substr($i,0,2);';if(!($r%5))$s.='/=2;';if(!($r%4))$s.='+=4;';if(!($r%3))$s.='*=-1;';$r-=mt_rand(1,5);}$s.='var_dump($i);';echo"<?php $s
";

不打高尔夫球

<?php
mt_srand(0+$argv[1]);
$r = mt_rand(1,100);
$s = "\$i=rand(1,$r);";
while ($r > 0)
{
    if (!($r%10)) $s .= '$i*=2;';
    if (!($r%9))  $s .= '$i++;';
    if (!($r%8))  $s .= '$i=pow($i,rand(1,$i));';
    if (!($r%7))  $s .= '$i--;';
    if (!($r%6))  $s .= '$i=substr($i,0,2);';
    if (!($r%5))  $s .= '$i/=2;';
    if (!($r%4))  $s .= '$i+=4;';
    if (!($r%3))  $s .= '$i*=-1;';
    $r -= mt_rand(1,5);
}
$s .= 'var_dump($i);';
echo "<?php $s
";

> php r.php 1
<?php $i=rand(1,58);$i*=-1;$i=pow($i,rand(1,$i));$i=substr($i,0,2);$i+=4;$i*=-1;$i=pow($i,rand(1,$i));$i=substr($i,0,2);$i+=4;$i*=-1;$i*=2;$i/=2;$i+=4;$i/=2;$i*=-1;$i*=2;$i/=2;$i=substr($i,0,2);$i*=-1;var_dump($i);
> php r.php 2
<?php $i=rand(1,57);$i*=-1;$i+=4;$i--;$i=substr($i,0,2);$i*=-1;$i*=-1;$i--;$i+=4;$i/=2;$i++;$i=substr($i,0,2);$i*=-1;$i=pow($i,rand(1,$i));$i+=4;$i--;$i=substr($i,0,2);$i+=4;$i*=-1;$i--;$i+=4;var_dump($i);

2
您能提供一个输出示例吗?
Alexandru

5

斯卡拉:1543(scala =>斯卡拉)

我有变量(x,y,z),函数(mul,add,neg,abs),值和平衡括号。

<!--code:language-scala-->
object FormelBauer {
    val fun = List (" mul10 (", " add1 (", " neg (", " abs (")
    val ops = List (" * ", " + ", " - ", " / ")
    def c(maxLen: Int, m: Int) : String = {
        def f()= new StringBuffer (fun (r.nextInt (fun.length)))
        def w()= new StringBuffer ("" + (r.nextInt (180) - 90))
        def v()= new StringBuffer ("" + ('x' + r.nextInt (3)).toChar)
        def o()= new StringBuffer (ops (r.nextInt (ops.length)))
        def g(t: Int, b: Int, d: List [Char]) : StringBuffer ={
            var a = d.filterNot (x => if (b > 0) x == '.' else x == ')')
            if (b > m) a = a.filterNot (_ == 'k')
            if (b > m) a = a.filterNot (_ == 'f')
            if (t > maxLen) a = a.filterNot (_ == '+')
            val elem = r.nextInt (a.length)
            val start = a(elem)
            start match {
                case '.' => new StringBuffer ("")
                case 'f' => f.append(g (t + 1, b + 1, List ('(', '8', 'x')))
                case '(' => new StringBuffer ("(").append   (g (t + 1, b + 1, List ('(', '8', 'x')))
                case '8' => w.append(g (t + 1, b, List ('.', ')', '+')))
                case 'x' => v.append(g (t + 1, b, List ('.', ')', '+')))
                case ')' => new StringBuffer (") ").append  (g (t + 1, b -1, List ('.', ')', '+')))
                case '+' => o.append(g (t + 1, b, List ('f', '(', '8', 'x')))
        }}
        (g (0,0,List('f','(','8','x'))).toString
    }
import util._
  var r : Random = _    
    def main (as: Array [String]) : Unit = {
      val s=as(0).toInt
        r=new Random(s) 
        "xyz".map(c=>println("val "+c+"="+(c+r.nextInt(s))))
        println("""def mul10(i:Int)=10*i
def add1(i:Int)=i+1
def neg(i:Int)= -i
def abs(i:Int)=if(i<0)-i else i
"""+c(45,5))}
}

如您所见,它不是打高尔夫球的。因为,这并不能使我接近其他解决方案,但是问题是,更多的变化会花费更多。例如,3个变量,4个功能可以轻松地减少为两个。

生成一些样本:

for i in {1..7} ; do scala FormelBauer $i; echo; done

val x=120
val y=121
val z=122
def mul10(i:Int)=10*i
def add1(i:Int)=i+1
def neg(i:Int)= -i
def abs(i:Int)=if(i<0)-i else i
(y)  / 79

val x=121
val y=121
val z=123
def mul10(i:Int)=10*i
def add1(i:Int)=i+1
def neg(i:Int)= -i
def abs(i:Int)=if(i<0)-i else i
 add1 ((((78 +  neg (z * z) )  / x) ) )  + -23 - ((-83)  * y) 

val x=122
val y=123
val z=122
def mul10(i:Int)=10*i
def add1(i:Int)=i+1
def neg(i:Int)= -i
def abs(i:Int)=if(i<0)-i else i
x / -71 - (y) 

val x=122
val y=124
val z=125
def mul10(i:Int)=10*i
def add1(i:Int)=i+1
def neg(i:Int)= -i
def abs(i:Int)=if(i<0)-i else i
x

val x=122
val y=123
val z=126
def mul10(i:Int)=10*i
def add1(i:Int)=i+1
def neg(i:Int)= -i
def abs(i:Int)=if(i<0)-i else i
-24 + z

val x=121
val y=121
val z=124
def mul10(i:Int)=10*i
def add1(i:Int)=i+1
def neg(i:Int)= -i
def abs(i:Int)=if(i<0)-i else i
 abs (z) 

val x=123
val y=126
val z=126
def mul10(i:Int)=10*i
def add1(i:Int)=i+1
def neg(i:Int)= -i
def abs(i:Int)=if(i<0)-i else i
 add1 (-62 - 30 * (-68)  /  neg (x - 69 + 33 / 45 + x * x)  -  abs (-18 * (y + x)  /  neg (x)  - y)  *  abs ((61) ) )  + (y) 

测试最长的一个:

add1 (-62 - 30 * (-68)  /  neg (x - 69 + 33 / 45 + x * x)  -  abs (-18 * (y + x)  /  neg (x)  - y)  *  abs ((61) ) )  + (y) 

res6:Int = -5425


5

Perl-> shell:66个字符

@ p = split(':',$ ENV {PATH});
@ c =`ls @p [@ARGV [0]]`;
打印@c [rand($#c)];

可能有点偏离主题,但也许如此。

s153254 @ helios:/ home / s153254 / lab $ perl code.p 1
远程登录
s153254 @ helios:/ home / s153254 / lab $ perl code.p 2
inloglogind
s153254 @ helios:/ home / s153254 / lab $ perl code.p 2
df
s153254 @ helios:/ home / s153254 / lab $ perl code.p 3
斯文夫



4

红宝石→Brainfuck(110 107个字符)

s="";m=%w:< > . , + -:;rand(99).downto(r=0){s<<(rand(40)==0? (r+=1)&&'[%s':'%s')%m.shuffle[0]};p(s<<']'*r)

用法

$ ruby bf.rb

产生可执行的Brainfuck程序。

有点像ESultanik的无耻剥夺,所以我会相信他的想法。

  • 更改为零?至== 0

3

Javascript-> Brainf * ck:119个字符

s=prompt();a=["+","-",">","<",".",",","[-]"];i=0;b="";while(i++<s*s){b+=a[Math.floor(((Math.random()*s)%1)*7)]}alert(b)

样本I / O:

10
.--.+,-><->.<+.[-].->.>[-][-]<+,[-]>><-[-]>,,>>[-].-+<[-]+>,<[-][-]<<[-]<[-]+,+[-][-][-].-[-],[-]>.<<[-]-..<-.->.++,>+-[-],.[-]..+,<-[-].+-[-]
11
,..[-]--,[-].,[-]>[-]->..[-]<,<..>[-]<>++-.[-].,,<[-].<+<[-]>-->[-]+-[-]+>-[-][-]>-,[-]->>-,-..++<+,,-,.,[-]->[-]<,+[-][-]+.,-,>+->.[-],.>..,++,.[-],+[-]-,.,--.--,

代码肯定可以短一些,但是恕我直言,有些事情会使它变得不那么有趣。但是,如果其他人想出了一个较短的程序,我会减少更多。


2

Python-> Python,148个字符

比其他Python条目更长的时间(以(主观的)更有趣的代价)。

import sys as s,random as r
w,o=s.stdout.write,__builtins__
r.seed(s.argv[1])
w('print\\')
for i in'\n....':n=r.choice(dir(o));o=getattr(o,n);w(i+n)

这将打印内置对象的深层嵌套属性。

$ python randprog.py 1
print\
round.__setattr__.__delattr__.__init__.__class__

2

PowerShell,生成PowerShell – 43

本着Keith解决方案的精神:

-join(0.."$input"|%{'-','+'|random;random})

生成加法和减法的随机表达式:

PS> -join(0..(random 9)|%{'-','+'|random;random 9})
+2-0-0+3-7
PS> -join(0..(random 9)|%{'-','+'|random;random 9})
-7+1+7+1-5+2+8
PS> -join(0..(random 9)|%{'-','+'|random;random 9})
-1+7+7-0-6-0-2
PS> -join(0..(random 9)|%{'-','+'|random;random 9})
+2-6-5+3-2+7
PS> -join(0..(random 9)|%{'-','+'|random;random 9})
-6

一种Powershell方式gcm|random -c @args|% na*:)
疯狂的

2

Python-> Fractran(117)

import random as r,sys
r.seed(int(sys.argv[1]))
z=r.randint
print','.join(`z(1,99)`+'/'+`z(1,99)`for q in[0]*z(1,99))

2

游戏制作者语言-> Arduino或Ti84-Basic,6个3个字符

a=argument0;if a mod 2{return("void setup(){Serial.begin(9600);}void loop(){Serial.print"+string(a*random(9))+";delay("+string(floor(random(999)))+")}"}else{return(":Lbl A:Horizontal "+string(a*random(9))+":Goto A")}

说明:

a=argument0 将输入放入变量 a

if a mod 2 基本上,程序一半的机会是Arduino,一半Ti-Basic 84

Arduino程序以随机​​的间隔输出随机的东西,随机地跳过随机的东西。

Ti-Basic程序疯狂地绘制水平线。

另外,还有一个好处-生成的程序已经打好了!不确定是否会有所帮助...


1

Perl-> HQ9 +(42个字符)

$a="HQ9+";for(1..<>%4){chop$a}print chop$a

输入示例

4264532623562346

输出量

Q

1

JavaScript-> Javascript(44个字符)

alert('alert("'+Math.random()*prompt()+'")')

它具有43个字符,可以执行生成的程序,而不显示其源代码:

eval('alert("'+Math.random()*prompt()+'")')

例子:

种子:5
执行了3次:

alert("2.335241624386981")
alert("0.4577956395223737")
alert("0.8359265828039497")

种子在哪里?
门把手
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.