Générez un programme aléatoire dans votre langue préférée [fermé]

21

Nous avons tous entendu parler de tests de compilateurs utilisant des entrées générées aléatoirement. Votre tâche consiste à écrire un programme pour générer un programme valide (y compris aucun comportement indéfini) dans votre langue préférée. Le langage de programme générateur ne doit pas nécessairement être le même que le langage de programme généré.

Votre programme recevra un entier comme argument que vous pouvez utiliser comme graine pour votre générateur de nombres aléatoires. Les programmes générés doivent être structurellement différents (avec des graines différentes) et pas seulement des noms de variables ou des constantes différents.

Exemples:

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

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

Veuillez inclure quelques sorties dans vos réponses.

La solution la plus courte l'emporte. Je donnerai un petit bonus basé sur le nombre de votes, alors votez pour les solutions les plus créatives.

Alexandru
la source
2
Tâche parfaite pour développer des algorithmes génétiques à évolution ouverte. Je me suis toujours demandé comment cela pouvait se faire.
mellamokb
1
Je pense que l'absence de spécification fixe en fait une mauvaise question. "Structurellement différent" est sujet à interprétation, et dans certaines interprétations, c'est un problème extrêmement simple.
Peter Taylor
1
Tout ce qu'il faut vraiment faire, c'est jouer au golf un programme qui peut générer une phrase aléatoire à partir d'une grammaire BNF donnée (c'est trivial). Ensuite, branchez simplement la grammaire pour tout autre langage de programmation et pouf : un programme valide dans ce langage. Cela fonctionnera pour n'importe quelle langue sans contexte (ce qui exclut malheureusement Perl).
ESultanik
2
main(seed) { return 4; // Chosen by dice roll - Guaranteed to be random } Référence
Neil
1
Neil: Juste pour noter: Probablement tout le monde ici connaît xkcd, en particulier celui lié. Ils connaissent probablement aussi celui de Dilbert sur des nombres aléatoires. Et cela n'a aucune pertinence ici car il demande un programme avec une structure aléatoire, pas seulement un nombre aléatoire.
Joey

Réponses:

18

Python → Brainf * ck (185 223 233 255 285 287 303 caractères)

Code

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 Caractères : supprimés math.ceil(ce n'est pas vraiment nécessaire).
  • 287 → 285 Caractères : basculé vers une chaîne vide pour désigner l'opérateur de branche.
  • 285 → 255 caractères : condensé l'instruction if dans la boucle while.
  • 255 → 233 Caractères : implémentation des suggestions de JBernardo à partir des commentaires.
  • 233 → 223 Caractères : Mise en œuvre de la suggestion de tjko à partir des commentaires.
  • 223 → 185 caractères : implémentation de quelques suggestions de réduction d'espaces dans les commentaires.

Exemples

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

En fait comprendre ce que les programmes de BF résultants n'est laissé en exercice au lecteur.

ESultanik
la source
vous pouvez également utiliserif o: s+=0(NL)else: s+='['+b()+']'
Alexandru
@Alexandru: Merci! J'ai manqué ça. Votre code ne semble pas fonctionner exactement, mais il m'a aidé à le raccourcir.
ESultanik
3
Cela signifie-t-il que Brainfuck est votre langue préférée?
zneak
1
Ce n'est pas un problème, mais le code généré entraînera probablement une boucle infinie.
Peter Olson
6
@Peter, c'est vrai, mais éviter que l'utilisation de cette méthode de génération aléatoire équivaut probablement à résoudre le problème de l'arrêt!
ESultanik
17

Python -> Piet, 385 345 car

Il est possible de générer n'importe quel programme Piet avec cela. J'aurais pu m'arrêter à des pixels aléatoires, mais je voulais créer des programmes "intéressants". La fonction mpeint un pixel une couleur et pénètre récursivement dans chacun de ces pixels voisins. Il existe de meilleures façons de dessiner des blobs aléatoires, mais cela est réglé pour se terminer en un nombre raisonnable d'étapes, donc c'est assez bon pour le golf. La fonction des R(w,h,n)jeux n blobs aléatoires sur une ( w x h ) image blanche, et affiche le résultat en format PPM.

Je suis particulièrement fier de la façon dont je génère les couleurs - pour un choix aléatoire de 0 <= c < 20,

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

est le code décimal d'une couleur valide dans la palette Piet au moyen d'un code Gray à piste unique . Autrement dit, chaque couleur est représentée par 3 bits adjacents, et chaque tranche '0003...0'[c:c+3]représente une couleur différente. Comme ce n'est pas la liste complète de 27 mots sur 3 lettres, j'ai vraiment eu de la chance de trouver le code 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])

