Genere un programa aleatorio en su idioma favorito [cerrado]


21

Todos escuchamos sobre probar compiladores utilizando entradas generadas aleatoriamente. Su tarea es escribir un programa para generar un programa válido (incluido ningún comportamiento indefinido) en su idioma favorito. El lenguaje del programa generador no tiene que ser el mismo que el lenguaje del programa generado.

Su programa recibirá un número entero como argumento que puede usar como semilla para su generador de números aleatorios. Los programas generados deben ser estructuralmente diferentes (dados diferentes semillas) no solo diferentes nombres de variables o constantes.

Ejemplos:

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

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

Incluya un par de resultados en sus respuestas.

La solución más corta gana. Daré un pequeño bono basado en el número de votos, así que vote las soluciones más creativas.


2
Tarea perfecta para desarrollar algoritmos genéticos con evolución abierta. Siempre me he preguntado cómo se podría hacer.
mellamokb

1
Creo que la falta de una especificación fija hace que esta sea una mala pregunta. "Estructuralmente diferente" está abierto a interpretación, y en algunas interpretaciones este es un problema extremadamente simple.
Peter Taylor

1
Todo lo que uno realmente necesita hacer es desarrollar un programa que pueda generar una oración aleatoria a partir de una gramática BNF dada (esto es trivial). Luego, simplemente conecte la gramática para cualquier otro lenguaje de programación y poof : un programa válido en ese lenguaje. Esto funcionará para cualquier lenguaje sin contexto (que desafortunadamente descarta a Perl).
ESultanik

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

1
Neil: Solo para tener en cuenta: Probablemente todos aquí conocen xkcd, especialmente el vinculado. Probablemente también conocen el Dilbert en números aleatorios. Y no tiene relevancia aquí, ya que solicita un programa con estructura aleatoria, no solo un número aleatorio.
Joey

Respuestas:


18

Python → Brainf * ck (185 223 233 255 285 287 303 caracteres)

Código

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 caracteres : eliminados math.ceil(no es realmente necesario).
  • 287 → 285 Caracteres : se cambia a una cadena vacía para indicar el operador de rama.
  • 285 → 255 caracteres : condensó la instrucción if en el ciclo while.
  • 255 → 233 Caracteres : implementadas las sugerencias de JBernardo de los comentarios.
  • 233 → 223 Caracteres : se implementó la sugerencia de tjko de los comentarios.
  • 223 → 185 caracteres : se implementaron algunas sugerencias de reducción de espacios en blanco de los comentarios.

Ejemplos

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

En realidad averiguar lo que los programas de BF resultantes no se deja como ejercicio para el lector.


también puedes usarif o: s+=0(NL)else: s+='['+b()+']'
Alexandru

@Alexandru: ¡Gracias! Me lo perdí. Su código no parecía funcionar exactamente, pero me ayudó a acortarlo.
ESultanik

3
¿Esto de alguna manera significa que Brainfuck es tu idioma favorito?
zneak

1
No es que esto sea un problema, pero el código generado probablemente causará un bucle infinito.
Peter Olson

66
@Peter, es cierto, ¡pero evitar que usar este método de generación aleatoria probablemente sea equivalente a resolver el problema de detención!
ESultanik

17

Python -> Piet, 385 345 char

Es posible generar cualquier programa Piet con esto. Podría haberme detenido en píxeles aleatorios, pero quería hacer programas "interesantes". La función mpinta un píxel por color, y recursivamente pasa a cada uno de esos píxeles vecinos. Hay mejores formas de dibujar blobs aleatorios, pero esto está ajustado para terminar en un número razonable de pasos, por lo que es lo suficientemente bueno para el golf. La función R(w,h,n)dibuja n blobs aleatorios en una imagen blanca ( w x h ) e imprime el resultado en formato PPM.

Estoy especialmente orgulloso de cómo genero los colores, para una elección aleatoria de 0 <= c < 20,

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

