Boşluk doldurmak için isteğe bağlı dikdörtgenler düzenlemek


26

Bu dikdörtgenler dikdörtgen bir alanı doldurabilir mi?

Bir demet dikdörtgen verildiğinde, dikdörtgen bir alanı dolduracak şekilde düzenlenmiş olup olmadıkları sorulur.

gözlük

Bir dizi keyfi m x ndikdörtgen verildiğinde ; 0 <= m, n <= 1000, bunları herhangi bir delik veya örtüşme olmadan tam olarak dikdörtgen bir alanı kaplayacak şekilde düzenlemenin mümkün olup olmadığını belirleyin. Dikdörtgenler döndürülemez ve her dikdörtgen yalnızca bir kez yerleştirilebilir.

Giriş

Bunun için giriş çok esnektir; giriş bir çeşit 2 boşluk boyut listesi verir. Örneğin, aşağıdakilerin her ikisi de geçerlidir:

Boşluğa Göre Ayrılmış, Dönüş

1 2
1 5
4 5
3 6

Boyutların Listesi

[[1, 2], [1, 5], [4, 5], [3, 6]]

Çıktı

Doğru / yanlış, 0/1, T / F, Doğru / Yanlış gibi her türlü doğru / yanlış değer. Çok açık olmayan bir çıktı yöntemi kullanacaksanız, lütfen cevabınızı belirtin.

Örnekler

Test Durumu 1

Giriş:

1 1
1 5
2 6

Çıktı: true(veya benzeri bir şey)
Nasıl düzenlenir:

XYYYYY
ZZZZZZ
ZZZZZZ

Test Durumu 2

Giriş:

1 1
2 2

Çıktı: false(veya benzeri bir şey)
Açıklama: Farklı boyutlarda iki kare düzenleyemediğiniz ve kenarlarını sıraya koyamayacağınız açıktır.

Test Durumu 3

Giriş:

1 1
1 2
1 2
2 1
2 1

Çıktı: true(veya benzeri bir şey) Nasıl düzenlenir:

AAB
DEB
DCC

@ETHProductions'in belirttiği gibi, diğer tüm test durumlarında, tek bir dikdörtgene sahip olana kadar dikdörtgenleri ortak bir kenar uzunluğuyla birleştirmeye devam edebilirsiniz, bu nedenle bu test durumu yalnızca bu fikri kullanan herhangi bir kodu kırmak içindir.

Test Durumu 4

Giriş:

3 2
4 1
2 1
4 1
2 1
5 2
3 2
1 4
3 2
2 1
2 1
1 1
5 1

Çıktı: true(veya benzeri bir şey)
Nasıl düzenlenir:

AAABBBBEE
AAACCDDDD
FFFFFGGGH
FFFFFGGGH
IIIJJKKLH
IIIMMMMMH

Not : Nasıl düzenleyeceğinizi belirtmeniz gerekmez, yalnızca düzenlenip düzenlenmediğini belirlemeniz gerekir.

Bu kod golf, yani bayt cinsinden en kısa cevap kazanır! 14 Ocak'tan itibaren en kısa cevabı kabul edeceğim, ancak yine de oy verebileceğimden daha sonra cevap vermekten çekinmeyin! :)

Mutlu golf!

~ AL

PS Bu soruna hangi etiketin uygulanması gerektiğini biliyorsanız, lütfen ekleyin, kod-golf dışında bir etiket olarak ne yazacağımı kesinlikle bilmiyorum.

EDIT : Programınız iyi bir bilgisayarda en fazla 10 saniyede 25 dikdörtgen işleyebilmelidir (bu kural için oldukça esnek olacağım).

EDIT : Gönderim kabul tarihini yılın son gününe uzattım, ancak o zamana kadar bir cevap alacağımdan şüpheliyim ...

EDIT : Gönderim kabul son tarihini 2 hafta uzattım, o zaman cevap gelmezse, mevcut C cevabı kabul edilecektir! :)


Her giriş dikdörtgeni sadece bir kere mi kullanılmalı?
xnor

