床の最も単純なタイリング


10

床を表す文字列を入力として受け取り、床の特定のパターンを作成できる最も単純なメタタイルの領域を出力または返すプログラムまたは関数を記述する必要があります。

床は正方形のグリッドの一部です。すべての正方形のタイルは、紺碧または黒のいずれかで色付けされます(入力によってa、およびb入力で表されます)。

フロアの例:

  aaaa
ababab
aaaaa

メタタイリング

  • 構築されているNことにより、M空色、黒四角の矩形メタタイル
  • 使用されるメタタイルは平行移動まで同一です(回転またはミラーリングすることはできません)
  • 2つのメタタイルの側面が接続されている場合、それらはその全長に沿って接続する必要があります(つまり、メタタイルはスペースをグリッド状に並べます)。

メタタイルの例:

ba
aa

それによって作成されたメタタイリング:

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

このメタタイルは、左の文字が示すように、上部に表示されるフロアを作成します。

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

メタタイルの面積が小さい場合、メタタイルは他より単純です。この例には2*2 = 4、例の床で可能な最小の面積があります。したがって、出力は4例のようになります。

入力

  • 文字列の文字から成るa b spacenewline少なくとも一つを含有するa又はb
  • 文字(ab)は、1つの4連結(並列接続)形状を形成します。
  • 行の前に不要なスペースはありません。つまり、aまたはで始まる行が少なくとも1つありbます。
  • 2つの入力形式から選択できます。

    • 行の最後に不要な空白がありません(例に見られるように)。
    • 行の右側にスペースを入れて、すべての行を最長の行と同じ長さにします。
  • 末尾の改行はオプションです。

出力

  • タイルに入力フロアが含まれる、可能な最小のメタタイルの領域である単一の整数。

例はダッシュで区切られています。例の3つの部分は、入力、出力、および可能な最小のメタタイルの1つです。

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つのコーナー(タイルの端にあるメタタイルを除く)に接触する必要があります。「2つのメタタイルの側面が接続されている場合、それらは全長に沿って接続する必要がある」と述べました。だからあなたの与えられた例は違法です。
randomra

回答:


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ものは、sizeの有効なメタタイルの幅/高さの組み合わせを列挙しますq
  • メタタイルの候補サイズに一致する文字配列はゼロで初期化されます。
  • 内部ループは、床のすべてのタイルを反復処理します。
  • u フロアタイルに対応するメタタイルのインデックスです。
  • 床タイルとメタタイルタイルの両方がある場合ab、異なる(の合計a = 97b = 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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.