Язык описания мондрианской живописи

16

Эта задача заключается в написании интерпретатора для языка описания картин Мондриана (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 красного, синего и желтого цветов :

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

Arnaud
источник
1
Язык не велик. vи hаргументы должны быть в пикселях
Джон Дворжак
Кроме того, я не уверен, какой смысл вращать стек вместо того, чтобы хлопать.
Джон Дворжак
Использование процентов позволяет выбрать любой размер выходного растрового изображения - результат будет таким же (только он будет масштабирован)
Arnaud
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.

nutki
источник
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

Программа читает инструкцию как одну строку из стандартного ввода , если это недопустимо, дайте мне знать.

Компилируется в программу, которая принимает флаги -w width -h height -o outputfile . Выводит файл "a.svg", если это не сразу понятно из кода. Поскольку на выходе получается векторное изображение, оно не «идеально подходит для пикселей».

Я впервые работаю с пакетом Diagrams, не стесняйтесь указывать на любые ошибки, которые я допустил. Особенно хороший бэкэнд, который позволил бы мне выводить меньше кода.

Вы можете увидеть некоторые из первых шагов, которые я предпринял при разработке кода, по адресу http://paste.hskll.org/get/1737 . Он отличается от приведенного выше кода в импорте и не содержит main, поскольку paste.hskll.org предоставляет собственную среду main и среду рисования.

shiona
источник
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.

  • заменить на функцию вместо 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>

оборота edc65
источник