Wygeneruj losowy program w swoim ulubionym języku [zamknięte]

21

Wszyscy słyszeliśmy o testowaniu kompilatorów przy użyciu losowo generowanych danych wejściowych. Twoim zadaniem jest napisanie programu do wygenerowania prawidłowego programu (w tym braku niezdefiniowanego zachowania) w ulubionym języku. Generujący język programu nie musi być taki sam jak generowany język programu.

Twój program otrzyma liczbę całkowitą jako argument, którego możesz użyć jako źródła dla generatora liczb losowych. Wygenerowane programy powinny być strukturalnie różne (biorąc pod uwagę różne nasiona), a nie tylko różne nazwy zmiennych lub stałe.

Przykłady:

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

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

Podaj kilka odpowiedzi w swoich odpowiedziach.

Najkrótsze rozwiązanie wygrywa. Dam niewielką premię na podstawie liczby głosów, więc proszę głosować na najbardziej kreatywne rozwiązania.

Alexandru
źródło
2
Idealne zadanie do opracowania algorytmów genetycznych z ewolucją otwartą. Zawsze zastanawiałem się, jak to zrobić.
mellamokb
1
Myślę, że brak ustalonej specyfikacji sprawia, że ​​jest to złe pytanie. „Strukturalnie inny” jest otwarty na interpretację, aw niektórych interpretacjach jest to niezwykle prosty problem.
Peter Taylor
1
Wszystko, co naprawdę trzeba zrobić, to golf, który może generować losowe zdanie z danej gramatyki BNF (jest to trywialne). Następnie po prostu podłącz gramatykę dla dowolnego innego języka programowania i poof : poprawny program w tym języku. Będzie to działać dla dowolnego języka bezkontekstowego (co niestety wyklucza Perla).
ESultanik,
2
main(seed) { return 4; // Chosen by dice roll - Guaranteed to be random } Odniesienie
Neil
1
Neil: Uwaga: prawdopodobnie wszyscy tutaj znają xkcd, szczególnie ten połączony. Prawdopodobnie znają też Dilberta na liczbach losowych. Nie ma to tutaj znaczenia, ponieważ prosi o program o losowej strukturze, a nie tylko o losową liczbę.
Joey,

Odpowiedzi:

18

Python → Brainf * ck (185 223 233 255 285 287 303 znaków)

Kod

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 Znaków : Usunięto math.ceil(nie jest to naprawdę konieczne).
  • 287 → 285 Znaków : Przełączony na pusty ciąg znaków, oznaczający operatora gałęzi.
  • 285 → 255 znaków : Skondensowana instrukcja if w pętli while.
  • 255 → 233 Znaki : Zaimplementowano sugestie JBernardo z komentarzy.
  • 233 → 223 Znaki : Zaimplementowano sugestię tjko z komentarzy.
  • 223 → 185 znaków : Wprowadzono sugestie dotyczące redukcji białych znaków w komentarzach.

Przykłady

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

Dowiedzieć się, co faktycznie powstałe programy BF nie pozostawiamy jako ćwiczenie dla czytelnika.

ESultanik
źródło
możesz również użyćif o: s+=0(NL)else: s+='['+b()+']'
Alexandru
@Alexandru: Dzięki! Tęsknie za tym. Twój kod nie działał dokładnie, ale pomógł mi go skrócić.
ESultanik
3
Czy to w jakiś sposób oznacza, że ​​Brainfuck jest twoim ulubionym językiem?
zneak
1
Nie jest to problem, ale kod wyjściowy prawdopodobnie spowoduje nieskończoną pętlę.
Peter Olson
6
@Peter, prawda, ale unikanie tej metody generowania losowego jest prawdopodobnie równoznaczne z rozwiązaniem problemu zatrzymania!
ESultanik
17

Python -> Piet, 385 345 znaków

Dzięki temu można wygenerować dowolny program Piet. Mogłem po prostu zatrzymać losowe piksele, ale chciałem tworzyć „ciekawe” programy. Funkcja mmaluje piksel kolorem i rekurencyjnie wkracza w każdy z sąsiadujących pikseli. Istnieją lepsze sposoby rysowania losowych obiektów blob, ale są one dostrojone tak, aby kończyły się w rozsądnej liczbie kroków, więc są wystarczająco dobre dla golfa. Funkcja R(w,h,n)rysuje n losowych plam na białym obrazie ( szer x wys ) i drukuje wynik w formacie PPM.

Jestem szczególnie dumny z tego, jak generuję kolory - dla przypadkowego wyboru 0 <= c < 20,

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

jest dziesiętnym kodem prawidłowego koloru w palecie Piet za pomocą jednościeżkowego kodu Graya . Oznacza to, że każdy kolor jest reprezentowany przez 3 sąsiednie bity, a każdy plasterek '0003...0'[c:c+3]reprezentuje inny kolor. Ponieważ nie jest to pełna lista 27 słów na 3 literach, naprawdę udało mi się znaleźć kod Graya.

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

Przykładowe dane wyjściowe wygenerowane przez polecenie R(30,40,500)

losowy program Piet

Bez importu mogę też napisać go jako odpowiedni (bez średnika) 1-liniowy:

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)

