Generiere ein zufälliges Programm in deiner Lieblingssprache [geschlossen]


21

Wir alle haben davon gehört, Compiler mit zufällig generierten Eingaben zu testen. Ihre Aufgabe ist es, ein Programm zu schreiben, um ein gültiges Programm (einschließlich kein undefiniertes Verhalten) in Ihrer Lieblingssprache zu generieren. Die erzeugende Programmsprache muss nicht mit der erzeugten Programmsprache übereinstimmen.

Ihr Programm erhält eine Ganzzahl als Argument, das Sie als Ausgangswert für Ihren Zufallsgenerator verwenden können. Die generierten Programme sollten strukturell unterschiedlich sein (bei unterschiedlichen Seeds), nicht nur unterschiedliche Variablennamen oder Konstanten.

Beispiele:

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

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

Bitte fügen Sie Ihren Antworten einige Ergebnisse bei.

Die kürzeste Lösung gewinnt. Ich werde einen kleinen Bonus geben, basierend auf der Anzahl der Stimmen, also stimmen Sie bitte über die kreativsten Lösungen ab.


2
Perfekte Aufgabe für die Entwicklung genetischer Algorithmen mit offener Evolution. Ich habe mich immer gefragt, wie es gemacht werden könnte.
Mellamokb

1
Ich denke, das Fehlen einer festen Spezifikation macht dies zu einer schlechten Frage. "Strukturell anders" kann interpretiert werden, und bei einigen Interpretationen ist dies ein äußerst einfaches Problem.
Peter Taylor

1
Alles, was man wirklich tun muss, ist Golf, ein Programm, das aus einer gegebenen BNF-Grammatik einen zufälligen Satz erzeugen kann (dies ist trivial). Dann schließen Sie einfach die Grammatik für jede andere Programmiersprache und puh : ein gültiges Programm in dieser Sprache. Dies funktioniert für jede kontextfreie Sprache (was Perl leider ausschließt).
ESultanik

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

1
Neil: Nur zur Erinnerung: Wahrscheinlich kennt jeder hier xkcd, besonders der verknüpfte. Sie kennen wahrscheinlich auch den Dilbert auf Zufallszahlen. Und es hat hier keine Relevanz, da es nach einem Programm mit zufälliger Struktur fragt, nicht nur nach einer Zufallszahl.
Joey

Antworten:


18

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

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 Zeichen : entfernt math.ceil(nicht wirklich notwendig).
  • 287 → 285 Zeichen : Auf eine leere Zeichenfolge umgeschaltet, um den Verzweigungsoperator zu kennzeichnen.
  • 285 → 255 Zeichen : Die if-Anweisung in der while-Schleife wurde komprimiert.
  • 255 → 233 Zeichen : Die Vorschläge von JBernardo aus den Kommentaren wurden implementiert .
  • 233 → 223 Zeichen : Der Vorschlag von tjko aus den Kommentaren wurde implementiert .
  • 223 → 185 Zeichen : Einige Vorschläge zur Reduzierung von Leerzeichen aus den Kommentaren wurden implementiert.

Beispiele

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

Eigentlich , herauszufinden , was die resultierenden BF Programme haben für den Leser als Übung überlassen.


Sie können auch verwendenif o: s+=0(NL)else: s+='['+b()+']'
Alexandru

@ Alexandru: Danke! Das habe ich vermisst. Ihr Code schien nicht genau zu funktionieren, aber es hat mir geholfen, ihn zu verkürzen.
ESultanik

3
Bedeutet das irgendwie, dass Brainfuck Ihre Lieblingssprache ist?
Zneak

1
Nicht, dass dies ein Problem ist, aber der ausgegebene Code wird wahrscheinlich eine Endlosschleife verursachen.
Peter Olson

6
@Peter, stimmt, aber das Vermeiden dieser Methode der Zufallsgenerierung ist wahrscheinlich gleichbedeutend mit dem Lösen des Halteproblems!
ESultanik

17

Python -> Piet, 385 345 Zeichen

Es ist möglich, ein beliebiges Piet-Programm damit zu generieren. Ich hätte einfach bei zufälligen Pixeln stehen bleiben können, aber ich wollte "interessante" Programme machen. Die Funktion mmalt ein Pixel in eine Farbe und springt rekursiv in jedes der Nachbarpixel. Es gibt bessere Möglichkeiten, um zufällige Blobs zu zeichnen, aber dies ist so abgestimmt, dass es in einer angemessenen Anzahl von Schritten endet, also ist es gut genug für Golf. Die Funktion R(w,h,n)zeichnet n zufällige Blobs auf ein ( B x H ) weißes Bild und druckt das Ergebnis im PPM-Format.

