Coprire una regione con rettangoli


22

Ingresso

Il tuo contributo in questa sfida è un elenco di coppie di numeri interi. Rappresentano gli angoli sud-ovest dei quadrati delle unità sul piano e l'elenco rappresenta la loro unione come sottoinsieme del piano. Ad esempio, l'elenco

[(0,0),(1,0),(0,1),(1,1),(2,1),(1,2),(2,2)]

rappresenta il set di colore rosso in questa immagine:

Un dominio

Produzione

Il tuo output è un elenco di quadrupli interi, che rappresentano sottoinsiemi rettangolari del piano. Più esplicitamente, una quadrupla (x,y,w,h)presenta un rettangolo di larghezza w > 0e altezza il h > 0cui angolo sud-ovest è a (x,y). I rettangoli devono formare una copertura esatta della regione di input, nel senso che ciascuno dei quadrati delle unità è un sottoinsieme di alcuni rettangoli, ogni rettangolo è un sottoinsieme della regione e due rettangoli possono sovrapporsi solo ai bordi. Per vietare soluzioni banali, il rivestimento non deve contenere due rettangoli che potrebbero essere uniti in un rettangolo più grande.

Ad esempio, l'elenco

[(0,0,2,1),(0,1,3,1),(1,2,2,1)]

rappresenta la copertura legale

Una copertura legale

della regione sopra, mentre la copertura data da

[(0,0,2,2),(2,1,1,1),(1,2,1,1),(2,2,1,1)]

è illegale, poiché i quadrati 1 per 1 adiacenti potrebbero essere uniti:

Una copertura illegale

Regole

Puoi dare un programma completo o una funzione. La formattazione precisa dell'input e dell'output non è importante, entro limiti ragionevoli. Vince il conteggio dei byte più corto e le scappatoie standard non sono ammesse. Siete incoraggiati a fornire una spiegazione del vostro algoritmo e alcuni esempi di output.

Casi test

Una regione a forma di U:

[(0,0),(0,1),(0,2),(0,3),(0,4),(0,5),(1,0),(1,1),(1,2),(1,3),(1,4),(1,5),(2,0),(2,1),(3,0),(3,1),(4,0),(4,1),(4,2),(4,3),(4,4),(4,5),(5,0),(5,1),(5,2),(5,3),(5,4),(5,5)]

U

Un grande triangolo:

