Język opisu malarstwa Mondrian

16

Wyzwanie polega na kodowaniu tłumacza dla języka opisu malarstwa Mondrian (MPDL).

Definicja języka

Język działa na stosie prostokątów. Prostokąt jest zdefiniowany przez jego lewą górną współrzędną i dolną prawą współrzędną. Współrzędne muszą być liczbami całkowitymi. Stos jest inicjowany pojedynczym prostokątem z atrybutami(1,1,254,254)

Każde polecenie ma następujący format: <character><integer>

Istnieją trzy polecenia:

v<integer>: wykonaj podział pionowy na ostatnim prostokącie w stosie, w miejscu wskazanym przez parametr (w procentach). Prostokąt źródłowy jest usuwany ze stosu i zastępowany dwoma nowymi prostokątami wynikającymi z podziału. Lewy prostokąt jest wciskany na stosie, a następnie prawy prostokąt. Ponieważ współrzędne prostokąta są liczbami całkowitymi, ułamki powinny być zaokrąglane do największej mniejszej liczby całkowitej.

h<integer>: podział poziomy. Górny prostokąt jest wciskany na stosie, a następnie dolny prostokąt.

c<integer>: usuwa najnowszy prostokąt ze stosu i maluje go na kolor podany jako parametr. 1 = biały, 2 = czerwony, 3 = niebieski, 4 = żółty

Wyzwanie

Napisz program, który przyjmuje jako parametr opis malowania i tworzy bitmapę 256 x 256 reprezentacji malowanych prostokątów. Prostokąty muszą być oddzielone czarną linią 3 piksele. Prostokąt z jednym lub dwoma pikselami powinien mieć ukryte czarne piksele poza obramowaniem.

Dane wejściowe można odczytać jako parametr lub jako plik, zależnie od Ciebie. Polecenia powinny być oddzielone spacją. Możesz założyć, że plik wejściowy ma poprawną składnię i nie ma spacji końcowych ani wiodących, tabulatorów itp. Dane wyjściowe można wyświetlić bezpośrednio na ekranie lub zapisać w pliku, zależnie od Ciebie.

Najkrótszy kod wygrywa.

Test

Następujące źródło:

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

Powinien produkować Kompozycję II w kolorze czerwonym, niebieskim i żółtym :

wprowadź opis zdjęcia tutaj

Arnaud
źródło
1
Język nie jest świetny. va hargumenty powinny być w pikselach
John Dvorak
Nie jestem też pewien, jaki jest sens obracania stosu zamiast wyskakiwania.
John Dvorak
Użycie wartości procentowych pozwala wybrać dowolny rozmiar wyjściowej mapy bitowej - wynik będzie taki sam (tylko będzie skalowany)
Arnaud
1
Tak, coś takiego, ale pamiętaj, że nadal możesz obejść się bez dodatkowych elementów składni, ponieważ wszyscy operatorzy mają stałą liczbę parametrów. Tak więc powyższe można nadal analizować, gdy jest reprezentowane jako v30 v50 c1 c5 h70 v50 c1 c3 c2.
nutki
3
Naprawdę mam nadzieję, że ktoś napisze rozwiązanie w Piet !
Skyler

Odpowiedzi:

6

Perl 5 + ImageMagick - 297

Coś na początek:

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"

Pobiera dane z wiersza poleceń i generuje a.gif.

nutki
źródło
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

Program odczytuje instrukcje jako jedną linię od standardowego wejścia , jeśli jest to niedopuszczalne, daj mi znać.

Kompiluje się w program, który przyjmuje flagi -w szerokość -h wysokość -o plik wyjściowy . Wysyła plik „a.svg”, jeśli nie jest to natychmiast usunięte z kodu. Ponieważ wynik jest obrazem wektorowym, nie jest on „pikselowy”.

Po raz pierwszy pracuję z pakietem Diagramy, możesz wskazać wszelkie błędy, które popełniłem. Zwłaszcza każdy backend, który pozwoliłby mi na wyjście z mniejszym kodem, byłby miły.

Niektóre z pierwszych kroków, które podjąłem podczas opracowywania kodu, można znaleźć na stronie http://paste.hskll.org/get/1737 . Różni się od powyższego kodu importem i brakuje mu głównego, ponieważ paste.hskll.org zapewnia własne środowisko główne i rysunkowe.

shiona
źródło
2

Python - 434 405 377 364 361

Mój pierwszy golf python. Prawdopodobnie można to DUŻO poprawić, więc wszelkie opinie są mile widziane.

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]]
William Barbosa
źródło
1
Możesz zapisać znak, łącząc linie 4, 5 średnikiem. Również a+=[x]zamiast a.append(x). A split nie potrzebuje argumentu, jeśli oddziela się spacjami.
Sp3000,
1

HTML + JavaScript ES6 (407)

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

Mika Lammi
źródło
1
O wiele bardziej golfowy! x.charAt(0)-> x[0]; x.substr-> x.slice; white yellow-> #fff #ff0; document.getElementById("c")-> c... i więcej
edc65
@ edc65 Dzięki! Poprawię to jutro.
Mika Lammi,
Dzięki za odpowiedź, ale próbuję ją przetestować i mam biały ekran?
Arnaud,
@SuperChafouin Z jakiej przeglądarki korzystasz? Nie sądzę, że funkcje strzałek (i inne rzeczy ES6) są naprawdę obsługiwane, z wyjątkiem Firefoksa.
Mika Lammi,
1

HTML + JavaScript (ES6) 335

Zbyt podobna do odpowiedzi @mika - oznaczenie CW.

  • zamień na funkcję zamiast podzielonej ... mapy
  • operator rozrzutu
  • wcisnąć 2 wartości na raz
  • trójskładnikowy zamiast właściwości funkcji

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

rev edc65
źródło