矩形差


20

在此挑战中,您将获得两个重叠的矩形,并且需要计算通过从另一个中删除一个而创建的矩形。

例如,如果您从黑色矩形中删除红色矩形:

矩形

您最终得到以下两个矩形集之一:

分体式 二分

您还需要处理以下内容:

所有测试用例

更明确地说:

  • 您将输入两个矩形A和B的坐标。
  • 您需要输出覆盖A的所有区域而没有B的最少的非重叠矩形。允许任何可能的覆盖
  • 直角坐标作为4个整数传递。您可以将它们传递为两对(代表两个角点),也可以作为4个整数的元组/列表传递。您的输入和输出必须保持一致。
  • A和B不一定会重叠或接触,并且各自的面积至少为1

测试用例:

[(0 0) (5 5)] [(3 4) (8 7)]   -> [(0 0) (5 4)] [(0 4) (3 5)] # or [(0 0) (3 5)] [(3 0) (5 4)]
[(2 4) (10 11)] [(5 5) (6 6)]  -> [(2 4) (10 5)] [(2 5) (5 6)] [(6 5) (10 6)] [(2 6) (10 11)]    #Other sets of 4 rectangles are possible
[(3 3) (8 8)] [(0 1) (10 8)]   ->    #No rectangles should be output
[(0 0) (5 5)] [(1 1) (10 2)]   -> [(0 0) (1 5)] [(1 0) (2 1)] [(2 0) (5 5)]  #Other sets of 3 rectangles are possible
[(1 5) (7 8)] [(0 0) (1 10)]   -> [(1 5) (7 8)]  #Only possible output
[(4 1) (10 9)] [(2 5) (20 7)]   -> [(4 1) (10 5)] [(4 7) (10 9)]  #Only possible output
[(1 1) (8 8)] [(0 6) (9 9)]     -> [(1 1) (8 6)]   #Only possible output

这是一个,所以请使代码尽可能短!



1
我们可以假设给定的输入{(x1, y1), (x2, y2)}持有x1 < x2y1 < y2
tsh

是的 矩形的面积为1,您可以按照自己喜欢的顺序对坐标进行排序。
内森·美林

边缘厚吗?定义的矩形何时包括边缘?
ЕвгенийНовиков

边缘的厚度为0。
弥敦道·美林

Answers:


3

Python 2中375个 360 345 343字节

from itertools import*;P=product
def f(S,M):(l,t),(r,b)=S;(L,T),(R,B)=M;u,v,x,y=(L>=r)+(l<L),(T>=b)+(t<T),(R>=r)+(l<R),(B>=b)+(t<B);return[S]if v==y!=1or u==x!=1else[list(p(p(*zip(*(S+M))),repeat=2))[[43,197,6,199,9,231,142,229,53,189,134,181][int(i,36)]]for i in '38,491,258,2058,8,4B,28,208,7,41,27,461,,4,2,4A'.split(',')[u+2*v+4*x+8*y-12]]

在线尝试!

编辑:-15来自@notjagan的建议;通过将解决方案矩形数组重新编码为int36格式和简短的查找表,再进行-15;通过@musicman用p替换乘积来获得-2。

一个带有两个矩形的函数,每个矩形是((left,top),(right,bottom));的元组;返回结果矩形的列表。

基本策略:

     |     |
 0,0 | 1,0 | 2,0
-----A-----+-----
     |     |
 0,1 | 1,1 | 2,1
-----+-----B-----
     |     |
 0,2 | 1,2 | 2,2
     |     |

在上图中,点A和B分别是“源”矩形(第一个矩形)的左上和右下。

我们在该网格中找到了“ Mask”矩形的左上(u,v)和右下的每个位置(x,y)

如果这两个点都在第一列或最后一列中;或第一行或最后一行;那么就没有重叠;我们可以只返回Source rect。

否则,还有16个案件。例如,OP的第一个示例就是我们可以标记的情况(1,1),(2,2)。每种情况都可以映射到一组结果矩形,这些矩形的角始终与源矩形左,右或蒙版矩形左,右的水平值进行坐标匹配;同样,对于垂直值,源的顶部,底部或遮罩。

例如,对于这种(1,1),(2,2)情况,矩形将是((l,t),(T,r))((l,T),(R,b)),其中l,t,r,bL,T,R,B分别是Source和Mask矩形的左,上,右和下。