[(0,0),(0,1),(0,2),(0,3),(0,4),(0,5),(0,6),(0,7),(0,8),(0,9),(1,0),(1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(1,8),(2,0),(2,1),(2,2),(2,3),(2,4),(2,5),(2,6),(2,7),(3,0),(3,1),(3,2),(3,3),(3,4),(3,5),(3,6),(4,0),(4,1),(4,2),(4,3),(4,4),(4,5),(5,0),(5,1),(5,2),(5,3),(5,4),(6,0),(6,1),(6,2),(6,3),(7,0),(7,1),(7,2),(8,0),(8,1),(9,0)]

Triangolo

Un quadrato con buchi:

[(0,0),(0,1),(0,2),(0,3),(0,4),(0,5),(0,6),(0,7),(0,8),(1,0),(1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(1,8),(1,9),(2,0),(2,1),(2,2),(2,3),(2,4),(2,5),(2,6),(2,7),(2,8),(2,9),(3,0),(3,1),(3,2),(3,4),(3,5),(3,6),(3,7),(3,8),(3,9),(4,0),(4,1),(4,2),(4,3),(4,4),(4,5),(4,6),(4,7),(4,8),(4,9),(5,0),(5,1),(5,2),(5,3),(5,4),(5,5),(5,7),(5,8),(5,9),(6,1),(6,2),(6,3),(6,5),(6,6),(6,7),(6,8),(6,9),(7,0),(7,1),(7,2),(7,3),(7,4),(7,5),(7,6),(7,7),(7,8),(7,9),(8,0),(8,1),(8,2),(8,3),(8,4),(8,5),(8,6),(8,7),(8,8),(8,9),(9,0),(9,1),(9,2),(9,3),(9,4),(9,5),(9,6),(9,7),(9,8),(9,9)]

Piazza forata

Regioni disconnesse:

[(0,0),(0,1),(0,2),(0,3),(0,4),(0,5),(0,6),(0,7),(0,8),(1,0),(1,1),(1,2),(1,3),(1,4),(1,6),(1,7),(1,8),(1,9),(2,1),(2,2),(2,3),(2,4),(2,5),(2,6),(2,7),(2,8),(2,9),(4,0),(4,1),(4,2),(4,4),(4,5),(4,6),(4,7),(4,8),(4,9),(5,0),(5,1),(5,2),(5,3),(5,4),(5,5),(5,6),(5,7),(5,8),(5,9),(6,0),(6,1),(6,2),(6,4),(6,5),(6,6),(6,7),(6,8),(6,9),(8,0),(8,1),(8,2),(8,3),(8,4),(8,5),(8,6),(8,7),(8,8),(8,9),(9,0),(9,1),(9,2),(9,3),(9,7),(9,8),(9,9),(10,0),(10,1),(10,2),(10,3),(10,4),(10,5),(10,6),(10,7),(10,8),(10,9)]

Disconnected

Verifier

Utilizzare questo programma Python 2 per verificare la soluzione. Prende da STDIN un elenco di tuple (input) e un elenco di quadruple (output), separati da una virgola.

Ho anche scritto questo programma Python 2 per generare le immagini e puoi anche usarlo. Prende da STDIN un elenco di tuple o quadruple e produce un file denominato out.png. Richiede la libreria PIL. Se lo desideri, puoi modificare anche le dimensioni delle celle della griglia e anche la larghezza delle linee della griglia.

Risposte:


12

Python: 196 193 182 caratteri

def g(r):
 for p in r:
  for q in r:
   for h in 0,1:
    if p[h::2]==q[h::2]and p[1-h]+p[~h]==q[1-h]:p[~h]+=q[~h];r.remove(q);return g(r)
 return r
f=lambda P:g([x+[1,1]for x in P])

La mia prima soluzione ha usato lo stesso algoritmo di KSFT, quindi ho sperimentato altri metodi.

Prima faccio un po 'di preelaborazione, converto tutti i punti in piccoli rettangoli 1x1 {x+(1,1)for x in P}. Con questi rettangoli, chiamo la funzione g. gscorre ogni combinazione di rettangoli. Se trova 2 rettangoli, che possono essere uniti in uno più grande, cancella entrambi e aggiunge quello nuovo. Successivamente si chiama con il nuovo set di rettangoli.

uso

f([[0,0],[1,0],[0,1],[1,1],[2,1],[1,2],[2,2]])

risultati

Ecco la visualizzazione dei risultati. Si noti che potrebbero essere leggermente diversi nella versione corrente. L'idea è però che non esiste alcun tipo di modello evidente.

Una regione a forma di U:

Un grande triangolo

Un quadrato con buchi:

Regioni disconnesse:

Solo per divertimento: Pyth: 73 69 caratteri

D!HFGHFZHV2I&q%2>GN%2>ZNqs%2>G-1N@Z-1N X-3NG@Z-3NR!-H]Z)))RH!m+d*2]1Q

Funziona solo nella versione offline. Il bug nella versione online è stato corretto ora. Provalo qui: Pyth Compiler / Executor . Si aspetta un elenco di elenchi, non un elenco di tuple.

edit: Ho usato un'idea di @ edc65: Invece di cancellare entrambi i rettangoli e crearne uno nuovo, ne manipolo uno e ne elimino solo uno. Nella soluzione Python ho potuto cavalcare i set e i cast di tuple-list-tuple. -11 caratteri in Python / -4 caratteri in Pyth


2
Python3: le faccine ora sono codice valido.
flawr

Potrei sbagliarmi, ma penso che tu possa cambiare 3-hin ~h?
Sp3000,

Accettato per la versione Pyth.
Zgarb,

14

Pitone - 272 261 258 251 224

Penso di poter giocare a golf di più. Sono abbastanza sicuro che funzioni, ma non ho ancora finito di testarlo su tutti i casi di test. Ho finito di provarlo. Funziona con tutti i casi di test.

a=sorted(input())
b=[]
r=range
for i in a:
 c=set(a)-set(b);w=h=1;x,y=i
 if i in b:continue
 while not{(x,y+h)}-c:h+=1
 while all((x+w,y+j)in c for j in r(h)):w+=1
 for j in r(w):
  for k in r(h):b+=(j+x,k+y),
 print x,y,w,h

Sto lavorando per aggiungere immagini dei risultati. Modifica: ecco i risultati dell'esempio e i casi di test:

Esempio di output Uscita del caso di test 1 Uscita test case 2 Test case 3 output Test case 4 output

Sto cercando di scrivere questo in Perl, ma non riesco a capire come ottenere array multidimensionali da stdin senza un numero enorme di personaggi. Qualcuno ha qualche suggerimento?


Due cose: (i[0]+w,i[1]+j)not in cper {(i[0]+w,i[1]+j)}-ce si può passare w=h=1alla c=set(a)-set(b)linea
SP3000