Ich bin besonders stolz darauf, wie ich die Farben generiere - für eine zufällige Auswahl von 0 <= c < 20,

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

ist der Dezimalcode für eine gültige Farbe in der Piet-Palette über einen einspurigen Gray-Code . Das heißt, jede Farbe wird durch 3 benachbarte Bits dargestellt, und jeder Schnitt '0003...0'[c:c+3]repräsentiert eine andere Farbe. Da dies nicht die vollständige Liste von 27 Wörtern in 3 Buchstaben ist, habe ich wirklich Glück gehabt, den Gray-Code zu finden.

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

Beispielausgabe, die vom Befehl generiert wird R(30,40,500)

zufälliges Piet-Programm

Ohne den Import kann ich es auch als richtigen (Semikolon-freien) 1-Liner schreiben:

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)

aber es ist lächerlich langsam (und fast 100 Zeichen länger) ... obwohl ich nicht ganz sicher bin warum (und nicht schrecklich geneigt, es herauszufinden).


9

Python -> Python, 135 Zeichen

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)

Erzeugt kleine zufällige Ausdrucksauswertungen wie folgt:

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

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

6

PHP, 352 Zeichen

Generiert PHP-Code in PHP.

Ich entschied, dass mir die Länge nicht so wichtig war, sondern ich wollte eine interessante und vielfältige Reihe von Lösungen. Das ist meine Antwort darauf.

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

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

Beispiel

> 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
Könnten Sie bitte ein Ausgabebeispiel beifügen?
Alexandru

5

scala: 1543 (scala => scala)

Ich habe Variablen (x, y, z), Funktionen (mul, add, neg, abs), Werte und ausgeglichene Klammern.

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

Wie Sie sehen, ist es nicht sehr golfen. Weil es mich nicht in die Nähe der anderen Lösungen bringt, aber ein Problem ist, dass mehr Variation mehr kostet. 3 Variablen, 4 Funktionen könnten zum Beispiel leicht auf zwei reduziert werden.

Einige Beispiele generieren:

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) 

Den längsten testen:

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 Zeichen

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

Möglicherweise ein wenig falsches Thema, aber vielleicht auch.

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

Ruby → Brainfuck ( 110 107 Zeichen)

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

Verwendung

$ ruby bf.rb

Erzeugt ein ausführbares Brainfuck-Programm.

Irgendwie eine schamlose Abzocke von ESultanik, also werde ich ihm die Idee zuschreiben.

  • .Zero geändert? bis == 0

3

Javascript -> Brainf * ck: 119 Zeichen

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

Beispiel-E / A:

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

Der Code könnte definitiv kürzer sein, aber einige Dinge würden ihn meiner Meinung nach weniger interessant machen. Aber wenn jemand anderes ein kürzeres Programm entwickelt, werde ich mehr einsparen.


2

Python -> Python, 148 Zeichen

Länger als die anderen Python-Einträge auf Kosten von (subjektiv) etwas interessanter.

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)

Dies gibt ein tief verschachteltes Attribut eines eingebauten Objekts aus.

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

2

PowerShell, PowerShell generieren - 43

Im Geiste von Keiths Lösung:

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

generiert zufällige Ausdrücke von Additionen und Subtraktionen:

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

Ein Powershell Weg 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

Game Maker Language -> Arduino oder Ti84-Basic, 6 3 Zeichen

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

Erläuterung:

a=argument0 Setzt die Eingabe in eine Variable a

if a mod 2 Grundsätzlich ist die Hälfte der Wahrscheinlichkeit, dass das Programm Arduino ist, die Hälfte Ti-Basic 84

Das Arduino-Programm gibt in zufälligen Intervallen zufällige Daten aus und überspringt zufällige Daten.

Das Ti-Basic-Programm zeichnet horizontale Linien wie verrückt.

Außerdem gibt es einen Bonus - die generierten Programme sind bereits golfen! Ich bin mir nicht sicher, ob das hilfreich wäre ...


1

Perl -> HQ9 + (42 Zeichen)

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

Beispiel Eingabe

4264532623562346

Ausgabe

Q

1

JavaScript -> Javascript (44 Zeichen)

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

Und mit 43 Zeichen kann es das generierte Programm ausführen, anstatt seine Quelle anzuzeigen:

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

Beispiele:

Samen: 5
3-mal ausgeführt:

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

Wo ist der Same?
Türklinke
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.