Dikdörtgenleri olan bir Bölgeyi ört


22

Giriş

Bu zorluktaki girişiniz bir tamsayı çifti listesidir. Düzlemdeki birim karelerin güneybatı köşelerini ve liste düzlemin bir alt kümesi olarak birliklerini temsil eder. Örneğin, liste

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

Bu resimdeki kırmızı renkli seti temsil eder:

Bir etki alanı

Çıktı

Yor çıktısı, düzlemin dikdörtgen altkümelerini temsil eden tam sayı dörtlü bir listedir. Daha açık bir şekilde, dörtlü bir (x,y,w,h)kısım , güneybatı köşesinde bulunan genişlik w > 0ve yükseklikteki bir dikdörtgeni yineler . Dikdörtgenler, birim karelerin her birinin bir dikdörtgenin alt kümesi olduğu, her dikdörtgenin bölgenin alt kümesi olduğu anlamında, giriş bölgesinin tam bir örtüsünü oluşturmalıdır ve iki dikdörtgen yalnızca kendi sınırlarında üst üste gelebilir. Önemsiz çözümleri yasaklamak için, kaplama daha büyük bir dikdörtgene birleştirilebilecek iki dikdörtgen içermemelidir.h > 0(x,y)

Örneğin, liste

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

yasal kapsamı temsil eder

Yasal bir kaplama

Yukarıdaki bölgelere ait

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

komşu 1'e 1 kareler birleştirilebileceğinden yasadışı:

Yasadışı bir örtü

kurallar

Tam bir program veya bir işlev verebilirsiniz. Girdi ve çıktının kesin biçimlendirilmesi, gerekçeyle önemli değildir. En kısa bayt sayısı kazanır ve standart boşluklar izin verilmez. Algoritmanız hakkında bir açıklama ve bazı örnek çıktılar vermeniz teşvik edilir.

Test Kılıfları

U şeklinde bir bölge:

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

Büyük bir üçgen:

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

Üçgen

Delikli bir kare:

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

Delikli kare

Bağlantısız bölgeler:

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

Bağlantı kesildi

Doğrulayıcı

Kullanın bu Çözümünüzü doğrulamak için Python 2 programı. STDIN'den bir tuples listesi (giriş) ve virgülle ayrılmış dörtlü bir liste (çıktınız) alır.

Ayrıca bu Python 2 programını resim üretmek için yazdım ve siz de kullanabilirsiniz. STDIN'den t ya da dörtlü bir listesini alır ve adlı bir dosya oluşturur out.png. PIL kütüphanesini gerektirir. İsterseniz ızgara hücrelerinin boyutunu ve gird çizgilerinin genişliğini de değiştirebilirsiniz.

Yanıtlar:


12

Python: 196 193 182 karakter

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

İlk çözümüm KSFT ile aynı algoritmayı kullandı, bu yüzden diğer yöntemleri denedim.

İlk önce biraz ön işleme yapıyorum, tüm noktaları küçük 1x1 dikdörtgenlere dönüştürüyorum {x+(1,1)for x in P}. Bu dikdörtgenlerle, işlevi çağırırım g. gher bir dikdörtgen kombinasyonu üzerinde yinelenir. 2 dikdörtgen bulursa, daha büyük olana birleştirilebilir, ikisini de siler ve yenisini ekler. Daha sonra kendisini yeni dikdörtgen kümelerle çağırır.

kullanım

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

Sonuçlar

İşte sonuçların görselleştirilmesi. Geçerli sürümde biraz farklı olabileceğini unutmayın. Fikir şu ki, farkedilir bir desen olmadığıdır.

U şeklinde bir bölge:

Büyük üçgen

Delikli bir kare:

Bağlantısız bölgeler:

Sadece eğlence için: Pyth: 73 69 karakter

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

Yalnızca çevrimdışı sürümde çalışır. Çevrimiçi sürümdeki hata şimdi düzeltildi. Burada deneyin: Pyth Derleyici / Yürütücü . Bir liste listesi değil, bir liste listesi bekliyor.

edit: @ edc65'den bir fikir kullandım: Her iki dikdörtgeni silmek ve yeni bir tane oluşturmak yerine, birini değiştiriyorum ve birini siliyorum. Python çözümünde setlerden ve tuple list-tuple parçalarından binebilirim. -Tyton'da 11 karakter / Pyth'de -4 karakter


2
Python3: Gülen yüzler artık geçerli kod.
kusur,