7
Neden bir son tarih var? O zaman bir cevabı kabul edebileceğinizi söyleyebilirsiniz, ancak zorlukların süresiz açık olması gerekir :)
Nathan Merrill

4
Dikdörtgenler döndürülebilir mi?
xnor

3
Eh, sizin probleminiz bir karar verilebilirlik problemi: "bu yönlendirilmiş dikdörtgenler, 0 israf ile başka bir dikdörtgen oluşturacak şekilde düzenlenebilir mi" (NP-komple bir problemdir) (Korf, 2003: pdfs.semanticscholar.org/90a5/… ). Korf'un algoritması, temelde, çözümü olmayan yapılandırmaları daha verimli bir şekilde ortadan kaldırmak için bazı optimizasyonlara sahip, kaba bir kuvvettir. Bunun bir golf sahasının çoğu dilde 250 karakterin altında olacağından şüpheliyim.
Gabriel Benamy

1
Kolay rota, aynı genişlikte veya yükseklikte iki dikdörtgeni, 1 dikdörtgen bırakana kadar art arda birleştirip birleştiremeyeceğinizi belirlemek olacaktır. Bu algoritma mevcut tüm test senaryoları için çalışır; ancak, [[1, 2], [2, 1], [1, 1], [1, 2], [2, 1]](düzenlenebilir ABB ACD EED) için başarısız olur . Bu basit test senaryosunu eklemek isteyebilirsiniz.
ETHProductions

Yanıtlar:


5

C, 1135 1158 1231 1598 bayt

Öyleyse, belirtilen son tarihi geçmiş, ancak henüz nasıl bir cevap alınmadığını görmek, işte bir (biraz uzun) C

İade:

  • 0 (sıfır) başarısızlık durumunda (sığmaz)
  • Başarıya tam uyan matris

Güncelleştirme:

Orijinal kod izin verilen 10'dan çok daha uzun süren bazı matrislere takılabilir. Mevcut revizyon, tüm matrisleri 1 yaşın altında tamamlamalıdır. Bu, 1) Giriş dikdörtgenlerini sıralama ve 2) takarken tekrarlanan boyutları atlayarak yapılır.

golfed:

#define R r[i]
#define Z return
#define _(B,D,E) for(int B=E;B<D;B++)
struct{int x,y,u,p;}r[25],*S;int A,M,N,U,V,X,Y;char *P;T(x,y,w,h){_(I,x+w,x)_(J,y+h,y)if(I/U|J/V|P[J*U+I])Z 0;Z 1;}L(x,y,w,h,c){_(I,x+w,x)_(J,y+h,y)P[J*U+I]=c;}F(){int x=0,y;while(++x<A)if(!P[x])break;if(x/A){_(i,V,0)printf("%*.*s\n",U,U,P+i*U);exit(0);}y=x/U;x-=y*U;_(i,N,0)if(!R.u&T(x,y,R.x,R.y))R.u=1,L(x,y,R.x,R.y,'A'+i),F(),R.u=0,L(x,y,R.x,R.y,0);}O(i,y){if(!R.u){if(!T(0,y,R.x,R.y))Z;R.u=1;R.p=0;L(0,y,R.x,R.y,'A'+i);y+=R.y;}if(y-V||F())_(j,N,0)if(j-i&!r[j].u){O(j,y);while(r[j].x-r[j+1].x|r[j].y-r[j+1].y)j++;}R.u=0;L(R.p,(y-=R.y),R.x,R.y,0);}Q(i,x){if(!R.u){if(R.x>U-x)Z;R.u=1;R.p=x;L(x,0,R.x,R.y,'A'+i);x+=R.x;}if(x-U||O(i,1))_(j,N,0)if(j-i&!r[j].u)Q(j,x);L(x-=R.x,0,R.x,R.y,0);R.u=0;}C(int*a,int*b){Z*a-*b?*a-*b:a[1]-b[1];}main(){_(i,25,0)if(++N&scanf("%d%d\n",&R.x,&R.y)-2)break;_(i,N,0){A+=R.x*R.y;if(R.x>X)X=R.x;if(R.y>Y)Y=R.y;}_(i,A+1,1)if(!(A%i)){if(i<Y|A/i<X)continue;M++;S=realloc(S,M*16);S[M-1].y=i;S[M-1].x=A/i;}qsort(S,M,16,C);P=calloc(A+1,1);_(j,M,0){U=S[j].x;V=S[j].y;_(i,N,0)R.u=1,L(0,0,R.x,R.y,'A'+i),Q(i,R.x),R.u=0;}printf("0\n");exit(1);}

