Carrelage le plus simple du sol

10

Vous devez écrire un programme ou une fonction qui reçoit une chaîne décrivant le sol en entrée et en sortie ou renvoie la zone du méta-pavage le plus simple qui pourrait créer le motif donné du sol.

Le sol fait partie d'une grille carrée. Chaque tuile carrée est de couleur azur ou noire (représentée par aet bdans l'entrée).

Un exemple d'étage:

  aaaa
ababab
aaaaa

Un méta-carrelage

  • est construit à partir d' un Nde Mméta-tuile rectangulaire de carrés noirs et d' azur
  • les méta-tuiles utilisées sont identiques jusqu'à la traduction (vous ne pouvez pas les faire pivoter ou les mettre en miroir)
  • si les côtés de deux méta-tuiles sont connectés, ils doivent se connecter sur toute leur longueur (c.-à-d. que les méta-tuiles tuiles l'espace d'une manière de grille)

Un exemple de méta-tuile:

ba
aa

et le méta-carrelage créé par lui:

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

Ce méta-carrelage crée l'étage supérieur affiché comme le montrent les lettres de gauche:

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

Un méta-pavage est plus simple qu'un autre si la zone de son méta-pavé est plus petite. Notre exemple a une zone 2*2 = 4qui est la plus petite possible pour l'exemple de sol. La sortie devrait donc être 4pour l'exemple.

Contribution

  • Une chaîne composée des caractères a b spaceet newlinecontenant au moins un aou b.
  • Les lettres ( ab) forment une forme à 4 connexions (connectées côte à côte).
  • Il n'y aura pas d'espaces inutiles à l'avant des rangées, c'est-à-dire qu'il y aura au moins une rangée commençant par aou b.
  • Vous pouvez choisir entre deux formats d'entrée:

    • Aucun espace inutile à la fin des lignes (comme le montrent les exemples).
    • Espaces sur le côté droit des lignes pour que toutes les lignes aient la même longueur que la ligne la plus longue.
  • Le retour à la ligne est facultatif.

Production

  • Un entier unique, l'aire de la plus petite méta-tuile possible dont la mosaïque contient le sol en entrée.

Exemples

Les exemples sont délimités par des tirets. Les trois parties d'un exemple sont l'entrée, la sortie et l'une des plus petites méta-tuiles possibles.

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

C'est le golf de code, donc l'entrée la plus courte gagne.

randomra
la source
@Ypnypn Chaque coin doit toucher 3 autres coins (sauf les méta-tuiles sur le bord du carrelage). Je l'ai déclaré comme "si les côtés de deux méta-tuiles sont connectés, ils doivent se connecter sur toute leur longueur". Votre exemple donné est donc illégal.
randomra

Réponses:

3

C - 208 octets

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

Code équivalent avant de jouer au 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;
                }
            }
        }
    }
}

L'algorithme est assez brutal, il devrait donc être assez évident de savoir comment il fonctionne en fonction du code. Voici tout de même quelques commentaires:

  • L'entrée doit avoir le formulaire avec des espaces de fin afin que toutes les lignes aient la même longueur.
  • La première boucle trouve la largeur en recherchant le premier caractère de nouvelle ligne.
  • La boucle externe dépasse les tailles de méta-tuiles candidates q. Se termine par un returnlorsqu'un méta-carreau peut couvrir le sol. Notez que la boucle n'a pas besoin d'une autre condition de sortie car il y a toujours une solution (le pire des cas est la taille de l'entrée).
  • La première boucle imbriquée et les suivantes ifénumèrent les combinaisons valides de largeur / hauteur de méta-tuile pour la taille q.
  • Un tableau de caractères correspondant à la taille de la méta-tuile candidate est initialisé à zéro.
  • La boucle intérieure itère sur toutes les tuiles du sol.
  • u est l'indice dans la méta-tuile qui correspond à la tuile de plancher.
  • Si les carreaux de sol et les carreaux de méta-carreaux sont aou bet sont différents (la somme de a = 97et b = 98est 195), il y a un décalage et la taille de la méta-tuile avec les dimensions tentées ne fonctionnera pas.
  • Sinon, si la tuile de sol est aou b, la couleur de la tuile est copiée dans la méta-tuile candidate.
  • Renvoie la taille de la méta-tuile une fois la correspondance réussie, c'est-à-dire si la tentative de correspondance n'a pas été marquée comme ayant échoué.

Code de test utilisé:

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

Production:

1
1
6
18
8
10
6
4
4
9
6
Reto Koradi
la source