蒙德里安绘画描述语言


16

挑战在于为Mondrian绘画描述语言(MPDL)编写解释器。

语言定义

该语言在矩形堆栈上运行。矩形由其左上坐标和右下坐标定义。坐标必须是整数。使用具有属性的单个矩形初始化堆栈(1,1,254,254)

每个命令具有以下格式: <character><integer>

有以下三个命令:

v<integer>:在参数中指示的位置(以百分比表示)上对堆栈中的最新矩形执行垂直分割。将源矩形从堆栈中删除,并替换为拆分产生的两个新矩形。左边的矩形被压入堆栈,然后是右边的矩形。由于矩形坐标是整数,因此分数应四舍五入为最大的较小整数。

h<integer>:水平分割。顶部矩形被压入堆栈,然后底部矩形被压入堆栈。

c<integer>:从堆栈中删除最新的矩形,并将其绘制为参数指定的颜色。1 =白色,2 =红色,3 =蓝色,4 =黄色

挑战

编写一个程序,将绘制说明作为参数,并创建绘制矩形的256x256位图表示形式。矩形必须以3像素的黑线分隔。一个或两个像素矩形应使其非黑色像素被边框黑色像素隐藏。

输入可以作为参数或文件读取,由您决定。命令应以空格分隔。您可以假定输入文件的语法正确,并且没有尾部或前导空格,制表符等。输出可以直接显示在屏幕上,也可以保存到文件,由您自己决定。

最短的代码获胜。

测试

以下来源:

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

应产生红色,蓝色和黄色成分II

在此处输入图片说明


1
语言不是很好。vh参数应该以像素为单位
John Dvorak

另外,我不确定旋转堆栈而不是弹出堆栈有什么意义。
约翰·德沃夏克

使用百分比可以让您为输出位图选择任何大小-结果将是相同的(只是将被缩放)
Arnaud 2014年

1
是的,但是请注意,由于所有运算符都有固定数量的参数,因此仍然可以不使用额外的语法元素。因此,当表示为时,仍可以解析以上内容v30 v50 c1 c5 h70 v50 c1 c3 c2
nutki 2014年

3
真希望有人在Piet中写一个解决方案!
Skyler

Answers:


6

Perl 5 + ImageMagick-297

开始于:

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"

在命令行上输入并生成a.gif


2

哈斯克尔-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

程序从stdin读取一行指令,如果这是不可接受的,请告诉我。

编译成带有标志-w width -h height -o outputfile的程序 如果尚无法从代码中立即清除,则输出一个“ a.svg”文件。由于输出是矢量图像,因此它不是“像素完美”的。

这是我第一次使用Diagrams -package,请随时指出我犯的任何错误。尤其是任何能让我用更少的代码输出的后端都很好。

您可以在http://paste.hskll.org/get/1737中看到开发代码时我采取的一些第一步。它与上面的代码在导入方面有所不同,并且缺少main,因为paste.hskll.org提供了自己的main和绘图环境。


2

蟒蛇- 434 405 377 364 361

我的第一个蟒蛇高尔夫。这可能可以改善很多,所以任何反馈表示赞赏。

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
您可以通过将第4、5行与分号合并来保存字符。也a+=[x]代替a.append(x)。如果用空格分隔,则split不需要参数。
Sp3000

1

HTML + JavaScript ES6(407)

经过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
好多高尔夫!x.charAt(0)-> x[0]; x.substr-> x.slice; white yellow-> #fff #ff0; document.getElementById("c")-> c...以及更多
edc65

@ edc65谢谢!明天我会进一步改善它。
米卡·拉米

感谢您的回答,但我尝试对其进行测试,但是我有一个白屏?
2014年

@SuperChafouin您正在使用什么浏览器?我认为除了Firefox之外,实际上不支持箭头功能(以及其他ES6东西)。
米卡·拉米

1

HTML + JavaScript(ES6)335

太类似于@mika答案-标记为CW。

  • 用函数替换而不是split ... map
  • 点差算子
  • 一次推送2个值
  • 三元运算符,而不是函数属性

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.