矩形差


20

この課題では、2つの重複する長方形が与えられ、一方を他方から削除して作成された長方形を計算する必要があります。

たとえば、黒い長方形から赤い長方形を削除する場合:

長方形

次の2つの長方形セットのいずれかになります。

スプリットワン スプリットツー

また、以下を処理する必要があります。

すべてのテストケース

より明確にするには:

  • AとBの2つの長方形の座標を入力します。
  • Bを除くAのすべての領域をカバーする、重複しない最小の長方形を出力する必要があります。可能なカバーは許可されています
  • 直交座標は4つの整数として渡されます。2つのペア(2つのコーナーポイントを表す)で、または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 < x2と仮定できy1 < y2ますか?
-tsh

うん。長方形の面積は1になり、座標は好きな順序で並べることができます。
ネイサンメリル

エッジは厚いですか?定義された長方形がエッジを含む場合
ЕвгенийНовиков

エッジの厚さは0です。
ネイサンメリル

回答:


3

Pythonの2375の 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]]

オンラインでお試しください!

編集:@notjaganからの提案から-15。別の-15は、ソリューション四角形の配列をint36形式に再エンコードし、短いルックアップテーブルを作成します。もう1つは、@ musicmanに従ってproductをpに置き換えることです。

それぞれの長方形が((left、top)、(right、bottom))のタプルである2つの長方形を取る関数。結果の長方形のリストを返します。

基本戦略:

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

上記の図では、ポイントAとBは、それぞれ「ソース」長方形(最初の長方形)の左上と右下です。

そのグリッドの「マスク」長方形の左上(u,v)と右下のそれぞれの配置を見つけます(x,y)

これらのポイントが両方とも最初または最後の列にある場合。または最初または最後の行。重複はありません。Source rectのみを返すことができます。

それ以外の場合、16のケースが残ります。たとえば、OPの最初の例は、labelを使用できる場合です(1,1),(2,2)。各ケースは、結果の長方形のセットにマップできます。その長方形のコーナーは、ソースの長方形left、right、またはMaskの長方形left、rightのいずれかの水平値と常に座標です。同様に、垂直値、ソースの上部、下部、またはマスクについても同様です。

例えば、ため(1,1),(2,2)場合、矩形があろう((l,t),(T,r))((l,T),(R,b))、場合l,t,r,bL,T,R,B左、上、右、およびソースの底部であり、それぞれ、矩形マスク。

したがって、すべての可能な組み合わせのセット(product(product(*zip(*)))ビットの意味)に座標をマッピングするルックアップテーブルを作成できます。、リストの残りの部分についてです)。


さまざまなゴルフの改善により-15バイト、またはPython 3で文字列を使用して-18バイト
–notjagan

次の操作を行うことにより、さらに2つのバイトオフ切り取ることができますp=productし、交換product(productしてp(p
musicman523

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 OK、編集。
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、およびbelowness = 8 w / rの最初の四角形内のすべてのセルをテストし、結果をORすることによって機能します。他方が最初と交差しない場合= 0で、元のオブジェクトが返されます。それ以外の場合、左のスライス、右のスライス、上のスライス、下のスライスの組み合わせが返されます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.