Ben yanlış olabilir, ama ben değiştirmek düşünüyorum 3-hiçin ~h?
Sp3000

Pyth sürümü için kabul edildi.
Zgarb

14

Python - 272 261 258 251 224

Sanırım bunu daha çok golf yapabilirim. Bunun işe yaradığından eminim, ancak henüz tüm test durumlarında test etmedim. Test etmeyi bitirdim. Tüm test durumları için çalışır.

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

Sonuçların görüntüleri eklemeye çalışıyorum. Düzenleme: İşte örnek ve test vakalarının sonuçları:

Örnek çıktı Test durumu 1 çıkışı Test senaryosu 2 çıkışı Test durumu 3 çıkışı Test durumu 4 çıkışı

Bunu Perl'de yazmaya çalışıyorum, ama çok boyutlu karakterlerin stid'den çok boyutlu dizileri nasıl alacağını çözemiyorum. Bir önerisi olan var mı?


İki şey: (i[0]+w,i[1]+j)not in chiç {(i[0]+w,i[1]+j)}-chareket edebilir ve w=h=1hiç c=set(a)-set(b)çizgi
SP3000

Birkaç: b+=[(j+i[0],k+i[1])]için b+=(j+i[0],k+i[1]),kullanmak ve rangeüç kez o atamak kısa yüzdenr=range
SP3000

Ayrıca emin değilim, ama bunu yapmak mümkündür x,y=ikullanarak sonra xve yyerine i[0]ve i[1]? Bu çok fazla bayt kurtarır.
Sp3000,

Var bu test, ama çalıştığını düşünmüyorum: Yerine while not[j for j in r(h)if(x+w,y+j)not in c]:w+=1kullanımı while all((x+w,y+j)in c for j in r(h)):w+=1.
Jakube

@ Sp3000 / Jakube Tüm önerilerinizi kullandım.
KSFT

8

Python 2, 139

Program standart girişte küme parantezi ile çevrili sıralı çiftlerin listesini kabul eder. Örneğin,{(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

Python'un bir döngü testinin içinde bir atamaya izin vermemesi genellikle rahatsız edicidir (sadece golfde değil). Bu soruna geçici bir çözüm bulmak için dize biçimlendirme işlemlerini kullandım.


Bu etkileyici. KSFT ile aynı algoritma, 'sadece' 85 (!!!) karakter daha kısa.
Jakube

5

Mathematica - 315 285 267 bayt

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)&

@ MartinBüttner'den biraz yardım alarak.

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
)&

Kullanımı:

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

görüntü tanımını buraya girin

Test Kılıfları

U şeklinde bir bölge

görüntü tanımını buraya girin

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

Büyük üçgen

görüntü tanımını buraya girin

{{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}}

Delikli bir kare

görüntü tanımını buraya girin

{{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}}

Bağlantısız bölgeler

görüntü tanımını buraya girin

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

Test vakaları ve görüntüleri birazdan burada olacak.

Algoritma: İlk kareyi alın. Girişte olmayan bir kareye rastlamadan çok sağa ulaşın. Ardından, girişte olmayan bir kareye sahip olmadan mümkün olduğunca yukarı gidin. Şimdi eksik kare olmayan bir dikdörtgene sahibiz. Çıkışa ekleyin, tüm kareleri girişten kaldırın ve art arda çağırın.


Sen değiştirerek 1 byte kaydedebilirsiniz not$all(\x->elem(x,i)s)ile any(\x->notElem(x,i)s).
nimi,

4

JavaScript (ES6) 148 155 199

Edit2 Biraz daha ayarlama
Edit Biraz golf oynamaya devam + özyinelemeyi kullanarak yeniden yaz. Böyle bir düşüş beklemiyorduk. Şimdi takip etmesi biraz zor, ama algoritma aynı.

Algoritma, jakube cevabına benzer.

  1. Her nokta 1x1 kare olur (ön işleme)
  2. Her eleman için başka bir
    Evet ile birleştirilip birleştirilemeyeceğini kontrol edin. Evet? İlk eleman büyür, ikinci eleman silinir, adım 2'den tekrar başlayın
    , bir sonraki öğeye geçin
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
  )()

Snippet'te test edin

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}

Örnek:

Giriş:

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

Çıktı:

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

görüntü tanımını buraya girin

Giriş:

{{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}}

Çıktı:

{{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}}

görüntü tanımını buraya girin

Algoritma:

Bölgeyi birim karelerle örtün, sonra birleştirin.

görüntü tanımını buraya girin

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.