Genera un programma casuale nella tua lingua preferita [chiuso]


21

Tutti abbiamo sentito parlare di compilatori di test che utilizzano input generati casualmente. Il tuo compito è quello di scrivere un programma per generare un programma valido (incluso nessun comportamento indefinito) nella tua lingua preferita. Il linguaggio del programma di generazione non deve essere uguale al linguaggio di programma generato.

Il tuo programma riceverà un numero intero come argomento che puoi usare come seed per il tuo generatore di numeri casuali. I programmi generati dovrebbero essere strutturalmente diversi (dati semi differenti) e non solo nomi di variabili o costanti diversi.

Esempi:

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

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

Includi un paio di risultati nelle tue risposte.

Vince la soluzione più breve. Ti darò un piccolo bonus in base al numero di voti, quindi per favore vota le soluzioni più creative.


2
Compito perfetto per lo sviluppo di algoritmi genetici con evoluzione a tempo indeterminato. Mi sono sempre chiesto come si potesse fare.
mellamokb,

1
Penso che la mancanza di una specifica fissa lo renda una brutta domanda. "Strutturalmente diverso" è aperto all'interpretazione e in alcune interpretazioni si tratta di un problema estremamente semplice.
Peter Taylor,

1
Tutto quello che bisogna fare è giocare a golf un programma in grado di generare una frase casuale da una determinata grammatica BNF (questo è banale). Quindi basta collegare la grammatica per qualsiasi altro linguaggio di programmazione e poof : un programma valido in quella lingua. Funzionerà con qualsiasi linguaggio senza contesto (che purtroppo esclude il Perl).
ESultanik,

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

1
Neil: Solo per notare: probabilmente tutti qui conoscono xkcd, specialmente quello collegato. Probabilmente conoscono anche quello di Dilbert su numeri casuali. E non ha rilevanza qui in quanto richiede un programma con struttura casuale, non solo un numero casuale.
Joey,

Risposte:


18

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

Codice

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 Personaggi : rimosso math.ceil(non è davvero necessario).
  • 287 → 285 Caratteri : passati a una stringa vuota per indicare l'operatore di filiale.
  • 285 → 255 caratteri : ha condensato l'istruzione if nel ciclo while.
  • 255 → 233 Personaggi : implementato i suggerimenti di JBernardo dai commenti.
  • 233 → 223 Personaggi : implementato il suggerimento di tjko dai commenti.
  • 223 → 185 Personaggi : implementati alcuni suggerimenti per la riduzione degli spazi bianchi dai commenti.

Esempi

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

In realtà per capire quali sono i programmi di BF risultanti non è lasciata come esercizio per il lettore.


puoi anche usareif o: s+=0(NL)else: s+='['+b()+']'
Alexandru,

@Alexandru: grazie! Ho perso questo. Il tuo codice non sembra funzionare esattamente, ma mi ha aiutato ad accorciarlo.
ESultanik,

3
Questo in qualche modo significa che Brainfuck è la tua lingua preferita?
zneak,

1
Non che questo sia un problema, ma il codice emesso probabilmente causerà un ciclo infinito.
Peter Olson,

6
@Peter, vero, ma evitare che l'utilizzo di questo metodo di generazione casuale sia probabilmente equivalente alla risoluzione del problema di Halting!
ESultanik,

17

Python -> Piet, 385 345 caratteri

È possibile generare qualsiasi programma Piet con questo. Avrei potuto fermarmi a pixel casuali, ma volevo creare programmi "interessanti". La funzione mcolora un pixel di un colore e ricorre ricorsivamente a ciascuno dei pixel vicini. Esistono modi migliori per disegnare blob casuali, ma questo è ottimizzato per terminare in un numero ragionevole di passaggi, quindi è abbastanza buono per il golf. La funzione R(w,h,n)disegna n blob casuali su un'immagine bianca ( w x h ) e stampa il risultato in formato PPM.

Sono particolarmente orgoglioso di come generi i colori: per una scelta casuale di 0 <= c < 20,

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

è il codice decimale per un colore valido nella palette Piet mediante un codice Gray a traccia singola . Cioè, ogni colore è rappresentato da 3 bit adiacenti e ogni sezione '0003...0'[c:c+3]rappresenta un colore diverso. Dato che questa non è la lista completa di 27 parole su 3 lettere, sono stato davvero fortunato a trovare il codice 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])

Output di esempio, generato dal comando R(30,40,500)

programma Piet casuale

Senza l'importazione, posso scriverlo anche come 1-liner (senza punto e virgola):

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)

ma è ridicolmente lento (e quasi 100 caratteri in più) ... anche se non sono del tutto sicuro del perché (e non terribilmente incline a scoprirlo).


9

Python -> Python, 135 caratteri

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 piccole valutazioni di espressioni casuali, in questo modo:

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

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

6

PHP, 352 caratteri

Genera codice PHP in PHP.

Decisi che non mi importava molto della lunghezza, ma desideravo invece un insieme interessante e diversificato di soluzioni. Questa è la mia risposta a questo.

Codice

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

Esempio

> 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
Potresti includere un esempio di output?
Alexandru,

5

scala: 1543 (scala => scala)

Ho variabili (x, y, z), funzioni (mul, add, neg, abs), valori e parentesi bilanciate.

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

Come vedi, non è molto golf. Perché, non mi avvicinerà alle altre soluzioni, ma un problema è che una maggiore variazione costa di più. 3 variabili, 4 funzioni potrebbero essere facilmente ridotte a due, ad esempio.

Generazione di alcuni campioni:

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) 

Testare il più lungo:

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 caratteri

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

Forse un po 'fuori tema, ma forse è così.

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

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 programma eseguibile brainfuck.

Una specie di imitazione spudorata di ESultanik, quindi gli darò credito per l'idea.

  • .Zero modificato? a == 0

3

Javascript -> Brainf * ck: 119 caratteri

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

I / O di esempio:

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

Il codice potrebbe sicuramente essere più breve, ma alcune cose, IMHO, lo renderebbero meno interessante. Ma se qualcun altro propone un programma più breve, ne ridurrò di più.


2

Python -> Python, 148 caratteri

Più lungo delle altre voci di Python a scapito di essere (soggettivamente) un po 'più interessante.

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)

Ciò stampa un attributo profondamente nidificato di un oggetto incorporato.

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

2

PowerShell, generazione di PowerShell - 43

Nello spirito della soluzione di Keith:

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

genera espressioni casuali di aggiunte e sottrazioni:

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

Un modo 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

Lingua del Game Maker -> Arduino o Ti84-Basic, 6 3 caratteri

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

Spiegazione:

a=argument0 Mette l'input in variabile a

if a mod 2 Fondamentalmente, metà delle probabilità il programma sarà Arduino, metà Ti-Basic 84

Il programma Arduino produce cose casuali a intervalli casuali, saltando casualmente cose casuali.

Il programma Ti-Basic disegna linee orizzontali come un matto.

Inoltre, c'è un bonus: i programmi generati sono già giocati a golf! Non sono sicuro che sarebbe utile ...


1

Perl -> HQ9 + (42 caratteri)

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

Esempio di input

4264532623562346

Produzione

Q

1

JavaScript -> Javascript (44 caratteri)

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

E con 43 caratteri, può eseguire il programma generato invece di visualizzarne l'origine:

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

Esempi:

Seme: 5
eseguito 3 volte:

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

Dov'è il seme?
Maniglia della porta
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.