Differenza rettangolare


20

In questa sfida, ti vengono dati due rettangoli sovrapposti e devi calcolare i rettangoli creati rimuovendo uno dall'altro.

Ad esempio, se rimuovi il rettangolo rosso da quello nero:

rettangoli

Si finisce con uno dei seguenti due set di rettangoli:

split-uno split-due

Dovrai anche gestire quanto segue:

Tutti i casi di test

Per essere più espliciti:

  • Inserirai le coordinate di due rettangoli, A e B.
  • Devi produrre il minor numero di rettangoli non sovrapposti che coprono tutta l'area di A senza B. È consentito qualsiasi possibile rivestimento
  • Le coordinate rettangolari vengono passate come 4 numeri interi. Puoi passarli in due coppie (che rappresentano i due punti d'angolo) o come una tupla / elenco di 4 numeri interi. I tuoi input e output devono essere coerenti.
  • A e B non si sovrapporranno o toccheranno necessariamente, e ciascuno avrà un'area di almeno 1

Casi test:

[(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

Questo è un , quindi rendi il tuo codice il più breve possibile!



1
possiamo supporre che il dato input sia {(x1, y1), (x2, y2)}valido x1 < x2e y1 < y2?
martedì

Sì. Il rettangolo avrà un'area di 1 e puoi ordinare le coordinate nell'ordine che preferisci.
Nathan Merrill,

Il bordo è spesso? Quando il rettangolo definito è incluso bordo?
Евгений Новиков

Il bordo ha uno spessore di 0.
Nathan Merrill,

Risposte:


3

Python 2 , 375 360 345 343 byte

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]]

Provalo online!

EDIT: -15 dai suggerimenti di @notjagan; un altro -15 ricodificando la matrice di rettangoli di soluzione in formato int36 e una breve tabella di ricerca; un altro -2 sostituendo il prodotto con p come da @musicman.

Una funzione che accetta due rettangoli, ognuno dei quali è una tupla di ((a sinistra, in alto), (a destra, in basso)); restituisce un elenco dei rettangoli risultanti.

La strategia di base:

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

Nel diagramma sopra, i punti A e B sono rispettivamente in alto a sinistra e in basso a destra del rettangolo "Sorgente" (il primo rettangolo).

Troviamo il posizionamento di ciascuno dei rettangoli in alto a sinistra (u,v)e in basso a destra (x,y)del rettangolo "Maschera" in quella griglia.

Se entrambi questi punti si trovano nella prima o nell'ultima colonna; o prima o ultima riga; quindi non c'è sovrapposizione; e possiamo restituire solo il retto Sorgente.

Altrimenti, rimangono 16 casi; ad esempio, il primo esempio del PO è il caso che possiamo etichettare (1,1),(2,2). Ogni caso può essere mappato su una serie di rettangoli risultanti i cui angoli sono sempre coordinate con valori orizzontali nei rettangoli Origine a sinistra, a destra o nei rettangoli Maschera a sinistra, a destra; e allo stesso modo per i valori verticali, la parte superiore, inferiore o le maschere della Sorgente.

Ad esempio, per il (1,1),(2,2)caso, i rettangoli sarebbero ((l,t),(T,r))e ((l,T),(R,b)), dove l,t,r,be L,T,R,Bsono rispettivamente i lati sinistro, superiore, destro e inferiore dei rettangoli Origine e Maschera.

Quindi possiamo creare una tabella di ricerca che associ le coordinate all'insieme di tutte queste possibili combinazioni (che è ciò di cui tratta il product(product(*zip(*)))bit) a un insieme di rettangoli che dovrebbero essere forniti per ciascuno dei casi (che, dopo qualche decompressione da golfy , è ciò di cui parla il resto della lista).


-15 byte apportando vari miglioramenti al golf, o -18 byte usando le stringhe in Python 3.
notjagan

Puoi tagliare altri due byte eseguendo p=producte sostituendo product(productconp(p
musicman523

3

JavaScript, 115 byte

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)

versione sovrapposta:

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)

Inserisci nel seguente formato: f([1,1,8,8])([0,6,9,9])


Indica input come ((x1, y1), (x2, y2)), ((x3, y3), (x4, y4))

Se si verifica una delle seguenti condizioni, restituire il primo rettangolo così com'è:

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

altrimenti

  • Se x1 <x3 <x2 generiamo un rettangolo ((x1, y1), (x3, y2)); e imposta x1: = x3
  • Se x1 <x4 <x2 generiamo un rettangolo ((x4, y1), (x2, y2)); e imposta x2: = x4
  • Se y1 <y3 <y2 generiamo un rettangolo ((x1, y1), (x2, y3)); e imposta y1: = y3
  • Se y1 <y4 <y2 generiamo un rettangolo ((x1, y4), (x2, y2)); e imposta y2: = y4

Questo è un approccio promettente; ma al momento non riesce a volte, ad esempio, quando il rettangolo Maschera non si sovrappone al rettangolo Sorgente; ad esempio f([0, 30, 10, 40])([5, 1, 6, 2])dovrebbe tornare [[0, 30, 10, 40]]ma invece ritorna[[0,30,5,40],[6,30,10,40]]
Chas Brown

@NathanMerrill ok, modificato.
TSH

@tsh sembra buono!
Nathan Merrill,

1

Java, 268 byte

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

Passa input come argomenti. Esempio

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

0

Python 2 , 272 byte

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]

Provalo online!

Funziona testando ogni cella all'interno del primo rettangolo per leftness = 1, aboveness = 4, rightness = 2 e belowness = 8 w / r rispetto all'altro, e ORing il risultato. Se l'altro non si interseca = 0 con il primo, viene restituito l'originale, altrimenti viene restituita una combinazione di una porzione sinistra, una porzione destra, una parte superiore e una parte inferiore, con spazio per la sovrapposizione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.