因此,我们可以创建一个查找表,将坐标映射到所有此类可能组合的集合(这就是product(product(*zip(*)))位数),将其映射到应为每种情况提供的一组矩形(在进行某些高尔夫球减压之后) ,就是列表的其余内容。


通过进行各种高尔夫改进来减少-15个字节,或者使用Python 3中的字符串来减少-18个字节
。– notjagan

您可以通过执行以下操作来p=product替换另外两个字节,并将其替换product(productp(p
musicman523 '17

3

JavaScript,115字节

f=a=>b=>b.some((n,i)=>(a[i^2]<n)^i/2)?[a]:b.map((n,i)=>a[i&1]<n&&n<a[i|2]&&(p=[...a],p[i^2]=a[i]=n,p)).filter(x=>x)

重叠版本:

f=a=>b=>b.some((n,i)=>(a[i^2]<n)^i/2)?[a]:b.map((n,i)=>a[i&1]<n&&n<a[i|2]&&(p=[...a],p[i^2]=n,p)).filter(x=>x)

输入以下格式: f([1,1,8,8])([0,6,9,9])


将输入表示为((x1,y1),(x2,y2)),((x3,y3),(x4,y4))

如果满足以下任一条件,则按原样返回第一个矩形:

  • x3> x2
  • x4 <x1
  • y3> y2
  • y4 <y1

除此以外

  • 如果x1 <x3 <x2然后我们生成一个矩形((x1,y1),(x3,y2)); 并设置x1:= x3
  • 如果x1 <x4 <x2然后我们生成一个矩形((x4,y1),(x2,y2)); 并设置x2:= x4
  • 如果y1 <y3 <y2,则我们生成一个矩形((x1,y1),(x2,y3)); 并设置y1:= y3
  • 如果y1 <y4 <y2,则我们生成一个矩形((x1,y4),(x2,y2)); 并设置y2:= y4

这是一种很有前途的方法;但是它当前有时会失败,例如,当“遮罩”矩形与“源”矩形不重叠时;例如,f([0, 30, 10, 40])([5, 1, 6, 2])应该返回[[0, 30, 10, 40]]但返回[[0,30,5,40],[6,30,10,40]]
Chas Brown

@NathanMerrill好,已编辑。
tsh

@tsh看起来不错!
弥敦道·美林

1

Java,268个字节

class W{public static void main(String[]z) {int a[]={0,0,0,0},i,j,y[]={0,1,4,3,6,1,2,3,4,1,6,5,4,7,6,3};for(i=0;i<4;i+=1){for(j=0;j<4;j+=1){a[j]=Integer.parseInt(z[y[i*4+j]]);}if(a[0]<a[2] && a[1]<a[3]){for(j=0;j<4;j+=1){System.out.println(String.valueOf(a[j]));}}}}}

不打高尔夫球

class W{
    public static void main(String[]z) {
        int a[]={0,0,0,0},i,j,y[]={0,1,4,3,6,1,2,3,4,1,6,5,4,7,6,3};

        for(i=0;i<4;i+=1){
            for(j=0;j<4;j+=1){
                a[j]=Integer.parseInt(z[y[i*4+j]]);
            }
            if(a[0]<a[2] && a[1]<a[3]){
                for(j=0;j<4;j+=1){
                    System.out.println(String.valueOf(a[j]));
                }
            }
        }
    }
}

将输入作为参数传递。例

java -jar W.jar 0 0 5 5 3 4 8 7

0

Python 2,272字节

lambda((a,b),(c,d)),((e,f),(g,h)):[([([[(a,b),(e,min(h,d))]]+[[(g,max(b,f)),(c,d)]]*2+[[(max(a,e),b),(c,f)]]*4+[[(a,h),(min(c,g),d)]])[m-1]for m in M&{1,2,4,8}]if M&{0}else[(a,b),(c,d)])for M in[{(x<e)*1+(x>g)*2+(y<f)*4+(y>h)*8 for x in range(a,c)for y in range(b,d)}]][0]

在线尝试!

这通过测试第一个矩形内的每个像元的leftness = 1,aboveness = 4,rightness = 2和underness = 8 w / r,然后对结果进行或运算来工作。如果另一个与第一个不相交= 0,则返回原始图像,否则返回左切片,右切片,上切片和下切片的某种组合,并提供重叠部分。

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.