ความแตกต่างเป็นรูปสี่เหลี่ยมผืนผ้า


20

ในความท้าทายนี้คุณจะได้รับสองรูปสี่เหลี่ยมผืนผ้าที่ทับซ้อนกันและคุณจำเป็นต้องคำนวณรูปสี่เหลี่ยมผืนผ้าที่สร้างขึ้นโดยการลบหนึ่งจากอื่น ๆ

ตัวอย่างเช่นหากคุณลบสี่เหลี่ยมสีแดงออกจากสีดำ:

รูปสี่เหลี่ยม

คุณท้ายด้วยหนึ่งในสองชุดสี่เหลี่ยมต่อไปนี้:

แยกหนึ่ง แยกสอง

คุณจะต้องจัดการสิ่งต่อไปนี้ด้วย:

กรณีทดสอบทั้งหมด

เพื่อให้ชัดเจนยิ่งขึ้น:

  • คุณจะป้อนค่าพิกัดของสองรูปสี่เหลี่ยมผืนผ้า A และ B
  • คุณต้องแสดงผลสี่เหลี่ยมที่ไม่ได้ซ้อนกันน้อยที่สุดซึ่งครอบคลุมพื้นที่ทั้งหมดของ A โดยไม่มี B การอนุญาตใด ๆ ที่เป็นไปได้จะได้รับอนุญาต
  • พิกัดสี่เหลี่ยมถูกส่งผ่านเป็นจำนวนเต็ม 4 ตัว คุณสามารถส่งต่อพวกเขาเป็นสองคู่ (แทนจุดสองมุม) หรือเป็น tuple / list ของจำนวนเต็ม 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 และคุณสามารถสั่งพิกัดในลำดับใดก็ได้ที่คุณต้องการ
Nathan Merrill

ขอบหนาหรือไม่ เมื่อรวมกรอบที่กำหนดไว้จะรวมขอบหรือไม่
ЕвгенийНовиков

ขอบมีความหนา 0
Nathan Merrill

คำตอบ:


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; อีก -15 โดยการเข้ารหัสอาร์เรย์ของวิธีแก้ปัญหาสี่เหลี่ยมในรูปแบบ int36 และตารางการค้นหาสั้น ๆ ; อีก -2 โดยการแทนที่ผลิตภัณฑ์ด้วย p ตาม @musicman

ฟังก์ชั่นที่ใช้สองรูปสี่เหลี่ยมแต่ละรูปสี่เหลี่ยมเป็น tuple ของ ((ซ้าย, บน), (ขวา, ล่าง) ส่งคืนรายการสี่เหลี่ยมที่เกิดขึ้น

กลยุทธ์พื้นฐาน:

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

ในแผนภาพด้านบนจุด A และ B เป็นมุมบนซ้ายและขวาล่างตามลำดับของสี่เหลี่ยมผืนผ้า 'แหล่งที่มา' (rect แรก)

เราพบการวางตำแหน่งของแต่ละมุมบนซ้าย(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,bและL,T,R,Bเป็นซ้ายบนขวาและล่างของสี่เหลี่ยมแหล่งที่มาและมาสก์ตามลำดับ

ดังนั้นเราสามารถสร้างตารางการค้นหาที่แมปพิกัดกับชุดของชุดค่าผสมที่เป็นไปได้ทั้งหมด (ซึ่งเป็นสิ่งที่product(product(*zip(*)))บิตเป็นเรื่องเกี่ยวกับ) กับชุดของรูปสี่เหลี่ยมที่ควรจะมีให้สำหรับแต่ละกรณี (ซึ่งหลังจากการบีบอัดกอล์ฟ สิ่งที่เหลือในรายการคืออะไร)


-15 ไบต์โดยการปรับปรุงการเล่นกอล์ฟต่าง ๆ หรือ-18 ไบต์โดยใช้สตริงใน Python 3
notjagan

คุณสามารถตัดเพิ่มอีกสองไบต์ได้โดยทำp=productและแทนที่product(productด้วยp(p
musicman523

3

จาวาสคริปต์, 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

นี่เป็นวิธีที่มีแนวโน้ม แต่บางครั้งมันล้มเหลวในขณะนี้เช่นเมื่อสี่เหลี่ยม Mask ไม่มีการทับซ้อนกับสี่เหลี่ยมต้นฉบับ เช่น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 ดูดี!
Nathan Merrill

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

Ungolfed

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 ไปยังอีกอันหนึ่ง, และ ORing ผลลัพธ์ หากส่วนอื่นไม่ได้ตัดกัน = 0 ด้วยค่าแรกจะส่งคืนต้นฉบับมิฉะนั้นจะส่งคืนชิ้นส่วนด้านซ้ายชิ้นส่วนด้านขวาชิ้นส่วนบนและชิ้นส่วนล่างบางส่วนพร้อมกันเพื่อให้ทับซ้อนกัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.