Engelsiz dikdörtgeni kaldırma


20

Bu görüntü 7 farklı renkli dikdörtgeni üst üste bindirerek yapılmıştır:

Ana resim

Siyah ve bordo dikdörtgenler engellenmez , yani üstlerinde başka dikdörtgen yoktur.

Bunun gibi bir görüntüyü alan bir program yazın ve ortaya çıkan görüntünün çıktısını almak için herhangi bir engelsiz dikdörtgeni kaldırın.

Misal

Programınızı yukarıdaki resimde çalıştırdıysanız ve çıktıda yeniden çalıştırmaya devam ederseniz, bu şekilde ilerleyebilir.

1.Aşama - Siyah kaldırıldı (kestane rengi olabilir):

koş 1

Run 2 - Bordo kaldırıldı (sadece seçim):

koş 2

3. Tur - Sarı kaldırıldı (tek seçenek):

koş 3

4. Koşu - Mavi kaldırıldı (yeşil olabilir):

koş 4

Run 5 - Yeşil kaldırıldı (sadece seçim):

koş 5

Yarış 6 - Kahverengi kaldırıldı (sadece seçim):

koş 6

Run 7 - Kırmızı kaldırıldı (sadece seçim):

koş 7

Ek çalışmalar aynı beyaz görüntüyü oluşturmalıdır.

Umarım Stack Exchange bu görüntüleri kayıtsız bir şekilde sıkıştırmamıştır.

Görüntü her zaman beyaz bir arka plana sahip olacak ve her dikdörtgen beyaz olmayan benzersiz bir RGB rengi olacaktır.

Görüntünün her zaman çakışan dikdörtgenler kümesi olarak yorumlanabileceğini varsayabilirsiniz. Özellikle, belirli bir renk için görüntünün üstüne en yakın o renge sahip pikselin, o rengin dikdörtgeninin üst kenarının bir parçası olduğunu varsayabilirsiniz. Aynı şey alt, sol ve sağ kenarlar için de geçerlidir.

Örneğin, bu görüntüde, kırmızı dikdörtgenin üst kenarı sarı dikdörtgenin alt kenarının hemen altındadır, çünkü turuncu dikdörtgen eski kırmızı üst kenarı kaplar:

örnek 1

Bu görüntüde, önce kırmızı dikdörtgen kaldırılabilir (siyah / bordo / turuncu / gri ile birlikte):

örnek 2

Alt dikdörtgenlerin sırası belirsiz olduğunda, onlara herhangi bir sipariş verebilirsiniz.

Örneğin, buradaki sol görüntü orta veya sağ olabilir:

örnek 3 örnek 4 örnek 5

Çıktıda paradoksal örtüşmeler olmamalıdır (bu yüzden ressamın algoritmasıyla yapmak mümkün olmalıdır). Yani bu görüntüde ( teşekkürler user23013 ), turuncu dikdörtgenin altında yeşil olması gerekir:

örnek 6

ek detaylar

  • Görüntü ve dikdörtgenler herhangi bir boyuta sahip olabilir.
  • Dikdörtgenler görüntü kenarlığına dokunabilir.
  • 256 adete kadar 3 - 1 dikdörtgen olabilir.
  • Giriş tamamen beyazsa, çıktı da olmalıdır.
  • Görüntü kitaplıkları kullanabilirsiniz.
  • Giriş, görüntü dosyası adı veya ham görüntü verisi olmalıdır. Stdin veya komut satırından gelebilir.
  • Çıktı aynı veya başka bir görüntü dosyasına yazılabilir, stdout'a çiğ olarak ya da basitçe görüntülenebilir.
  • Herhangi bir kayıpsız gerçek renk görüntü dosyası biçimine izin verilir.

En az bayt içeren gönderim kazanır.



Teknik olarak, gereksinimde çıktının paradoksal örtüşmeler olmayabileceğini söyleyen hiçbir şey yoktur. Eklenmeli mi, yoksa test senaryosunun yorumları da iyi mi?
John Dvorak

“Gerçek rengi” açıklığa kavuşturabilir misiniz?
FUZxxl


@JanDvorak Bunun ima edildiğine dair umudum vardı, ama haklısın, belirsiz, bu yüzden bir not ekledim.
Calvin'in Hobileri

Yanıtlar:


10

CJam, 241 bayt

(yeni satırlar kaldırılmış olarak.)

