Ubin lantai paling sederhana

10

Anda harus menulis program atau fungsi yang menerima string yang menggambarkan lantai sebagai input dan output atau mengembalikan area meta-tiling paling sederhana yang dapat membuat pola lantai yang diberikan.

Lantai adalah bagian dari kotak persegi. Setiap ubin persegi berwarna biru atau hitam (diwakili oleh adan bdalam input).

Lantai contoh:

  aaaa
ababab
aaaaa

Ubin meta

  • dibangun dari Noleh Mpersegi panjang meta-genteng kotak biru dan hitam
  • meta-tile yang digunakan identik dengan terjemahan (Anda tidak dapat memutar atau mencerminkannya)
  • jika sisi-sisi dari dua ubin meta terhubung, mereka harus terhubung sepanjang panjangnya (yaitu ubin meta ubin ruang dengan cara seperti kotak)

Contoh meta-tile:

ba
aa

dan meta-tiling yang dibuat olehnya:

       .
       .
       .
    babababa
    aaaaaaaa
... babababa ...
    aaaaaaaa    
    babababa
    aaaaaaaa
       .
       .
       .

Ubin meta ini menciptakan lantai yang ditampilkan di atas seperti yang ditunjukkan oleh huruf kiri:

       .
       .
       .
    ********
    ***aaaa*
... *ababab* ...
    *aaaaa**    
    ********
    ********
       .
       .
       .

Ubin meta lebih sederhana daripada yang lain jika luas meta-ubinnya lebih kecil. Contoh kami memiliki area 2*2 = 4yang terkecil yang mungkin untuk lantai contoh. Jadi hasilnya harus sebagai 4contoh.

Memasukkan

  • String yang terdiri dari karakter a b spacedan newlinemengandung setidaknya satu aatau b.
  • Huruf-huruf ( ab) membentuk satu bentuk yang terhubung 4 (terhubung berdampingan).
  • Tidak akan ada ruang yang tidak perlu di bagian depan baris yaitu akan ada setidaknya satu baris dimulai dengan aatau b.
  • Anda dapat memilih dua format input:

    • Tidak ada spasi kosong di akhir baris (seperti yang terlihat pada contoh).
    • Spasi di sisi kanan baris untuk membuat semua baris sama panjang dengan baris terpanjang.
  • Mengejar baris baru adalah opsional.

Keluaran

  • Integer tunggal, area meta-tile terkecil yang mungkin yang ubinnya berisi lantai input.

Contohnya

Contoh dibatasi oleh tanda hubung. Tiga bagian dari contoh adalah input, output dan salah satu dari meta-tile terkecil yang mungkin.

a

1

a
-----------------
 aaaa
aaa
a

1

a
-----------------
aabaab
abaa
aaba

6

aab
aba
-----------------
aabaab
a  a a
aabab

18

aabaab
aaaaaa
aababa
-----------------
ba
aaab

8

baaa
aaab
-----------------
 aaaa
ababb
aaaa

10

aaaaa
ababb
-----------------
 a aa
ab ba
 aba

6

aa
ab
ba
-----------------
 aaaa
abab
aaaa

4

aa
ab
-----------------
ba
 ba
  b

4

ba
ab
-----------------
baa
aba
aab

9

baa
aba
aab
-----------------
 aaaa
aabaa
aaaa

6

aaa
aab

Ini adalah kode golf sehingga entri terpendek menang.

randomra
sumber
@Ypnypn Setiap sudut harus menyentuh 3 sudut lainnya (kecuali ubin meta di tepi ubin). Saya menyatakannya sebagai "jika sisi-sisi dari dua meta-tile terhubung, mereka harus terhubung sepanjang panjangnya". Jadi contoh yang Anda berikan adalah ilegal.
randomra

Jawaban:

3

C - 208 byte

