Найпростіша плитка підлоги


10

Вам слід написати програму або функцію, яка отримує рядок, що описує підлогу як вхід і вихід або повертає область найпростішого мета-плитки, яка могла б створити заданий малюнок підлоги.

Підлога - частина квадратної сітки. Кожна квадратна плитка пофарбована лазурним або чорним кольором (представлена на вході aта bна вході).

Приклад поверху:

  aaaa
ababab
aaaaa

Металочерепиця

  • побудований з Nпо Mпрямокутної мета-плитці блакитних і чорних квадратів
  • використовувані мета-плитки є однаковими до перекладу (їх не можна обертати або дзеркально відображати)
  • якщо сторони двох металочерепиць з'єднані, вони повинні з'єднуватися по всій довжині (тобто мета-плитка плиткою простір таким чином, як сітка)

Приклад мета-плитки:

ba
aa

і створена нею мета-плитка:

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

Цей металочерепиця створює верхній показаний поверх, як показують ліві літери:

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

Металочерепиця простіша за іншу, якщо площа її металочерепиці менша. У нашому прикладі є площа, 2*2 = 4яка є найменшою можливою для прикладу. Тож вихід повинен бути 4для прикладу.

Вхідні дані

  • Рядок, що складається з символів a b spaceі newlineмістить принаймні один aабо b.
  • Букви ( ab) утворюють одну 4-з'єднану (з'єднану стороною) форму.
  • На передній частині рядків не буде зайвих пробілів, тобто буде принаймні один ряд, що починається з aабо b.
  • Ви можете вибрати два вхідні формати:

    • Немає зайвого пробілу в кінці рядків (як це показано в прикладах).
    • Пробіли в правій частині рядків, щоб усі рядки були однакової довжини, як і найдовший ряд.
  • Новий рядок не є обов'язковим.

Вихідні дані

  • Одне ціле число, площа найменшої можливої ​​мета-плитки, плитка якої містить вхідний поверх.

Приклади

Приклади розмежовані тире. Три частини прикладу - це вхід, вихід та одна з можливих найменших мета-плиток.

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

Це кодовий гольф, тому найкоротший запис виграє.


@Ypnypn Кожен кут повинен торкатися 3 інших кутів (крім мета-плитки на краю плитки). Я заявив це як "якщо сторони двох мета-плиток з'єднані, вони повинні з'єднуватися по всій довжині". Тож ваш приклад є незаконним.
випадкова

Відповіді:


3

C - 208 байт

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

Еквівалентний код перед гольфом:

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

Алгоритм має досить грубу силу, тому має бути досить очевидно, як він працює на основі коду. Ось кілька коментарів все одно:

  • Очікується, що введення має форму з пробілами, щоб усі лінії мали однакову довжину.
  • Перший цикл знаходить ширину, шукаючи перший символ нового рядка.
  • Зовнішня петля перевищує можливі розміри мета-плиток q. Виходить, returnколи металочерепиця може покрити підлогу. Зауважте, що циклу не потрібна інша умова виходу, оскільки завжди є рішення (найгірший випадок - це розмір вводу).
  • Перший вкладений цикл і далі ifперераховують дійсні комбінації ширини / висоти металевих плит для розміру q.
  • Масив символів, що відповідає розміру мета-плитки-кандидата, ініціалізується нулем.
  • Внутрішня петля ітералізує всі плитки в підлозі.
  • u - індекс у мета-плитці, що відповідає плитці підлоги.
  • Якщо і плитка для підлоги, і плитка для металочерепиці є aабо bвідрізняються (сума a = 97і b = 98є 195), існує невідповідність, і розмір металочерепиці з спробами розмірів не працюватиме.
  • В іншому випадку, якщо плитка для підлоги є aабо b, колір плитки скопіюється в мета-плитку-кандидат.
  • Повертає розмір мета-плитки, коли було здійснено успішне відповідність, тобто якщо спроба відповідності не була позначена як невдала.

Використовуваний тестовий код:

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

Вихід:

1
1
6
18
8
10
6
4
4
9
6
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.