Создать случайную программу на вашем любимом языке [закрыто]

21

Мы все слышали о тестировании компиляторов с использованием случайно сгенерированных входных данных. Ваша задача - написать программу для создания допустимой программы (в том числе без неопределенного поведения) на вашем любимом языке. Язык генерирующей программы не обязательно должен совпадать с языком генерируемой программы.

Ваша программа получит целое число в качестве аргумента, который вы можете использовать в качестве начального числа для генератора случайных чисел. Сгенерированные программы должны быть структурно различными (учитывая разные начальные значения), а не просто разными именами или константами.

Примеры:

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

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

Пожалуйста, включите несколько выходов в ваши ответы.

Самое короткое решение побеждает. Я дам небольшой бонус в зависимости от количества голосов, поэтому, пожалуйста, голосуйте за самые креативные решения.

Александр
источник
2
Идеальная задача для разработки генетических алгоритмов с открытой эволюцией. Мне всегда было интересно, как это можно сделать.
mellamokb
1
Я думаю, что отсутствие фиксированной спецификации делает это плохим вопросом. «Структурно иное» открыто для интерпретации, и в некоторых интерпретациях это чрезвычайно простая проблема.
Питер Тейлор
1
Все, что действительно нужно сделать, - это игра в гольф, которая может генерировать случайное предложение из заданной грамматики БНФ (это тривиально). Затем просто подключите грамматику для любого другого языка программирования и poof : допустимая программа на этом языке. Это будет работать для любого языка без контекста (который, к сожалению, исключает Perl).
ESultanik
2
main(seed) { return 4; // Chosen by dice roll - Guaranteed to be random } Справка
Нил
1
Нил: Просто чтобы заметить: Вероятно, все здесь знают xkcd, особенно связанный. Они, вероятно, также знают Дилберта по случайным числам. И здесь это не имеет никакого отношения, поскольку в нем просят программу со случайной структурой, а не просто случайное число.
Джои

Ответы:

18

Python → 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 символов : сжатый оператор if в цикле while.
  • 255 → 233 персонажа : Реализованы предложения Дж. Бернардо из комментариев.
  • 233 → 223 персонажа : Реализовано предложение tjko из комментариев.
  • 223 → 185 символов : Реализованы некоторые предложения по сокращению пробелов из комментариев.

Примеры

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

Фактическое выяснение того, что делают полученные BF-программы , оставлено читателю в качестве упражнения.

ESultanik
источник
Вы также можете использоватьif o: s+=0(NL)else: s+='['+b()+']'
Александру
@Alexandru: Спасибо! Я пропустил это. Ваш код, похоже, не работал точно, но он помог мне сократить его.
ESultanik
3
Значит ли это, что Brainfuck - твой любимый язык?
zneak
1
Не то чтобы это проблема, но выводимый код, скорее всего, вызовет бесконечный цикл.
Питер Олсон
6
@Peter, правда, но избегая того, что использование этого метода случайной генерации, скорее всего, эквивалентно решению проблемы остановки!
ESultanik
17

Питон -> Пит, 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]

является десятичным кодом для допустимого цвета в палитре Пита с помощью однотрекового кода Грея . То есть каждый цвет представлен 3 смежными битами, а каждый срез '0003...0'[c:c+3]представляет свой цвет. Поскольку это не полный список из 27 слов на 3 буквы, мне очень повезло с поиском кода Грея.

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)

случайная программа Пита

Без импорта я могу написать его как правильный (без точки с запятой) 1-строчный:

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

Питон -> Питон, 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))])
zhazam
источник
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
";

Ungolfed

<?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);
rintaun
источник
2
Не могли бы вы включить пример вывода?
Александру
5

scala: 1543 (scala => 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 -> оболочка: 66 символов

@ Р = Раскол ( ':', $ ENV {PATH});
@ c = `ls @p [@ARGV [0]]`;
print @c [rand ($ # c)];

Возможно, немного не по теме, но, возможно, так.

s153254 @ helios: / home / s153254 / lab $ perl code.p 1
телнет
s153254 @ helios: / home / s153254 / lab $ perl code.p 2
in.rlogind
s153254 @ helios: / home / s153254 / lab $ perl code.p 2
Д.Ф.
s153254 @ helios: / home / s153254 / lab $ perl code.p 3
svenv


Энтони
источник
4

Ruby → 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.

Что-то вроде бесстыдного грабежа Эсултаника, поэтому я воздаю ему должное за эту идею.

  • Поменял .zero? до == 0
incluye
источник
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)

Пример ввода / вывода:

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

Код определенно может быть короче, но некоторые вещи, IMHO, сделают его менее интересным. Но если кто-то придумает более короткую программу, я урежу больше.

Питер Олсон
источник
2

Питон -> Питон, 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__
Fraxtil
источник
2

PowerShell, генерирующий PowerShell - 43

В духе решения Кейта:

-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

Питон -> Фрактран (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

Game Maker Language -> 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 рисует горизонтальные линии как сумасшедшие.

Также есть бонус - созданные программы уже в гольфе! Не уверен, что это будет полезно ...

Timtech
источник
1

Perl -> HQ9 + (42 символа)

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

Пример ввода

4264532623562346

Выход

Q
PhiNotPi
источник
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")
user1886419
источник
Где семя?
Дверная ручка