Différence rectangulaire


20

Dans ce défi, vous obtenez deux rectangles qui se chevauchent et vous devez calculer les rectangles créés en supprimant l'un de l'autre.

Par exemple, si vous supprimez le rectangle rouge du noir:

rectangles

Vous vous retrouvez avec l'un des deux ensembles de rectangle suivants:

split-one split-deux

Vous devrez également gérer les éléments suivants:

Tous les cas de test

Pour être plus explicite:

  • Vous entrerez les coordonnées de deux rectangles, A et B.
  • Vous devez sortir le moins de rectangles non superposés qui couvrent toute la zone de A sans B. Tout recouvrement possible est autorisé
  • Les coordonnées rectangulaires sont transmises sous forme de 4 entiers. Vous pouvez les passer en deux paires (représentant les deux points d'angle), ou en tant que tuple / liste de 4 entiers. Vos entrées et sorties doivent être cohérentes.
  • A et B ne se chevaucheront pas ou ne se toucheront pas nécessairement, et chacun aura une zone d'au moins 1

Cas de 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

C'est un , alors faites votre code le plus court possible!



1
pouvons-nous supposer que l'entrée donnée est {(x1, y1), (x2, y2)}vraie x1 < x2et y1 < y2?
tsh

Oui. Le rectangle aura une zone de 1, et vous pouvez ordonner les coordonnées dans l'ordre que vous souhaitez.
Nathan Merrill

Le bord est-il épais? Lorsque le rectangle est défini, le bord est-il inclus?
Евгений Новиков

Le bord a 0 épaisseur.
Nathan Merrill

Réponses:


3

Python 2 , 375 360 345 343 octets

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

Essayez-le en ligne!

MODIFICATIONS: -15 à partir des suggestions de @notjagan; un autre -15 en ré-encodant le tableau de rectangles de solution au format int36 et une courte table de recherche; un autre -2 en remplaçant le produit par p selon @musicman.

Une fonction qui prend deux rectangles, chaque rect étant un tuple de ((gauche, haut), (droite, bas)); renvoie une liste des rectangles résultants.

La stratégie de base:

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

Dans le diagramme ci-dessus, les points A et B sont respectivement en haut à gauche et en bas à droite du rectangle «Source» (le premier rect).

Nous trouvons le placement de chacun des coins supérieur gauche (u,v)et inférieur droit (x,y)du rectangle «Masque» dans cette grille.

Si ces deux points sont dans la première ou la dernière colonne; ou première ou dernière ligne; alors il n'y a pas de chevauchement; et nous pouvons retourner juste le rect Source.

Sinon, il reste 16 cas; par exemple, le premier exemple du PO est le cas que nous pouvons étiqueter (1,1),(2,2). Chaque cas peut être mappé à un ensemble de rectangles résultants dont les coins sont toujours des coordonnées avec des valeurs horizontales dans les rectangles source gauche, droite ou les rectangles Masque gauche, droite; et de même pour les valeurs verticales, le haut, le bas ou les masques de la source.

Par exemple, pour le (1,1),(2,2)cas, les rectangles seraient ((l,t),(T,r))et ((l,T),(R,b)), où l,t,r,bet L,T,R,Bsont respectivement à gauche, en haut, à droite et en bas des rectangles Source et Masque.

Nous pouvons donc créer une table de recherche qui mappe les coordonnées à l'ensemble de toutes ces combinaisons possibles (ce qui est le product(product(*zip(*)))bit) à un ensemble de rectangles qui devraient être fournis pour chacun des cas (qui, après une décompression de golf , c'est de cela que traite le reste de la liste).


-15 octets en apportant diverses améliorations au golf, ou -18 octets en utilisant des chaînes en Python 3.
notjagan

Vous pouvez couper deux octets supplémentaires en faisant p=productet en remplaçant product(productparp(p
musicman523

3

JavaScript, 115 octets

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)

version qui se chevauchent:

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)

Entrée au format suivant: f([1,1,8,8])([0,6,9,9])


Indique l'entrée comme ((x1, y1), (x2, y2)), ((x3, y3), (x4, y4))

Si l'une des conditions suivantes est remplie, retournez le premier rectangle tel quel:

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

autrement

  • Si x1 <x3 <x2 alors nous générons un rectangle ((x1, y1), (x3, y2)); et définissez x1: = x3
  • Si x1 <x4 <x2 alors nous générons un rectangle ((x4, y1), (x2, y2)); et définissez x2: = x4
  • Si y1 <y3 <y2 alors nous générons un rectangle ((x1, y1), (x2, y3)); et définissez y1: = y3
  • Si y1 <y4 <y2 alors nous générons un rectangle ((x1, y4), (x2, y2)); et définissez y2: = y4

Il s'agit d'une approche prometteuse; mais il échoue actuellement parfois, par exemple, lorsque le rectangle de masque n'a pas de chevauchement avec le rectangle source; par exemple f([0, 30, 10, 40])([5, 1, 6, 2])devrait revenir [[0, 30, 10, 40]]mais revient à la place[[0,30,5,40],[6,30,10,40]]
Chas Brown

@NathanMerrill ok, édité.
tsh

@tsh a l'air bien!
Nathan Merrill

1

Java, 268 octets

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

Non golfé

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

Passez l'entrée comme arguments. Exemple

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

0

Python 2 , 272 octets

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]

Essayez-le en ligne!

Cela fonctionne en testant chaque cellule à l'intérieur du premier rectangle pour la gaucherie = 1, l'aboveness = 4, la rectitude = 2 et la belowness = 8 w / r à l'autre, et OU le résultat. Si l'autre ne coupe pas = 0 avec le premier, l'original est renvoyé, sinon une combinaison d'une tranche gauche, d'une tranche droite, d'une tranche supérieure et d'une tranche inférieure est renvoyée, avec possibilité de chevauchement.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.