Beschreibungssprache für das Mondrian-Gemälde


16

Diese Herausforderung besteht darin, einen Interpreter für eine Mondrianische Bildbeschreibungssprache (MPDL) zu codieren .

Sprachdefinition

Die Sprache arbeitet mit einem Stapel Rechtecke. Ein Rechteck wird durch seine obere linke Koordinate und seine untere rechte Koordinate definiert. Koordinaten müssen ganze Zahlen sein. Der Stapel wird mit einem einzelnen Rechteck mit Attributen initialisiert(1,1,254,254)

Jeder Befehl hat das folgende Format: <character><integer>

Es gibt drei Befehle:

v<integer>: Führe eine vertikale Teilung des letzten Rechtecks ​​im Stapel an der durch den Parameter angegebenen Position durch (in Prozent). Das Quellrechteck wird aus dem Stapel entfernt und durch die beiden neuen Rechtecke ersetzt, die sich aus der Aufteilung ergeben. Das linke Rechteck wird auf den Stapel geschoben, dann das rechte Rechteck. Da Rechteckkoordinaten Ganzzahlen sind, sollten Brüche auf die größte kleinere Ganzzahl gerundet werden.

h<integer>: horizontale Teilung. Das obere Rechteck wird auf den Stapel geschoben, dann das untere Rechteck.

c<integer>: Entfernt das letzte Rechteck vom Stapel und malt es in der als Parameter angegebenen Farbe. 1 = weiß, 2 = rot, 3 = blau, 4 = gelb

Herausforderung

Schreiben Sie ein Programm, das als Parameter eine Malbeschreibung verwendet und eine 256x256-Bitmap-Darstellung der gemalten Rechtecke erstellt. Die Rechtecke müssen mit einer schwarzen Linie von 3 Pixeln getrennt werden. Bei einem Ein-oder Zwei-Pixel-Rechteck sollten die nicht schwarzen Pixel durch die schwarzen Randpixel verdeckt sein.

Die Eingabe kann nach Belieben als Parameter oder als Datei gelesen werden. Die Befehle sollten durch ein Leerzeichen getrennt sein. Sie können davon ausgehen, dass die Eingabedatei die richtige Syntax aufweist und keine nachgestellten oder führenden Leerzeichen, Tabulatoren usw. enthält. Die Ausgabe kann direkt auf dem Bildschirm angezeigt oder in einer Datei gespeichert werden.

Der kürzeste Code gewinnt.

Prüfung

Die folgende Quelle:

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

Sollte die Komposition II in Rot, Blau und Gelb produzieren :

Bildbeschreibung hier eingeben


1
Die Sprache ist nicht so toll. vund hArgumente sollten in Pixel angegeben werden
John Dvorak

Ich bin mir auch nicht sicher, wozu es gut ist, den Stapel zu drehen, anstatt zu platzen.
John Dvorak

Mit Prozent ermöglicht es Ihnen , unabhängig von Größe für die Ausgabe - Bitmap zu wählen - wird das Ergebnis gleich sein (nur wird es skaliert)
Arnaud

1
Ja, so ähnlich, aber beachten Sie, dass Sie immer noch auf zusätzliche Syntaxelemente verzichten können, da alle Operatoren eine konstante Anzahl von Parametern haben. Das oben Gesagte kann also trotzdem analysiert werden, wenn es als dargestellt wird v30 v50 c1 c5 h70 v50 c1 c3 c2.
Nutki

3
Ich hoffe wirklich, jemand schreibt eine Lösung in Piet !
Skyler

Antworten:


6

Perl 5 + ImageMagick - 297

Etwas, mit dem man anfangen sollte:

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"

Übernimmt die Eingabe in der Befehlszeile und generiert 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

Das Programm liest die Anweisungen als eine Zeile von stdin , wenn dies nicht akzeptabel ist, lassen Sie es mich wissen.

Kompiliert in ein Programm, das Flags -w width -h height -o outputfile akzeptiert . Gibt eine "a.svg" -Datei aus, wenn dies nicht sofort aus dem Code hervorgeht. Da es sich bei der Ausgabe um ein Vektorbild handelt, ist es nicht „pixelgenau“.

Ich arbeite zum ersten Mal mit Diagrams -package und kann auf Fehler hinweisen, die ich gemacht habe. Besonders jedes Backend, mit dem ich weniger Code ausgeben könnte, wäre schön.

Einige der ersten Schritte, die ich bei der Entwicklung des Codes unternommen habe, finden Sie unter http://paste.hskll.org/get/1737 . Es unterscheidet sich vom obigen Code in Bezug auf Importe und es fehlt main, da paste.hskll.org eine eigene Haupt- und Zeichenumgebung bietet.


2

Python - 434 405 377 364 361

Mein erstes Pythongolf. Dies kann wahrscheinlich VIEL verbessert werden, so dass jedes Feedback geschätzt wird.

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
Sie können ein Zeichen speichern, indem Sie die Zeilen 4, 5 mit einem Semikolon verbinden. Auch a+=[x]statt a.append(x). Und Split braucht kein Argument, wenn es durch Leerzeichen getrennt wird.
Sp3000

1

HTML + JavaScript ES6 (407)

Getestet mit 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
So viel mehr Golf! x.charAt(0)-> x[0]; x.substr-> x.slice; white yellow-> #fff #ff0; document.getElementById("c")-> c... und mehr
edc65

@ edc65 Danke! Ich werde es morgen weiter verbessern.
Mika Lammi

Danke für die Antwort, aber ich versuche es zu testen und ich habe einen weißen Bildschirm?
Arnaud

@SuperChafouin Welchen Browser verwenden Sie? Ich glaube nicht, dass Pfeilfunktionen (und andere ES6-Funktionen) wirklich unterstützt werden, außer in Firefox.
Mika Lammi

1

HTML + JavaScript (ES6) 335

Zu ähnlich wie @mika answer - Kennzeichnung CW.

  • Ersetzen Sie mit Funktion anstelle von Split ... Karte
  • Spread-Operator
  • 2 Werte gleichzeitig drücken
  • ternärer Operator anstelle von Funktionseigenschaften

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

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.