Мова опису мондрійського живопису


16

Це завдання полягає в кодуванні перекладача для Mondrian мови опису картини (MPDL).

Визначення мови

Мова діє на стеку прямокутників. Прямокутник визначається лівою верхньою лівою і нижньою правою координатами. Координати повинні бути цілими числами. Стек ініціалізується єдиним прямокутником з атрибутами(1,1,254,254)

Кожна команда має такий формат: <character><integer>

Є три команди:

v<integer>: виконати вертикальний розріз на останньому прямокутнику в стеку у положенні, зазначеному параметром (у відсотках). Прямокутник-джерело виймається зі стека і замінюється двома новими прямокутниками, які є результатом розщеплення. Лівий прямокутник висувається на стек, потім правий прямокутник. Оскільки координати прямокутника є цілими числами, дроби повинні бути округлені до найбільшого меншого цілого числа.

h<integer>: горизонтальний розкол. Верхній прямокутник висувається на стек, потім нижній прямокутник.

c<integer>: видаляє останній прямокутник зі стека та зафарбовує його в колір, заданий як параметр. 1 = білий, 2 = червоний, 3 = синій, 4 = жовтий

Виклик

Напишіть програму, яка приймає за параметр опис картини та створює бітову картину розміром 256х256 зображених прямокутників. Прямокутники повинні бути відокремлені чорною лінією в 3 пікселі. Прямокутник одного або двох пікселів повинен мати свої нечорні пікселі, приховані чорними пікселями.

Ви можете читати дані як параметр або як файл. Команди повинні бути розділені пробілом. Ви можете припустити, що вхідний файл має правильний синтаксис і не має проміжних чи провідних пробілів, вкладок тощо. Вихід можна безпосередньо відображати на екрані або зберігати у файлі.

Виграє найкоротший код.

Тест

Наступне джерело:

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

Слід створити склад II червоного, синього та жовтого кольорів :

введіть тут опис зображення


1
Мова не велика. vа hаргументи мають бути в пікселях
Джон Дворак

Крім того, я не впевнений, який сенс повертати стек, а не вискакувати.
Джон Дворак

Використання відсотків дозволяє вибрати будь-який розмір для вихідної растрової карти - результат буде однаковим (лише він буде масштабуватися)
Арно

1
Так, щось подібне, але зауважте, ви все ще можете обійтися без додаткових синтаксичних елементів, оскільки всі оператори мають постійну кількість параметрів. Отже, вищевикладене можна ще розібрати, якщо представити як v30 v50 c1 c5 h70 v50 c1 c3 c2.
nutki

3
Дуже сподіваючись, що хтось пише рішення в Piet !
Скайлер

Відповіді:


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 ширина -h висота -o вихідний файл . Виводить файл "a.svg", якщо це не відразу зрозуміло з коду. Оскільки вихід є векторним зображенням, він не є «піксельним ідеальним».

Це мій перший раз, коли я працюю з "Діаграмами", не соромтесь зазначити будь-які помилки, які я зробив. Особливо добре було б будь-який бекенд, який дозволив би мені вивести менше коду.

Деякі перші кроки, які я зробив під час розробки коду, ви можете побачити на сторінці http://paste.hskll.org/get/1737 . Він відрізняється від наведеного вище коду в імпорті та не має основного, оскільки paste.hskll.org забезпечує власне основне середовище для малювання.


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). І розщепленню не потрібен аргумент, якщо розділяти пробіл.
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 Дякую! Я завтра вдосконалю його.
Міка Ламмі

Дякую за відповідь, але я намагаюся перевірити це, і у мене білий екран?
Арно

@SuperChafouin Який браузер ви використовуєте? Я не думаю, що функції стрілок (та інші речі ES6) справді підтримуються, окрім Firefox.
Міка Ламмі

1

HTML + JavaScript (ES6) 335

Занадто схожий на відповідь @mika - маркування CW.

  • замінити функцією, а не розділити ... карту
  • оператор розповсюдження
  • натисніть відразу 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>

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.