es el código decimal para un color válido en la paleta Piet a través de un código gris de una sola pista . Es decir, cada color está representado por 3 bits adyacentes, y cada corte '0003...0'[c:c+3]representa un color diferente. Como esta no es la lista completa de 27 palabras en 3 letras, realmente tuve la suerte de encontrar el código Gray.

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])

Salida de muestra, generada por el comando R(30,40,500)

programa aleatorio de Piet

Sin la importación, también puedo escribirlo como un 1-liner adecuado (sin punto y coma):

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)

pero es ridículamente lento (y casi 100 caracteres más largos) ... aunque no estoy completamente seguro de por qué (y no estoy terriblemente inclinado a averiguarlo).


9

Python -> Python, 135 caracteres

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)

Genera pequeñas evaluaciones de expresiones aleatorias, como esta:

> ./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 caracteres

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

6

PHP, 352 caracteres

Genera código PHP en PHP.

Decidí que no me importaba mucho la longitud, sino que quería un conjunto de soluciones interesante y diverso. Esta es mi respuesta a eso.

Código

<?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
";

Sin golf

<?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
";

Ejemplo

> 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
¿Podría por favor incluir un ejemplo de salida?
Alexandru

5

scala: 1543 (scala => scala)

Tengo variables (x, y, z), funciones (mul, add, neg, abs), valores y paréntesis balanceados.

<!--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))}
}

Como ves, no es muy golf. Porque no me acercará a las otras soluciones, pero un problema es que más variación cuesta más. 3 variables, 4 funciones podrían reducirse fácilmente a dos, por ejemplo.

Generando algunas muestras:

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) 

Probar el más largo:

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 -> caparazón: 66 caracteres

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

Posiblemente un poco fuera de tema, pero tal vez sea así.

s153254 @ helios: / home / s153254 / lab $ perl code.p 1
telnet
s153254 @ helios: / home / s153254 / lab $ perl code.p 2
in.rlogind
s153254 @ helios: / home / s153254 / lab $ perl code.p 2
df
s153254 @ helios: / home / s153254 / lab $ perl code.p 3
svenv



4

Rubí → Brainfuck ( 110 107 caracteres)

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

Uso

$ ruby bf.rb

Produce un programa ejecutable brainfuck.

Una especie de estafa desvergonzada de ESultanik, así que le atribuiré la idea.

  • ¿Cambió .zero? a == 0

3

Javascript -> Brainf * ck: 119 caracteres

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

Muestra de E / S:

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

El código definitivamente podría ser más corto, pero algunas cosas, en mi humilde opinión, lo harían menos interesante. Pero si a alguien más se le ocurre un programa más corto, reduciré más.


2

Python -> Python, 148 caracteres

Más largo que las otras entradas de Python a costa de ser (subjetivamente) un poco más interesante.

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)

Esto imprime un atributo profundamente anidado de un objeto incorporado.

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

2

PowerShell, generando PowerShell - 43

En el espíritu de la solución de Keith:

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

genera expresiones aleatorias de sumas y restas:

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

Una manera Powershell gcm|random -c @args|% na*:)
mazzy

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

Idioma de Game Maker -> Arduino o Ti84-Basic, 6 3 caracteres

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")}

Explicación:

a=argument0 Pone la entrada en variable a

if a mod 2 Básicamente, la mitad de posibilidades de que el programa sea Arduino, la mitad de Ti-Basic 84

El programa Arduino genera cosas aleatorias a intervalos aleatorios, omitiendo aleatoriamente cosas aleatorias.

El programa Ti-Basic dibuja líneas horizontales como locos.

Además, hay una bonificación: ¡los programas generados ya están jugando al golf! No estoy seguro si eso sería útil ...


1

Perl -> HQ9 + (42 caracteres)

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

Entrada de ejemplo

4264532623562346

Salida

Q

1

JavaScript -> Javascript (44 caracteres)

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

Y con 43 caracteres, puede ejecutar el programa generado en lugar de mostrar su fuente:

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

Ejemplos:

Semilla: 5
Ejecutada 3 veces:

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

¿Dónde está la semilla?
Pomo de la puerta
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.