Qualche altro in più: b+=[(j+i[0],k+i[1])]a b+=(j+i[0],k+i[1]),e lo usi rangetre volte, quindi è più breve da assegnarer=range
Sp3000,

Inoltre non sono sicuro, ma è possibile fare x,y=iquindi utilizzando xe yinvece di i[0]e i[1]? Ciò consentirebbe di risparmiare molti byte.
Sp3000,

Non l'ho provato, ma penso che funzioni: invece di while not[j for j in r(h)if(x+w,y+j)not in c]:w+=1usare while all((x+w,y+j)in c for j in r(h)):w+=1.
Jakube,

@ Sp3000 / Jakube Ho usato tutti i tuoi suggerimenti.
KSFT,

8

Python 2, 139

Il programma accetta liste di coppie ordinate circondate da parentesi graffe su input standard. Per esempio,{(0,0),(1,0),(0,1),(1,1),(2,1),(1,2),(2,2)}

s=input()
while s:x,y=min(s);w=h=0;exec"while(x+w,y)in s:w+=1\nwhile%s<=s:s-=%s;h+=1"%(("{(X,y+h)for X in range(x,x+w)}",)*2);print x,y,w,h

È spesso irritante (non solo nel golf) che Python non consenta un incarico all'interno di un test ad anello. Per ovviare a questo, ho usato le operazioni di formattazione delle stringhe.


È impressionante. Lo stesso algoritmo di KSFT, "solo" 85 (!!!) caratteri più brevi.
Jakube,

5

Mathematica - 315285 267 byte

