Einfachste Fliesenverlegung

10

Sie sollten ein Programm oder eine Funktion schreiben, die eine Zeichenfolge empfängt, die den Boden als Eingabe und Ausgabe beschreibt, oder den Bereich der einfachsten Meta-Kacheln zurückgibt, die das gegebene Muster des Bodens erzeugen könnten.

Der Boden ist Teil eines quadratischen Gitters. Jede quadratische Kachel ist entweder azurblau oder schwarz gefärbt (dargestellt durch aund bin der Eingabe).

Ein Beispielboden:

  aaaa
ababab
aaaaa

Eine Meta-Kachelung

  • wird von einem eingebauten Nvon Mrechteckiger meta-Kachel von himmelblau und schwarzen Quadraten
  • Die verwendeten Meta-Kacheln sind bis zur Übersetzung identisch (Sie können sie nicht drehen oder spiegeln).
  • Wenn die Seiten von zwei Meta-Kacheln verbunden sind, sollten sie sich über ihre gesamte Länge verbinden (dh Meta-Kacheln kacheln den Raum gitterartig).

Ein Beispiel für eine Meta-Kachel:

ba
aa

und die von ihm erstellten Meta-Kacheln:

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

Diese Meta-Kacheln erzeugen das obere angezeigte Stockwerk, wie die linken Buchstaben zeigen:

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

Eine Meta-Kachelung ist einfacher als eine andere, wenn der Bereich ihrer Meta-Kachelung kleiner ist. Unser Beispiel hat eine Fläche, 2*2 = 4die für den Beispielboden so klein wie möglich ist. Die Ausgabe sollte also 4für das Beispiel sein.

Eingang

  • Eine Zeichenfolge, die aus den Zeichen besteht a b spaceund newlinemindestens ein aoder enthält b.
  • Die Buchstaben ( ab) bilden eine 4-verbundene (nebeneinander verbundene) Form.
  • Es gibt keine unnötigen Leerzeichen an der Vorderseite der Zeilen, dh es gibt mindestens eine Zeile, die mit aoder beginnt b.
  • Sie können zwischen zwei Eingabeformaten wählen:

    • Kein unnötiges Leerzeichen am Ende der Zeilen (wie in den Beispielen gezeigt).
    • Leerzeichen auf der rechten Seite der Zeilen, damit alle Zeilen dieselbe Länge wie die längste Zeile haben.
  • Nachgestellte Zeilenumbrüche sind optional.

Ausgabe

  • Eine einzelne Ganzzahl, die Fläche der kleinstmöglichen Meta-Kachel, deren Kachel die Eingabeetage enthält.

Beispiele

Beispiele werden durch Bindestriche begrenzt. Die drei Teile eines Beispiels sind Eingabe, Ausgabe und eine der möglichen kleinsten Meta-Kacheln.

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

Dies ist Code Golf, so dass der kürzeste Eintrag gewinnt.

randomra
quelle
@Ypnypn Jede Ecke muss 3 andere Ecken berühren (außer den Meta-Kacheln am Rand der Kacheln). Ich sagte es als "wenn die Seiten von zwei Meta-Kacheln verbunden sind, sollten sie sich über ihre gesamte Länge verbinden". Ihr Beispiel ist also illegal.
Randomra

Antworten:

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

Äquivalenter Code vor dem Golfen:

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

Der Algorithmus ist ziemlich brutal, daher sollte es ziemlich offensichtlich sein, wie er basierend auf dem Code funktioniert. Hier noch ein paar Kommentare:

  • Es wird erwartet, dass die Eingabe das Formular mit nachgestellten Leerzeichen hat, sodass alle Zeilen dieselbe Länge haben.
  • Die erste Schleife ermittelt die Breite, indem nach dem ersten Zeilenumbruchzeichen gesucht wird.
  • Die äußere Schleife liegt über den möglichen Meta-Kachelgrößen q. Beendet mit einem, returnwenn eine Meta-Kachel den Boden bedecken kann. Beachten Sie, dass die Schleife keine weitere Ausgangsbedingung benötigt, da es immer eine Lösung gibt (der schlimmste Fall ist die Größe der Eingabe).
  • In der ersten und folgenden verschachtelten Schleife ifwerden gültige Kombinationen aus Breite und Höhe der Metakacheln für die Größe aufgelistet q.
  • Ein Zeichenarray, das der Größe der Meta-Kachel des Kandidaten entspricht, wird mit Null initialisiert.
  • Die innere Schleife durchläuft alle Fliesen im Boden.
  • u ist der Index in der Meta-Kachel, der der Bodenkachel entspricht.
  • Wenn sowohl Bodenfliesen als auch Meta-Fliesen-Fliesen aoder bund unterschiedlich sind (Summe von a = 97und b = 98ist 195), liegt eine Nichtübereinstimmung vor, und die Meta-Fliesengröße mit den versuchten Abmessungen funktioniert nicht.
  • Andernfalls wird, wenn die Bodenfliese aoder ist b, die Fliesenfarbe auf die Kandidaten-Meta-Fliese kopiert.
  • Gibt die Größe der Meta-Kachel zurück, wenn eine erfolgreiche Übereinstimmung erzielt wurde, dh wenn die versuchte Übereinstimmung nicht als fehlgeschlagen markiert wurde.

Verwendeter Testcode:

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

Ausgabe:

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