w,q,n,m,r,g,u;t(char*f){for(w=0;f[w++]-10;);for(q=1;;q++)for(n=1;m=q/n,n<=q;++n)if(n*m==q){char t[q];bzero(t,q);r=q;for(g=0;f[g];++g){u=g/w%m*n+g%w%n;r=t[u]+f[g]-195?r:0;if(f[g]&64)t[u]=f[g];}if(r)return r;}}

Kode Setara sebelum bermain golf:

#include <stdio.h>
#include <strings.h>

int t(char* f) {
    int w = 0;
    for ( ; f[w++] - 10; );

    for (int q = 1; ; q++) {
        char t[q];
        for (int n = 1; n <= q; ++n) {
            int m = q / n;
            if (n * m == q) {
                bzero(t, q);
                int r = q;
                for (int g = 0; f[g]; ++g) {
                    int u = g / w % m * n + g % w % n;
                    if (t[u] + f[g] == 195) {
                        r = 0;
                    }
                    if (f[g] & 64) {
                        t[u] = f[g];
                    }
                }
                if (r) {
                    return r;
                }
            }
        }
    }
}

Algoritma ini cukup kasar, sehingga harus cukup jelas cara kerjanya berdasarkan kode. Berikut ini beberapa komentar:

  • Input diharapkan memiliki bentuk dengan spasi tambahan sehingga semua garis memiliki panjang yang sama.
  • Loop pertama menemukan lebar dengan mencari karakter baris baru pertama.
  • Lingkaran luar melebihi ukuran meta-ubin kandidat q. Keluar dengan suatu returnsaat ubin meta dapat menutupi lantai. Perhatikan bahwa loop tidak memerlukan kondisi keluar lain karena selalu ada solusi (kasus terburuk adalah ukuran input).
  • Loop bersarang pertama dan berikut ini ifmenyebutkan kombinasi lebar / tinggi meta-tile yang valid untuk ukuran q.
  • Array karakter yang cocok dengan ukuran meta-tile kandidat diinisialisasi nol.
  • Loop dalam berulang di semua ubin di lantai.
  • u adalah indeks dalam ubin meta yang sesuai dengan ubin lantai.
  • Jika kedua ubin lantai dan ubin meta adalah aatau bdan berbeda (jumlah a = 97dan b = 98adalah 195), ada ketidakcocokan, dan ukuran meta-ubin dengan dimensi yang dicoba tidak akan berfungsi.
  • Sebaliknya, jika ubin lantai adalah aatau b, warna ubin disalin ke kandidat ubin meta.
  • Mengembalikan ukuran meta-tile saat pertandingan berhasil dilakukan, yaitu jika pertandingan yang dicoba tidak ditandai sebagai gagal.

Kode uji yang digunakan:

#include <stdio.h>

extern int t(char* s);

int main()
{
    printf("%d\n", t(
        "a\n"
    ));
    printf("%d\n", t(
        " aaaa\n"
        "aaa  \n"
        "a    \n"
    ));
    printf("%d\n", t(
        "aabaab\n"
        "abaa  \n"
        "aaba  \n"
    ));
    printf("%d\n", t(
        "aabaab\n"
        "a  a a\n"
        "aabab \n"
    ));
    printf("%d\n", t(
        "ba  \n"
        "aaab\n"
    ));
    printf("%d\n", t(
        " aaaa\n"
        "ababb\n"
        "aaaa \n"
    ));
    printf("%d\n", t(
        " a aa\n"
        "ab ba\n"
        " aba \n"
    ));
    printf("%d\n", t(
        " aaaa\n"
        "abab \n"
        "aaaa \n"
    ));
    printf("%d\n", t(
        "ba \n"
        " ba\n"
        "  b\n"
    ));
    printf("%d\n", t(
        "baa\n"
        "aba\n"
        "aab\n"
    ));
    printf("%d\n", t(
        " aaaa\n"
        "aabaa\n"
        "aaaa \n"
    ));
    return 0;
}

Keluaran:

1
1
6
18
8
10
6
4
4
9
6
Reto Koradi
sumber