ale jest absurdalnie powolny (i prawie 100 znaków dłużej) ... chociaż nie jestem do końca pewien, dlaczego (i nie jestem strasznie skłonny się dowiedzieć).

boothby
źródło
9

Python -> Python, 135 znaków

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)

Generuje małe oceny losowych wyrażeń, takie jak to:

> ./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
źródło
8

Python -> HQ9 +: 108 znaków

import random
def g(): return ''.join([random.choice(['H','Q','9','+']) for x in range(random.randint(1,9))])
zhazam
źródło
6

PHP, 352 znaków

Generuje kod PHP w PHP.

Uznałem, że nie dbam tak bardzo o długość, ale zamiast tego chciałem interesującego i różnorodnego zestawu rozwiązań. To jest moja odpowiedź na to.

Kod

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

Nie golfił

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

Przykład

> 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
źródło
2
Czy możesz podać przykładowy wynik?
Alexandru
5

scala: 1543 (scala => scala)

Mam zmienne (x, y, z), funkcje (mul, add, neg, abs), wartości i zrównoważony nawias.

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

Jak widać, nie jest bardzo golfowy. Ponieważ nie zbliży mnie to do innych rozwiązań, ale problemem jest to, że więcej wariantów kosztuje więcej. Na przykład 3 zmienne, 4 funkcje można łatwo zredukować do dwóch.

Generowanie niektórych próbek:

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) 

Testowanie najdłuższego:

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

res6: Int = -5425

nieznany użytkownik
źródło
5

Perl -> shell: 66 znaków

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

Być może trochę nie na temat, ale może tak.

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
źródło
4

Ruby → Brainfuck ( 110 107 znaków)

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

Stosowanie

$ ruby bf.rb

Tworzy wykonywalny program pieprzenia mózgu.

Coś w rodzaju bezwstydnego wydzierżawienia ESultanika, więc przypisuję mu pomysł.

  • Zmieniłeś .zero? do == 0
w tym
źródło
3

JavaScript -> Brainf * ck: 119 znaków

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

Przykładowe I / O:

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

Kod może być zdecydowanie krótszy, ale niektóre rzeczy, IMHO, sprawią, że będzie mniej interesujący. Ale jeśli ktoś wymyśli krótszy program, ograniczę więcej.

Peter Olson
źródło
2

Python -> Python, 148 znaków

Dłuższy niż inne wpisy w Pythonie kosztem bycia (subiektywnie) nieco bardziej interesującym.

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)

Spowoduje to wydrukowanie głęboko zagnieżdżonego atrybutu obiektu wbudowanego.

$ python randprog.py 1
print\
round.__setattr__.__delattr__.__init__.__class__
Fraxtil
źródło
2

PowerShell, generujący PowerShell - 43

W duchu rozwiązania Keitha:

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

generuje losowe wyrażenia dodawania i odejmowania:

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
źródło
Powershell way 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))
pudełko kartonowe
źródło
2

Game Maker Language -> Arduino lub Ti84-Basic, 6 3 znaków

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

Wyjaśnienie:

a=argument0 Umieszcza dane wejściowe w zmiennej a

if a mod 2 Zasadniczo połowa szansy na program to Arduino, połowa Ti-Basic 84

Program Arduino generuje losowe rzeczy w losowych odstępach czasu, losowo pomijając losowe rzeczy.

Program Ti-Basic rysuje poziome linie jak szalone.

Jest też bonus - wygenerowane programy są już zagrane w golfa! Nie jestem pewien, czy byłoby to pomocne ...

Timtech
źródło
1

Perl -> HQ9 + (42 znaków)

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

Przykładowe dane wejściowe

4264532623562346

Wydajność

Q
PhiNotPi
źródło
1

JavaScript -> JavaScript (44 znaki)

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

Za pomocą 43 znaków może uruchomić wygenerowany program zamiast wyświetlać jego źródło:

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

Przykłady:

Ziarno: 5
Wykonano 3 razy:

alert("2.335241624386981")
alert("0.4577956395223737")
alert("0.8359265828039497")
użytkownik1886419
źródło
Gdzie jest ziarno?
Klamka