Azulejo mais simples do piso

10

Você deve escrever um programa ou função que receba uma string descrevendo o piso como entrada e saída ou retorne a área da meta-telha mais simples que possa criar o padrão especificado do piso.

O piso faz parte de uma grade quadrada. Cada bloco quadrado é colorido em azul ou preto (representado por ae bna entrada).

Um exemplo de andar:

  aaaa
ababab
aaaaa

Um meta-lado a lado

  • é construído a partir de um Npor Mrectangular meta-telha de quadrados azuis e pretos
  • os meta-mosaicos usados ​​são idênticos até a tradução (você não pode girá-los ou espelhá-los)
  • se os lados de dois meta-mosaicos estiverem conectados, eles deverão se conectar ao longo de todo o seu comprimento (ou seja, os meta-mosaicos dividirão o espaço de maneira semelhante a uma grade)

Um exemplo de meta-bloco:

ba
aa

e o meta-lado a lado criado por ele:

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

Essa meta-lado a lado cria o piso superior mostrado, como mostram as letras à esquerda:

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

Um meta-lado a lado é mais simples que outro se a área do seu lado a lado for menor. Nosso exemplo tem uma área 2*2 = 4que é a menor possível para o piso de exemplo. Portanto, a saída deve ser 4por exemplo.

Entrada

  • Uma sequência que consiste nos caracteres a b spacee que newlinecontém pelo menos um aou b.
  • As letras ( ab) formam um formato de 4 conexões (lado a lado).
  • Não haverá espaços desnecessários na frente das linhas, ou seja, haverá pelo menos uma linha começando com aou b.
  • Você pode escolher entre dois formatos de entrada:

    • Não há espaço em branco desnecessário no final das linhas (como visto nos exemplos).
    • Espaços no lado direito das linhas para tornar todas as linhas do mesmo comprimento que a linha mais longa.
  • A nova linha à direita é opcional.

Resultado

  • Um único inteiro, a área do menor meta-mosaico possível cujo mosaico contém o piso de entrada.

Exemplos

Os exemplos são delimitados por traços. As três partes de um exemplo são entrada, saída e um dos menores meta-blocos possíveis.

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

Este é um código de golfe, portanto a entrada mais curta vence.

randomra
fonte
@Ypnypn Todo canto tem que tocar em outros 3 cantos (exceto os meta-tiles na borda do ladrilho). Eu afirmei como "se os lados de dois meta-tiles estiverem conectados, eles deverão se conectar ao longo de todo o seu comprimento". Portanto, seu exemplo é ilegal.
Random # 15/05

Respostas:

3

C - 208 bytes

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

Código equivalente antes do golfe:

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

O algoritmo é uma força bastante bruta, portanto deve ser razoavelmente óbvio como ele funciona com base no código. Aqui estão alguns comentários de qualquer maneira:

  • A entrada deve ter o formulário com espaços à direita, para que todas as linhas tenham o mesmo comprimento.
  • O primeiro loop encontra a largura procurando o primeiro caractere de nova linha.
  • O loop externo ultrapassa os tamanhos candidatos de meta-tile q. Sai com a returnquando um meta-bloco pode cobrir o chão. Observe que o loop não precisa de outra condição de saída, pois sempre existe uma solução (o pior caso é o tamanho da entrada).
  • O primeiro loop aninhado e a seguir ifenumeram combinações válidas de largura / altura do meta-bloco para tamanho q.
  • Uma matriz de caracteres que corresponde ao tamanho do meta-bloco candidato é inicializada com zero.
  • O loop interno itera sobre todos os ladrilhos no chão.
  • u é o índice no meta-bloco que corresponde ao piso.
  • Se o ladrilho e o ladrilho de meta-ladrilho são aou bdiferentes (soma de a = 97e b = 98é 195), há uma incompatibilidade e o tamanho do meta-ladrilho com as dimensões tentadas não funcionará.
  • Caso contrário, se o mosaico for aou b, a cor do mosaico será copiada para o meta-mosaico candidato.
  • Retorna o tamanho do meta-bloco quando a correspondência bem-sucedida foi feita, ou seja, se a tentativa de correspondência não foi marcada como falha.

Código de teste usado:

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

Resultado:

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