删除通畅的矩形


20

该图像是通过将7个不同颜色的矩形彼此叠加而制成的:

主图

黑色和栗色矩形不受阻碍,也就是说,上方没有其他矩形。

编写一个程序,以获取诸如此类的图像并删除任何单个无障碍的矩形,然后输出结果图像。

如果您在上面的图像上运行程序,并在输出上重新运行它,则程序可能会像这样进行。

运行1-黑色被移除(可能是栗色的):

运行1

运行2-栗色已移除(唯一选择):

运行2

运行3-删除黄色(唯一选择):

运行3

运行4-已删除蓝色(本来可以是绿色):

运行4

运行5-移除绿色(唯一选择):

运行5

运行6-移除棕色(唯一选择):

运行6

运行7-移除红色(唯一选择):

运行7

任何其他运行都应产生相同的白色图像。

希望Stack Exchange不会无损地压缩任何这些图像。

图像将始终具有白色背景,并且每个矩形都是唯一的RGB颜色,而不是白色。

您可以假定图像始终可以解释为一组重叠的矩形。具体来说,您可以假定,对于特定颜色,该颜色最接近图像顶部的像素是该颜色矩形的上边缘的一部分。底部,左侧和右侧边缘也是如此。

因此,例如,在此图像中,红色矩形的顶部边缘将恰好在黄色矩形的底部边缘下方,因为橙色矩形覆盖了旧的红色顶部边缘:

例子1

在此图像中,可以先删除红色矩形(以及黑色/栗色/橙色/灰色):

例子2

当下部矩形的顺序不明确时,可以给它们任何顺序。

例如,此处的左侧图像可能变为中间或右侧:

例子3 例子4 例子5

输出不应有矛盾的重叠(因此应该可以使用画家的算法来实现)。因此,在此图像中(感谢user23013),它必须在橙色矩形下为绿色:

例子6

额外细节

  • 图像和矩形可以具有任何尺寸。
  • 矩形可能会触及图像边框。
  • 最多可能有256 3-1 矩形。
  • 如果输入是全白的,则输出也应该是白色。
  • 您可以使用图像库。
  • 输入应该是图像文件名或原始图像数据。它可以来自stdin或命令行。
  • 可以将输出写入相同或另一个图像文件,将原始图像输出到stdout,或简单地显示。
  • 允许使用任何常见的无损Truecolor图像文件格式。

字节最少的提交将获胜。



从技术上讲,要求中没有任何内容表明输出可能没有矛盾的重叠。应该添加它,还是对测试用例的两种解释都可以?
John Dvorak

您能否澄清“真彩色”?
FUZxxl 2015年


@JanDvorak我希望这暗示了,但是,您是对的,目前还不清楚,所以我添加了一条注释。
加尔文的业余爱好

Answers:


10

CJam,241个字节

(删除换行符。)

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文件格式。用法示例(使用ImageMagick):

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

好吧,它太长太慢...在本示例中运行大约一分钟。

我调整了测试用例的大小(并添加了一些其他用例),以简化测试。

似乎颜色空间信息丢失了,因此颜色略有不同。


2

Python中,690个 651 610 606 594 569字节

该脚本从标准输入读取图像名称。

它检测每个矩形的边缘,按它们包含的不同颜色的数量对其进行排序(无障碍的矩形仅包含一种颜色,然后出现在列表的末尾)

此列表用于重绘图像。通过选择列表的排列来决定重绘顺序,该排列将生成与输入的像素差最小的输出图像。

从PIL导入Image作为l,ImageDraw作为D;从ittools import *; O,R,I,Z,k = [],range,l.open(raw_input()),{},lambda x:-x [1 ];(W,H),Q = I.size,I.load()
对于乘积(R(W),R(H))中的i,j:
 c = Q [i,j]
 如果c在Z:x,y,X,Y = Z [c]; Z [c] = [x,y,max(X,i),max(Y,j)]
 else:Z [c] = [i,j,0,0]
对于排列中的n(对于c,(x,y,X,已排序([[(c,len({Q [g] for product in g(R(x,X),R(y,Y))}))) Z.items()中的Y),key = k)[1:-1]):o = l.new(I.mode,I.size,0xFFFFFF); [D.Draw(o).rectangle(Z [c],fill = c)for c,_ in n]; O + = [(o,sum(abs(ab)for t,T in zip(I.getdata(),o.getdata()))for a, b in zip(t,T)))]
max(O,key = k)[0] .show()

0

Java-1483字节

我不是一个出色的打高尔夫球的人,请说清楚。因此冗长不完全是Java的错;-)尽管如此,这似乎是一个非常有趣的挑战。我以某种方式解决了它-我认为-有点无聊和冗长,但是嘿。它的工作原理是(相对)快速,而且特别有趣。

想法如下:从左上角一直到右下角检查每个像素。是白色像素吗?忽视。它是彩色的吗?很酷,让我们跟踪它并尝试确定其边界(左上,右上,左下,右下)。

完成后,检查每个矩形的区域。它包含的颜色是否不同于矩形的颜色?然后找出哪个矩形属于该颜色并将该重叠矩形的z-index更新1。

最后,在考虑z索引的同时绘制所有矩形。实际上,它的工作原理就像您从CSS和其他3D产品中了解的z-index。首先绘制具有最低z索引的矩形,最后绘制最高z索引的矩形。

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"));}}}

完整的代码有点儿-这是一个轻描淡写的;-)-更清晰地写在这里:http : //pastebin.com/UjxUUXRp

另外,既然我看到节食者的意见,我本来可以简化一些部分。确实没有必要找到颜色与另一个矩形重叠的矩形。我确实可以算出“入侵”颜色的数量。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.