Linguaggio di descrizione della pittura di Mondrian


16

Questa sfida consiste nel codificare un interprete per un linguaggio di descrizione della pittura di Mondrian (MPDL).

Definizione della lingua

La lingua funziona su una pila di rettangoli. Un rettangolo è definito dalla sua coordinata superiore sinistra e coordinata inferiore destra. Le coordinate devono essere numeri interi. Lo stack è inizializzato con un singolo rettangolo con attributi(1,1,254,254)

Ogni comando ha il seguente formato: <character><integer>

Esistono tre comandi:

v<integer>: esegue una divisione verticale sull'ultimo rettangolo nello stack, nella posizione indicata dal parametro (in percentuale). Il rettangolo di origine viene rimosso dalla pila e sostituito con i due nuovi rettangoli risultanti dalla divisione. Il rettangolo sinistro viene inserito nella pila, quindi il rettangolo destro. Poiché le coordinate rettangolari sono numeri interi, le frazioni devono essere arrotondate al numero intero più piccolo più grande.

h<integer>: divisione orizzontale. Il rettangolo superiore viene inserito nella pila, quindi il rettangolo inferiore.

c<integer>: rimuove l'ultimo rettangolo dalla pila e lo colora al colore indicato come parametro. 1 = bianco, 2 = rosso, 3 = blu, 4 = giallo

Sfida

Scrivi un programma che accetta come parametro una descrizione del disegno e crea una rappresentazione bitmap 256x256 dei rettangoli dipinti. I rettangoli devono essere separati con una linea nera di 3 pixel. Un rettangolo di uno o due pixel dovrebbe avere i suoi pixel non neri nascosti dai pixel neri del bordo.

L'input può essere letto come parametro o come file, fino a te. I comandi dovrebbero essere separati da uno spazio. Si può presumere che il file di input abbia una sintassi corretta e non abbia spazi, schede, ecc. Finali o iniziali. L'output può essere visualizzato direttamente sullo schermo o salvato in un file, fino a te.

Vince il codice più corto.

Test

La seguente fonte:

v25 h71 v93 h50 c4 c1 c1 c2 h71 c3 h44 c1 c1

Dovrebbe produrre la composizione II in rosso, blu e giallo :

inserisci qui la descrizione dell'immagine


1
La lingua non è eccezionale. ve gli hargomenti dovrebbero essere in pixel
John Dvorak,

Inoltre, non sono sicuro di quale sia lo scopo di ruotare la pila invece di scoppiare.
John Dvorak,

L'uso delle percentuali ti consente di scegliere qualsiasi dimensione per la bitmap di output - il risultato sarà lo stesso (solo esso verrà ridimensionato)
Arnaud

1
Sì, qualcosa del genere, ma nota che puoi ancora fare a meno degli elementi di sintassi extra poiché tutti gli operatori hanno un numero costante di parametri. Quindi quanto sopra può ancora essere analizzato quando rappresentato come v30 v50 c1 c5 h70 v50 c1 c3 c2.
Nutki,

3
Spero davvero che qualcuno scriva una soluzione in Piet !
Skyler,

Risposte:


6

Perl 5 + ImageMagick - 297

Qualcosa da cui iniziare:

sub a{my($x,$y,$X,$Y,$d)=@_;$_=shift@ARGV;
/v/?a($d=$x+($X-$x)*$'/100,$y,$X,$Y).a($x,$y,$d,$Y):
/h/?a($x,$d=$y+($Y-$y)*$'/100,$X,$Y).a($x,$y,$X,$d):
/c/&&"-fill ".qw/white red blue yellow/[$'-1]." -draw 'rectangle $x,$y $X,$Y' "}
system"convert -size 256x256 -stroke black xc: ".a(0,0,255,255)."a.gif"

Accetta input dalla riga di comando e genera a.gif.


2

Haskell - 335

import Diagrams.Prelude
import Diagrams.Backend.SVG
c=centerXY
d((x:n):i)|x=='v'=(b#scaleX s#c|||a#scaleX(1-s)#c,k)|x=='h'=(b#scaleY s#c===a#scaleY(1-s)#c,k)|x=='c'=(square 1#fc([white,red,blue,yellow]!!(read n-1)),i)where{s=(read n)/100;(a,j)=d i;(b,k)=d j}
main=getLine>>=renderSVG"a.svg"(Width 256).pad 1.02.c.lwG 0.012.fst.d.words

Il programma legge le istruzioni come una riga da stdin , se questo è inaccettabile fammelo sapere.

Compila in un programma che accetta flag -w larghezza -h altezza -o file di output . Emette un file "a.svg", se non è immediatamente chiaro dal codice. Poiché l'output è un'immagine vettoriale, non è "pixel perfetto".

Questa è la prima volta che lavoro con Diagrams -package, sentiti libero di segnalare eventuali errori che ho fatto. Soprattutto qualsiasi backend che mi permettesse di produrre con meno codice sarebbe bello.

Puoi vedere alcuni dei primi passi che ho fatto durante lo sviluppo del codice in http://paste.hskll.org/get/1737 . Si differenzia dal codice sopra riportato nelle importazioni e manca di main poiché paste.hskll.org fornisce il proprio ambiente principale e di disegno.


2

Python - 434 405 377 364 361

Il mio primo golf in pitone. Questo può probabilmente essere migliorato MOLTO, quindi ogni feedback è apprezzato.

from turtle import*
a=[[1,1,254,254]]
for c in input().split():
 v,w,x,y=a.pop();p,b,f,g=int(c[1::1]),'hvc'.index(c[0]),x-v,y-w
 if b>1:goto(v,-w),color('#000',['#fff','red','#00f','#ff0'][p-1]),begin_fill(),[(fd(o),rt(90))for o in[f,g]*2],end_fill()
 else:a+=[[v,w,(x,v+(((x-v)/100)*p))[b],(w+(((y-w)/100)*p),y)[b]])],a+=[[[v,a[-1][2]][b],[a[-1][3],w][b],x,y]]

1
È possibile salvare un carattere unendo le righe 4, 5 con un punto e virgola. Anche a+=[x]invece di a.append(x). E la divisione non ha bisogno di argomenti se si separa per spazi bianchi.
Sp3000,

1

HTML + JavaScript ES6 (407)

Testato con Firefox 32.0.3

<canvas id=c width=256 height=256><script>r=[[1,1,253,253]]
p=x=>r.push(x)
o=c.getContext("2d")
o.lineWidth=3
prompt().split(" ").map(x=>{q=r.pop()
v=q[0]
b=q[1]
n=q[2]
m=q[3],{c:x=>{o.beginPath()
o.rect(v,b,n,m)
o.fillStyle=[,"#fff","red","blue","#ff0"][x]
o.fill()
o.stroke()},v:x=>{s=x/100*n|0
p([v,b,s,m])
p([v+s,b,n-s,m])},h:x=>{s=x/100*m|0
p([v,b,n,s])
p([v,b+s,n,m-s])}}[x[0]](+x.slice(1))})</script>


1
Molto più golfabile! x.charAt(0)-> x[0]; x.substr-> x.slice; white yellow-> #fff #ff0; document.getElementById("c")-> c... e altro ancora
edc65,

@ edc65 Grazie! Lo migliorerò ulteriormente domani.
Mika Lammi,

Grazie per la risposta, ma provo a provarlo e ho una schermata bianca?
Arnaud,

@SuperChafouin Quale browser stai utilizzando? Non penso che le funzioni freccia (e altre cose ES6) siano davvero supportate tranne che in Firefox.
Mika Lammi,

1

HTML + JavaScript (ES6) 335

Troppo simile alla risposta @mika - marcatura CW.

  • sostituisci con funzione invece di dividere ... mappa
  • operatore di diffusione
  • spingere 2 valori contemporaneamente
  • operatore ternario anziché proprietà della funzione

<canvas id=c><script>
c.width=c.height=256,
s=[[1,1,253,253]],
o=c.getContext('2d'),
o.translate(0.5,0.5), // to avoid anti-alias on straight lines
o.lineWidth=3,
prompt().replace(/(\S)(\d+)/g,(_,c,n)=>(
p=s.pop(o.fillStyle=[,'#fff','red','#00f','#ff0'][n]),
c<'d'?(o.fillRect(...p),o.strokeRect(...p))
:(c=c<'i'|2,
 q=[...p],
 q[c]=r=q[c]*n/100|0,
 p[c]-=r,
 p[c-2]+=r,
 s.push(q,p))))
</script>

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.