f=(r={};For[m=MemberQ;t=Table;s=Sort@#,s!={},For[{x,y,w,h}=#~Join~{1,1}&@@s;i=j=0,i<1||j<1,If[s~m~{x+w,y+a-1}~t~{a,h}==True~t~{h},w++,i++];If[s~m~{x+a-1,y+h}~t~{a,w}==True~t~{w},h++,j++]];s=s~Cases~_?(!m[Join@@t[{x+a,y+b}-1,{a,w},{b,h}],#]&);r~AppendTo~{x,y,w,h}];r)&

Con l'aiuto di @ MartinBüttner.

Ungolfed:

f = (
    rectangles = {};
    For[squares = Sort[#], squares != {},
        For[{x, y, w, h} = Join[squares[[1]], {1, 1}]; i = j = 0, i < 1 || j < 1,
            If[Table[MemberQ[squares, {x + w, y + a - 1}], {a, h}] == Table[True, {h}], w++, i++];
            If[Table[MemberQ[squares, {x + a - 1, y + h}], {a, w}] == Table[True, {w}], h++, j++];
        ];
        squares = Cases[squares, _ ? (!MemberQ[Join@@Table[{x + a - 1, y + b - 1}, {a, w}, {b, h}], #] &)];
        AppendTo[rectangles, {x, y, w, h}]
    ];
    rectangles
)&

Uso:

In: f @ {{0,0},{1,0},{0,1},{1,1},{2,1},{1,2},{2,2}}
Out: {{0, 0, 2, 2}, {1, 2, 2, 1}, {2, 1, 1, 1}}

inserisci qui la descrizione dell'immagine

Casi test

Una regione a forma di U.

inserisci qui la descrizione dell'immagine

{{0, 0, 6, 2}, {0, 2, 2, 4}, {4, 2, 2, 4}}

Un grande triangolo

inserisci qui la descrizione dell'immagine

{{0, 0, 6, 5}, {0, 5, 3, 3}, {0, 8, 2, 1}, {0, 9, 1, 1}, {3, 5, 2, 1}, {3, 6, 1, 1}, {6, 0, 3, 2}, {6, 2, 2, 1}, {6, 3, 1, 1}, {9, 0, 1, 1}}

Un quadrato con buchi

inserisci qui la descrizione dell'immagine

{{0, 0, 6, 3}, {0, 3, 3, 6}, {1, 9, 9, 1}, {3, 4, 3, 2}, {3, 6, 2, 3}, {4, 3, 6, 1}, {5, 7, 5, 2}, {6, 1, 4, 2}, {6, 5, 4, 2}, {7, 0, 3, 1}, {7, 4, 3, 1}}

Regioni disconnesse

inserisci qui la descrizione dell'immagine

{{0, 0, 2, 5}, {0, 5, 1, 4}, {1, 6, 2, 4}, {2, 1, 1, 5}, {4, 0, 3, 3}, {4, 4, 3, 6}, {5, 3, 1, 1}, {8, 0, 3, 4}, {8, 4, 1, 6}, {9, 7, 2, 3}, {10, 4, 1, 3}}

4

Haskell, 158

f[]=[]
f s@((x,y):_)=(x,y,w-x,h-y):f[r|r@(a,b)<-s,a<x||a>=w||b<y||b>=h]where w=[i|i<-[x..],notElem(i,y)s]!!0;h=[i|i<-[y..],not$all(\x->elem(x,i)s)[x..w-1]]!!0

casi di test e immagini saranno qui a breve.

Algoritmo: prendi la prima piazza. Raggiungi l'estrema destra senza incontrare un quadrato non nell'input. Quindi raggiungere il più in alto possibile senza avere un quadrato non sull'ingresso. Ora abbiamo un rettangolo senza un quadrato mancante. Aggiungilo all'output, rimuovi tutti i suoi quadrati dall'input e chiama in modo ricorsivo.


È possibile salvare 1 byte sostituendolo not$all(\x->elem(x,i)s)con any(\x->notElem(x,i)s).
nimi,

4

JavaScript (ES6) 148 155 199

Edit2 Qualche altro tuning
Modifica Alcuni golf + riscrivi usando la ricorsione. Non mi aspettavo una tale riduzione. Ora è un po 'difficile da seguire, ma l'algoritmo è lo stesso.

L'algoritmo è simile alla risposta @jakube.

  1. Ogni punto diventa un quadrato 1x1 (preelaborazione)
  2. Per ogni elemento, controlla se può essere unito con un altro
    Sì? Il primo elemento cresce, il secondo elemento viene cancellato, ricomincia dal passaggio 2
    Altrimenti, passa all'elemento successivo
F=l=>
  (l.map(x=>x.push(1,1)),R=f=>
    l.some(u=>
      (l=l.filter(t=>
        [0,1].every(p=>u[p]-t[p]|u[p^=2]-t[p]|u[p^=3]-t[p]+u[p^=2]||!(f=u[p]+=t[p]))
      ),f)
    )?R():l
  )()

Test in snippet

F=l=>(l.map(x=>x.push(1,1)),R=f=>l.some(u=>(l=l.filter(t=>[0,1].every(p=>u[p]-t[p]|u[p^=2]-t[p]|u[p^=3]-t[p]+u[p^=2]||!(f=u[p]+=t[p]))),f))?R():l)()

// Test
MyCanvas.width= 600;
MyCanvas.height = 220;
var ctx = MyCanvas.getContext("2d");
ctx.fillStyle="#f23";

Draw=(x,y,f,l)=>l.forEach(p=>ctx.fillRect(x+p[0]*f,y+p[1]*f,p[2]*f-1||f-1,p[3]*f-1||f-1));

test=[
[[0,0],[1,0],[0,1],[1,1],[2,1],[1,2],[2,2]],
[[0,0],[0,1],[0,2],[0,3],[0,4],[0,5],[1,0],[1,1],[1,2],[1,3],[1,4],[1,5],[2,0],[2,1],[3,0],[3,1],[4,0],[4,1],[4,2],[4,3],[4,4],[4,5],[5,0],[5,1],[5,2],[5,3],[5,4],[5,5]],
[[0,0],[0,1],[0,2],[0,3],[0,4],[0,5],[0,6],[0,7],[0,8],[0,9],[1,0],[1,1],[1,2],[1,3],[1,4],[1,5],[1,6],[1,7],[1,8],[2,0],[2,1],[2,2],[2,3],[2,4],[2,5],[2,6],[2,7],[3,0],[3,1],[3,2],[3,3],[3,4],[3,5],[3,6],[4,0],[4,1],[4,2],[4,3],[4,4],[4,5],[5,0],[5,1],[5,2],[5,3],[5,4],[6,0],[6,1],[6,2],[6,3],[7,0],[7,1],[7,2],[8,0],[8,1],[9,0]],
[[0,0],[0,1],[0,2],[0,3],[0,4],[0,5],[0,6],[0,7],[0,8],[1,0],[1,1],[1,2],[1,3],[1,4],[1,5],[1,6],[1,7],[1,8],[1,9],[2,0],[2,1],[2,2],[2,3],[2,4],[2,5],[2,6],[2,7],[2,8],[2,9],[3,0],[3,1],[3,2],[3,4],[3,5],[3,6],[3,7],[3,8],[3,9],[4,0],[4,1],[4,2],[4,3],[4,4],[4,5],[4,6],[4,7],[4,8],[4,9],[5,0],[5,1],[5,2],[5,3],[5,4],[5,5],[5,7],[5,8],[5,9],[6,1],[6,2],[6,3],[6,5],[6,6],[6,7],[6,8],[6,9],[7,0],[7,1],[7,2],[7,3],[7,4],[7,5],[7,6],[7,7],[7,8],[7,9],[8,0],[8,1],[8,2],[8,3],[8,4],[8,5],[8,6],[8,7],[8,8],[8,9],[9,0],[9,1],[9,2],[9,3],[9,4],[9,5],[9,6],[9,7],[9,8],[9,9]],
[[0,0],[0,1],[0,2],[0,3],[0,4],[0,5],[0,6],[0,7],[0,8],[1,0],[1,1],[1,2],[1,3],[1,4],[1,6],[1,7],[1,8],[1,9],[2,1],[2,2],[2,3],[2,4],[2,5],[2,6],[2,7],[2,8],[2,9],[4,0],[4,1],[4,2],[4,4],[4,5],[4,6],[4,7],[4,8],[4,9],[5,0],[5,1],[5,2],[5,3],[5,4],[5,5],[5,6],[5,7],[5,8],[5,9],[6,0],[6,1],[6,2],[6,4],[6,5],[6,6],[6,7],[6,8],[6,9],[8,0],[8,1],[8,2],[8,3],[8,4],[8,5],[8,6],[8,7],[8,8],[8,9],[9,0],[9,1],[9,2],[9,3],[9,7],[9,8],[9,9],[10,0],[10,1],[10,2],[10,3],[10,4],[10,5],[10,6],[10,7],[10,8],[10,9]]
]

Draw(0,0,10,test[0]),Draw(0,110,10,F(test[0]))
Draw(50,0,10,test[1]),Draw(50,110,10,F(test[1]))
Draw(130,0,10,test[2]),Draw(130,110,10,F(test[2]))
Draw(250,0,10,test[3]),Draw(250,110,10,F(test[3]))
Draw(370,0,10,test[4]),Draw(370,110,10,F(test[4]))
<canvas id=MyCanvas></canvas>


3

Mathematica, 153 151 144 136 133

Sort[{##,1,1}&@@@Input[]]//.{a___,r:{x_,y_,__},b___,{X_,Y_,W_,H_},c___}/;r=={x,Y,X-x,H}||r=={X,y,W,Y-y}:>{a,r+Sign@{0,0,X-x,Y-y},b,c}

Esempio:

Ingresso:

{{0, 0}, {1, 0}, {0, 1}, {1, 1}, {2, 1}, {1, 2}, {2, 2}}

Produzione:

{{0, 0, 2, 2}, {1, 2, 2, 1}, {2, 1, 1, 1}}

inserisci qui la descrizione dell'immagine

Ingresso:

{{0, 0}, {0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {0, 6}, {0, 7}, {0, 8}, {1, 0}, {1, 1}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {1, 6}, {1, 7}, {1, 8}, {1, 9}, {2, 0}, {2, 1}, {2, 2}, {2, 3}, {2, 4}, {2, 5}, {2, 6}, {2, 7}, {2, 8}, {2, 9}, {3, 0}, {3, 1}, {3, 2}, {3, 4}, {3, 5}, {3, 6}, {3, 7}, {3, 8}, {3, 9}, {4, 0}, {4, 1}, {4, 2}, {4, 3}, {4, 4}, {4, 5}, {4, 6}, {4, 7}, {4, 8}, {4, 9}, {5, 0}, {5, 1}, {5, 2}, {5, 3}, {5, 4}, {5, 5}, {5, 7}, {5, 8}, {5, 9}, {6, 1}, {6, 2}, {6, 3}, {6, 5}, {6, 6}, {6, 7}, {6, 8}, {6, 9}, {7, 0}, {7, 1}, {7, 2}, {7, 3}, {7, 4}, {7, 5}, {7, 6}, {7, 7}, {7, 8}, {7, 9}, {8, 0}, {8, 1}, {8, 2}, {8, 3}, {8, 4}, {8, 5}, {8, 6}, {8, 7}, {8, 8}, {8, 9}, {9, 0}, {9, 1}, {9, 2}, {9, 3}, {9, 4}, {9, 5}, {9, 6}, {9, 7}, {9, 8}, {9, 9}}

Produzione:

{{0, 0, 3, 9}, {1, 9, 9, 1}, {3, 0, 3, 3}, {3, 4, 1, 5}, {4, 3, 1, 6}, {5, 3, 1, 3}, {5, 7, 1, 2}, {6, 1, 1, 3}, {6, 5, 1, 4}, {7, 0, 3, 9}}

inserisci qui la descrizione dell'immagine

Algoritmo:

Copri la regione con i quadrati delle unità, quindi uniscili.

inserisci qui la descrizione dell'immagine

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.