Exemple de sortie, généré par la commande R(30,40,500)

programme Piet aléatoire

Sans l'importation, je peux également l'écrire en tant que 1 ligne (sans point-virgule):

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)

mais c'est ridiculement lent (et près de 100 caractères de plus) ... même si je ne sais pas vraiment pourquoi (et pas terriblement enclin à le découvrir).

boothby
la source
9

Python -> Python, 135 caractères

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)

Génère de petites évaluations d'expression aléatoire, comme ceci:

> ./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
Keith Randall
la source
8

Python -> HQ9 +: 108 caractères

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

PHP, 352 caractères

Génère du code PHP en PHP.

J'ai décidé que je ne me souciais pas autant de la longueur, mais je voulais plutôt un ensemble de solutions intéressant et diversifié. Voici ma réponse à cela.

Code

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

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

Exemple

> 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
la source
2
Pourriez-vous s'il vous plaît inclure un exemple de sortie?
Alexandru
5

scala: 1543 (scala => scala)

J'ai des variables (x, y, z), des fonctions (mul, add, neg, abs), des valeurs et des parenthèses équilibrées.

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

Comme vous le voyez, ce n'est pas très golfé. Parce que cela ne me rapprochera pas des autres solutions, mais un problème est que plus de variation coûte plus cher. Par exemple, 3 variables, 4 fonctions peuvent être facilement réduites à deux.

Génération de quelques échantillons:

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) 

Test du plus long:

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

res6: Int = -5425

Utilisateur inconnu
la source
5

Perl -> shell: 66 caractères

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

Peut-être un peu hors sujet, mais peut-être que oui.

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


Anthony
la source
4

Ruby → Brainfuck ( 110 107 caractères)

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

Usage

$ ruby bf.rb

Produit un programme exécutable de brainfuck.

Une sorte d'escroquerie éhontée de ESultanik, donc je lui attribuerai l'idée.

  • Changement de .zero? à == 0
incluye
la source
3

Javascript -> Brainf * ck: 119 caractères

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

Exemple d'E / S:

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

Le code pourrait certainement être plus court, mais certaines choses, à mon humble avis, le rendraient moins intéressant. Mais si quelqu'un d'autre propose un programme plus court, je réduirai davantage.

Peter Olson
la source
2

Python -> Python, 148 caractères

Plus long que les autres entrées Python au détriment d'être (subjectivement) un peu plus intéressant.

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)

Cela imprime un attribut profondément imbriqué d'un objet intégré.

$ python randprog.py 1
print\
round.__setattr__.__delattr__.__init__.__class__
Fraxtil
la source
2

PowerShell, génération de PowerShell - 43

Dans l'esprit de la solution de Keith:

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

génère des expressions aléatoires d'additions et de soustractions:

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
Joey
la source
Une façon 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))
boîte en carton
la source
2

Langue Game Maker -> Arduino ou Ti84-Basic, 6 3 caractères

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

Explication:

a=argument0 Met l'entrée en variable a

if a mod 2 Fondamentalement, la moitié des chances que le programme soit Arduino, la moitié Ti-Basic 84

Le programme Arduino génère des éléments aléatoires à des intervalles aléatoires, en sautant au hasard des choses aléatoires.

Le programme Ti-Basic dessine des lignes horizontales comme un fou.

De plus, il y a un bonus - les programmes générés sont déjà joués! Je ne sais pas si cela serait utile ...

Timtech
la source
1

Perl -> HQ9 + (42 caractères)

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

Exemple d'entrée

4264532623562346

Production

Q
PhiNotPi
la source
1

JavaScript -> Javascript (44 caractères)

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

Et avec 43 caractères, il peut exécuter le programme généré au lieu d'afficher sa source:

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

Exemples:

Graine: 5
Exécuté 3 fois:

alert("2.335241624386981")
alert("0.4577956395223737")
alert("0.8359265828039497")
user1886419
la source
Où est la graine?
Poignée de porte