UnGolfed:

#define R r[i]
#define Z return
#define _(B,D,E) for(int B=E;B<D;B++)
struct {
    int x,y,u,p;
} r[25],*S;
int A,M,N,U,V,X,Y;
char *P;

test_space(x,y,w,h) {
    _(I,x+w,x)
        _(J,y+h,y)
            if (    I >= U |
                    J >= V |
                    P[J*U+I]) Z 0;
    Z 1;
}
place_rect(x,y,w,h,c){
    _(I,x+w,x)
        _(J,y+h,y)P[J*U+I] = c;
}

fill_rest() {
    int x=0,y;
    while(++x<A) if (!P[x])break;
    if (x>=A) {
        _(i,V,0) printf("%*.*s\n", U,U, P+i*U);
        exit(0);
    }
    y = x / U; x -= y*U;

    _(i,N,0)
        if (!R.u & test_space(x, y, R.x, R.y))
                R.u = 1,
                place_rect(x, y, R.x, R.y, 'A'+i),
                fill_rest(),
                R.u = 0,
                place_rect(x, y, R.x, R.y, 0);

}

fill_y(i,y) {
    if (!R.u) {
        if (!test_space(0, y, R.x, R.y)) Z;
        R.u = 1;
        R.p = 0;
        place_rect(0, y, R.x, R.y, 'A'+i);
        y += R.y;
    }
    if (y == V) fill_rest();
    else _(j,N,0)
        if (j!=i && !r[j].u){ fill_y(j, y);
        while (r[j].x^r[j+1].x||r[j].y^r[j+1].y)j++;
        }
    R.u = 0;
    place_rect(R.p, (y -= R.y), R.x, R.y, 0);
}

fill_x(i,x) {
    if (!R.u) {
        if (R.x > U - x) Z;
        R.u = 1;
        R.p = x;
        place_rect(x, 0, R.x, R.y, 'A'+i);
        x += R.x;
    }
    if (x == U) fill_y(i, 1);
    else
        _(j,N,0)
            if (j!=i && !r[j].u) fill_x(j, x);
    place_rect((x -= R.x), 0, R.x, R.y, 0);
    R.u = 0;
}
C(int*a,int*b) {
    Z *a^*b?*a-*b:a[1]-b[1];
}


main() {
    _(i,25,0)
        if (++N&&scanf("%d %d\n", &R.x, &R.y)!=2) break;
    _(i,N,0){
        A+=R.x*R.y;
        if(R.x>X)X=R.x;
        if(R.y>Y)Y=R.y;
    }
    _(i,A+1,1)
        if (!(A%i)) {
            if (i < Y | A/i < X) continue;
            M++;
            S = realloc(S,M*16);
            S[M-1].y=i;
            S[M-1].x=A/i;
        }
    qsort(S, M, 16,C);
    P = calloc(A + 1,1);
    _(j,M,0){
        U = S[j].x; V = S[j].y;
        _(i,N,0)
            R.u = 1,
            place_rect(0, 0, R.x, R.y, 'A'+i),
            fill_x(i, R.x),
            R.u = 0;
    }
    printf("0\n");
    exit(1);
}

Açıklama: Biz 6 işlevi vardır: main, O, Q, F, Lve T. T t , belirli bir noktada için dikdörtgen alanı olup olmadığını görmek için uğratılmış EST'ler. Lfil l çıkış tamponu içinde bir dikdörtgen s ya da alternatif olarak onu üzerine tek kaldırır. Ove Qsırasıyla sol ve üst duvarlar inşa etmek ve F f tekrarlı arama ile dikdörtgenin kalan hastalıklar.

