Ngôn ngữ mô tả bức tranh Mondrian


16

Thách thức này bao gồm mã hóa trình thông dịch cho ngôn ngữ mô tả bức tranh Mondrian (MPDL).

Định nghĩa ngôn ngữ

Ngôn ngữ hoạt động trên một chồng hình chữ nhật. Một hình chữ nhật được xác định bởi tọa độ trên bên trái và tọa độ dưới bên phải của nó. Tọa độ phải là số nguyên. Ngăn xếp được khởi tạo với một hình chữ nhật duy nhất với các thuộc tính(1,1,254,254)

Mỗi lệnh có định dạng sau: <character><integer>

Có ba lệnh:

v<integer>: thực hiện phân chia dọc trên hình chữ nhật mới nhất trong ngăn xếp, tại vị trí được chỉ định bởi tham số (tính theo phần trăm). Hình chữ nhật nguồn được xóa khỏi ngăn xếp và thay thế bằng hai hình chữ nhật mới là kết quả của sự phân chia. Hình chữ nhật bên trái được đẩy trên ngăn xếp, sau đó hình chữ nhật bên phải. Vì tọa độ hình chữ nhật là số nguyên, phân số phải được làm tròn thành số nguyên nhỏ hơn lớn nhất.

h<integer>: chia ngang. Hình chữ nhật trên cùng được đẩy trên ngăn xếp, sau đó hình chữ nhật dưới cùng.

c<integer>: xóa hình chữ nhật mới nhất khỏi ngăn xếp và tô nó thành màu cho dưới dạng tham số. 1 = trắng, 2 = đỏ, 3 = xanh, 4 = vàng

Thử thách

Viết chương trình lấy tham số mô tả bức tranh và tạo một biểu diễn bitmap 256x256 của các hình chữ nhật được vẽ. Các hình chữ nhật phải được phân tách bằng một đường màu đen 3 pixel. Một hình chữ nhật một hoặc hai pixel phải có các pixel không phải màu đen của anh ta bị ẩn bởi các pixel đen viền.

Đầu vào có thể được đọc dưới dạng tham số hoặc dưới dạng tệp, tùy thuộc vào bạn. Các lệnh nên được phân tách bằng khoảng trắng. Bạn có thể giả sử rằng tệp đầu vào có cú pháp chính xác và không có dấu cách hoặc dấu cách hàng đầu, tab, v.v. Đầu ra có thể được hiển thị trực tiếp trên màn hình hoặc lưu vào tệp, tùy theo bạn.

Mã ngắn nhất sẽ thắng.

Kiểm tra

Nguồn sau:

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

Nên sản xuất Thành phần II có màu Đỏ, Xanh và Vàng :

nhập mô tả hình ảnh ở đây


1
Ngôn ngữ không phải là tuyệt vời. vvà các hđối số phải được tính bằng pixel
John Dvorak

Ngoài ra, tôi không chắc chắn điểm xoay vòng thay vì bật lên là gì.
John Dvorak

Sử dụng tỷ lệ phần trăm cho phép bạn chọn bất kỳ kích thước nào cho bitmap đầu ra - kết quả sẽ giống nhau (chỉ có tỷ lệ sẽ được chia tỷ lệ)
Arnaud

1
Vâng, một cái gì đó tương tự, nhưng lưu ý bạn vẫn có thể làm mà không cần thêm các yếu tố cú pháp vì tất cả các toán tử có số lượng tham số không đổi. Vì vậy, ở trên vẫn có thể được phân tích cú pháp khi được đại diện như v30 v50 c1 c5 h70 v50 c1 c3 c2.
nutki

3
Thực sự hy vọng ai đó viết một giải pháp trong Piet !
Skyler

Câu trả lời:


6

Perl 5 + ImageMagick - 297

Một cái gì đó để bắt đầu với:

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 đầu vào vào dòng lệnh và tạo 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

Chương trình đọc các hướng dẫn dưới dạng một dòng từ stdin , nếu điều này không được chấp nhận, hãy cho tôi biết.

Biên dịch thành một chương trình có cờ -w width -h height -o outputfile . Xuất ra tệp "a.svg", nếu mã đó không rõ ràng ngay lập tức. Vì đầu ra là một hình ảnh vector, nó không phải là "pixel hoàn hảo".

Đây là lần đầu tiên tôi làm việc với gói Sơ đồ, hãy thoải mái chỉ ra bất kỳ lỗi nào tôi đã mắc phải. Đặc biệt là bất kỳ phụ trợ nào cho phép tôi xuất ra với ít mã hơn sẽ tốt hơn.

Bạn có thể thấy một số bước đầu tiên tôi đã thực hiện khi phát triển mã trong http://paste.hskll.org/get/1737 . Nó khác với mã ở trên trong nhập khẩu và thiếu chính vì paste.hskll.org cung cấp môi trường chính và bản vẽ riêng.


2

Con trăn - 434 405 377 364 361

Golf trăn đầu tiên của tôi. Điều này có thể được cải thiện rất nhiều, vì vậy bất kỳ thông tin phản hồi đều được đánh giá cao.

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
Bạn có thể lưu char bằng cách hợp nhất các dòng 4, 5 với dấu chấm phẩy. Ngoài ra a+=[x]thay vì a.append(x). Và phân chia không cần một đối số nếu phân tách bằng khoảng trắng.
Sp3000

1

HTML + JavaScript ES6 (407)

Đã thử nghiệm với 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
Vì vậy, nhiều golf hơn! x.charAt(0)-> x[0]; x.substr-> x.slice; white yellow-> #fff #ff0; document.getElementById("c")-> c... và hơn thế nữa
edc65

@ edc65 Cảm ơn! Tôi sẽ cải thiện nó hơn nữa vào ngày mai.
Mika Lammi

Cảm ơn câu trả lời, nhưng tôi thử kiểm tra nó và tôi có một màn hình trắng?
Arnaud

@SuperChafouin Bạn đang sử dụng trình duyệt nào? Tôi không nghĩ rằng các chức năng mũi tên (và các công cụ ES6 khác) thực sự được hỗ trợ ngoại trừ trong Firefox.
Mika Lammi

1

HTML + JavaScript (ES6) 335

Quá giống với câu trả lời @mika - đánh dấu CW.

  • thay thế bằng chức năng thay vì chia ... bản đồ
  • điều hành lây lan
  • đẩy 2 giá trị cùng một lúc
  • toán tử ternary thay vì các thuộc tính chức năng

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

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.