rri:Hri:Vri:Q[q~]3/_Qa3*a+_|$W%:Pf{\a#}:AH/:B0ff*
P,,[AHAW%HBz:+_W%V\V]2/
ff{~@@f=/::|1#}0Ua4*t:R;
P0f<
V{H{BI=J=_2$=
0R{"I>! I+V<J>! J+H<"4/+4/z{~~}%:&1$*\)}%);2$-|t
}fJ}fI
[P,{_La#\1$0t1$f-}*;;]
{:TR=2/~\~V\-,>\f{\_3$=@~H\-,>{Tt}/t}~}/
:~Pf=:~
~]S*N

Ppm dosya biçimini kullanır. Örnek kullanım (ImageMagick kullanarak):

convert IVYvE.png -compress none ppm:-| (time /path/to/cjam-0.6.4.jar 1.cjam) |display

Çok uzun ve çok yavaş ... Örnek için bir dakika kadar sürüyor.

Testi kolaylaştırmak için test senaryolarını yeniden boyutlandırdım (ve başkalarını ekledim).

Renk alanı bilgileri kaybolmuş gibi görünüyor, bu yüzden renkler biraz farklı.


2

Piton, 690 651 610 606 594 569 bayt

Komut dosyası görüntü adını stdin'den okur.

Her dikdörtgenin kenarlarını algılar, içerdikleri farklı renk sayısına göre sıralar (engelsiz dikdörtgenler yalnızca 1 renk içerir ve listenin sonunda görünür)

Bu liste bir görüntüyü yeniden çizmek için kullanılır. Yeniden çizme sırasına, girdiyle en az piksel farkına sahip bir çıktı görüntüsü oluşturacak listenin permütasyonu seçilerek karar verilir.

PIL içe aktarma resmi l olarak, ImageDraw D olarak; itertools içe aktarma *; O, R, I, Z, k = [], aralık, l.open (raw_input ()), {}, lambda x: -x [1 ]; (W, H), Q = I.size, I.load ()
ürün içindeki i, j için (R (W), R (H)):
 C = S [ij]
 eğer Z, x, y, X, Y = Z [c]; Z [c] = [x, y, maks. (X, i), maks. (Y, j)]
 Başka: Z, [C] = [i, j, 0,0]
n için permütasyonlar (sıralanmış ([(c, len ({Q [g] üründeki g için (R (x, X), R (y, Y))}))) için c, (x, y, X, Y) Z.items ()] içinde, anahtar = k) [1: -1]): o = l.yeni (I. mod, I.boyut, 0xFFFFFF); [D.Çizim (o). Dikdörtgen (Z [c], c için _, n içinde _ için doldurun = c; O + = [(o, t için toplam (abs (ab), zip'te T (I.getdata (), o.getdata ()) a, zip olarak b (t, T)))]
v max (O anahtar = k) [0] .show ()

0

Java - 1483 bayt

Ben büyük bir kod golfçü değilim, net olsun; bu yüzden ayrıntı düzeyi tamamen Java'nın hatası değildir ;-) Bununla birlikte, bu gerçekten eğlenceli bir meydan okuma gibi görünüyordu. Bunu - sanırım - biraz sıkıcı ve ayrıntılı olacak şekilde çözdüm, ama hey. Çalışır, (nispeten) hızlı ve özellikle eğlenceliydi!

Fikir şu şekildedir: Her pikselin sol üst köşeden sağ alta tamamen başlamasını kontrol edin. Beyaz bir piksel mi? Aldırmamak. Renkli mi? Serin, takip edelim ve sınırlarını belirlemeye çalışalım (sol üst, sağ üst, sol alt, sağ alt).

Bu yapıldıktan sonra, her dikdörtgenin alanını kontrol edin. Dikdörtgenin renginden farklı bir renk içeriyor mu? Ardından o rengin hangi dikdörtgene ait olduğunu bulun ve çakışan dikdörtgenin z dizinini 1 ile güncelleyin.

Ve son olarak, z-endekslerini dikkate alarak tüm dikdörtgenleri çizin. Aslında CSS ve diğer 3B şeylerden bildiğiniz bir z-endeksi gibi çalışır. En düşük z-endeksine sahip dikdörtgenler önce çizilir, en yüksek z-endeksi en son çizilir.

import java.awt.*;import java.awt.image.*;import java.io.File;import java.util.*;import java.util.List;import javax.imageio.*;class A{class R{public Color k=new Color(-1);public int z;public Point a;public Point b;public Point c;public Point d;}public static void main(String[]w)throws Exception{BufferedImage i=ImageIO.read(new File(w[0]));List<R>r=new Vector<R>();for(int y=0;y<i.getHeight();y++){for(int x=0;x<i.getWidth();x++){Color c=new Color(i.getRGB(x,y));if(c.getRGB()==-1){continue;}R t=null;for(R s:r){if(s.k.equals(c)){t=s;}}if(t==null){t=new A().new R();r.add(t);}if(t.a==null){t.a=new Point(x, y);t.b=new Point(x, y);t.c=new Point(x, y);t.d=new Point(x, y);t.k=new Color(c.getRGB());}if(x<t.a.x){t.a.x=x;t.c.x=x;}if(x>t.b.x){t.b.x=x;t.d.x=x;}t.c.y=y;t.d.y=y;}}for(R s:r){List<Color>b=new Vector<Color>();for(int y=s.a.y;y<=s.c.y;y++){for(int x = s.a.x;x<=s.b.x;x++){if(i.getRGB(x, y)!=s.k.getRGB()){Color a=new Color(i.getRGB(x,y));boolean q=false;for(Color l:b){if(l.equals(a)){q=true;}}if(!q){b.add(a);} else {continue;}R f=null;for(R k:r){if(k.k.equals(a)){f=k;}}f.z=s.z+1;}}}}Collections.sort(r,new Comparator<R>(){public int compare(R a, R b){return a.z>b.z?1:(a.z==b.z?0:-1);}});for(int ii=r.size();ii>0;ii--){BufferedImage d=new BufferedImage(i.getWidth(),i.getHeight(),2);Graphics2D g=(Graphics2D)d.getGraphics();for(R s : r.subList(0, ii)){g.setColor(s.k);g.fillRect(s.a.x,s.a.y,s.b.x-s.a.x,s.c.y-s.a.y);}ImageIO.write(d,"png",new File(r.size()-ii+".png"));}}}

Biraz - ve daha açık bir şekilde yazılmış bir ifade ;-) - tam kodu burada bulabilirsiniz: http://pastebin.com/UjxUUXRp

Ayrıca, diyetisyenin teslimini gördüğüme göre, bazı parçaları daha kolay yapabilirdim. Rengi başka bir dikdörtgenin üzerine binen dikdörtgeni bulmak gerçekten gerekli değildir. Gerçekten de 'işgalci' renklerin sayısını sayabiliyordum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.