Temel arama yinelemeli olsa da, önce ana dikdörtgen için izin verilen genişlik ve yükseklik kombinasyonlarını oluşturarak ve sonra imkansız konfigürasyonları ortadan kaldırarak olası arama vektörlerinin büyük çoğunluğunu elimine ediyoruz. Merkezi doldurmadan önce alt ve sağ duvarları belirleyerek daha büyük dikdörtgenlerde ek hız kazanılabilir, ancak 25 iç dikdörtgen ile sınırlanırken iyi hız için gerekli değildir.


İyi iş! Çalışıyor gibi görünüyor ... Ancak çıkış biçiminizi belirtebilir misiniz? Görünen o ki, eğer çalışırsa işler basıyor ve çalmıyorsa çöküyor, buna izin vereceğim çünkü bu zaten bir cevap. Ayrıca, "Herkes uyuyor!" Yerine "1" yazdırarak epeyce bayt tasarruf edebilirsiniz. (çünkü buna izin verilir) ve ayrıca nasıl düzenlendiklerini yazdırarak da birkaç bayt. Basılı olması güzel, ama gereksiz bayt kullanıyor ve amaç ondan tasarruf etmektir. Aksi takdirde, iyi iş! Son teslim tarihini yarım ay uzatacağım, fakat şimdilik bir artıya oy verdim. :)
HyperNeutrino,

Teşekkürler. Biçimi belirlemek için güncelleme yaptım ve kilitlenme düzeltildi (istenmeyen). Matrix çıktısını (+ 30bayt) bıraktım çünkü çok şık ve eğer birisi golf dili çözümü yayınlarsa, beni sadece 30'a kadar atmayacaklar :)
Seth

-367 bytes ... Muhtemelen şimdiye kadarki en büyük golf? :-)
HyperNeutrino,

:-) Eh, bir hack-y başlangıç ​​noktası olması için yardımcı olur.
Seth

Tabii ki yapar! En büyük golf oyunum Java’nın birkaç düzenlemesinde 337 karakterdi ve bazı korkunç fikirler ile başladım (ah, eski güzel günlerim 50 milyon değişken yaratacağım ve sadece 2’ye ihtiyaç duyacağım ...). Her neyse, cevapları bekliyorum ama sanırım bu sadece çalışan bir cevap olabilir!
HyperNeutrino,

6

Haskell, 226 bayt

((y,z):l)&(w,x)|x*y<1=(w+y,x+z):l
(q:l)&p=p:q:l
(p@(u,v):r@(y,z):l)%q@(w,x)=[((y-w,z):l)&q&(u,v-x)|w<=y,x<=v]++[p:m|m<-(r:l)%q]
_%_=[]
g m(p:n)l=any(g[]$m++n)(l%p)||g(p:m)n l
g[]_[_,_,_]=0<1
g _[]_=0<0
($[(0,9^9),(9^9,0)]).g[]

Ideone'da dene

Nasıl çalışır

Bu, şeklini Genç bir şema olan tüm kısmi eğimleri yinelemeli olarak arar , bir seferde bir dikdörtgen ekler ve sonuçların herhangi birinin dikdörtgen olup olmadığını kontrol eder.

Herhangi bir dikdörtgenin herhangi bir döşemesinin bu şekilde inşa edilebileceğini görmek için: boş olmayan bir Genç diyagramın döşenmesinde R, güneybatı köşesinde başka bir dikdörtgene temas etmeyen döşemedeki dikdörtgenler kümesi olsun. Young diyagramının her içbükey tepe noktası R'de en fazla bir dikdörtgenin kenarına bitişik (sadece köşe bitişik değil) olduğundan ve bu içbükey köşe noktalarının sayısı R'deki dikdörtgen sayısından daha az olduğundan, en azından R içindeki bir dikdörtgen, bu içbükey köşelerin hiçbirinin kenarına bitişik değildir. Onu çıkarmak başka bir Young diyagramı verir, böylece indüksiyonla devam edebiliriz.


Güzel bir! Bu fantastik. Aferin! :)
HyperNeutrino
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.