OEISの拡張:ダイヤモンドタイルのカウント


46

私は約束します、これはダイアモンドタイルに関する私の最後の挑戦になるでしょう(とにかく、しばらくの間)。明るい面では、この課題はASCIIアートとは関係がなく、コードゴルフでもないため、これは実際にはまったく異なります。

念のため、すべての六角形に3つの異なるダイヤモンドのタイトルを付けることができます。

興味深い質問は、特定の六角形のサイズに対してこれらのタイルがいくつ存在するかです。これらの数値はかなり徹底的に研究されており、OEIS A008793に記載されているようです

ただし、回転と反射までのタイルの数を尋ねると、問題は複雑になります。たとえば、辺の長さN = 2の場合、次の20のタイルが存在します。

   ____     ____     ____     ____     ____     ____     ____     ____     ____     ____  
  /\_\_\   /\_\_\   /\_\_\   /\_\_\   /_/\_\   /_/\_\   /\_\_\   /_/\_\   /_/\_\   /_/\_\ 
 /\/\_\_\ /\/_/\_\ /\/_/_/\ /\/_/\_\ /\_\/\_\ /\_\/_/\ /\/_/_/\ /\_\/\_\ /\_\/_/\ /_/\/\_\
 \/\/_/_/ \/\_\/_/ \/\_\_\/ \/_/\/_/ \/\_\/_/ \/\_\_\/ \/_/\_\/ \/_/\/_/ \/_/\_\/ \_\/\/_/
  \/_/_/   \/_/_/   \/_/_/   \_\/_/   \/_/_/   \/_/_/   \_\/_/   \_\/_/   \_\/_/   \_\/_/ 
   ____     ____     ____     ____     ____     ____     ____     ____     ____     ____  
  /_/_/\   /\_\_\   /_/\_\   /_/_/\   /_/\_\   /_/\_\   /_/_/\   /_/_/\   /_/_/\   /_/_/\ 
 /\_\_\/\ /\/_/_/\ /_/\/_/\ /\_\_\/\ /\_\/_/\ /_/\/_/\ /_/\_\/\ /\_\_\/\ /_/\_\/\ /_/_/\/\
 \/\_\_\/ \/_/_/\/ \_\/\_\/ \/_/\_\/ \/_/_/\/ \_\/_/\/ \_\/\_\/ \/_/_/\/ \_\/_/\/ \_\_\/\/
  \/_/_/   \_\_\/   \_\/_/   \_\/_/   \_\_\/   \_\_\/   \_\/_/   \_\_\/   \_\_\/   \_\_\/ 

しかし、これらの多くは回転と反射の下で同一です。これらの対称性を考慮すると、6つの異なるタイルのみが残ります。

   ____     ____     ____     ____     ____     ____  
  /\_\_\   /\_\_\   /\_\_\   /_/\_\   /_/\_\   /_/\_\ 
 /\/\_\_\ /\/_/\_\ /\/_/_/\ /\_\/_/\ /\_\/_/\ /_/\/\_\
 \/\/_/_/ \/\_\/_/ \/\_\_\/ \/\_\_\/ \/_/\_\/ \_\/\/_/
  \/_/_/   \/_/_/   \/_/_/   \/_/_/   \_\/_/   \_\/_/ 

   2        2        6        6        1        3

ここで、数字は各タイルの多重度を示します。大きな六角形には、多重度4および12のタイルもあります。

対称性までのタイリングの数はあまり徹底的に研究されていないようです。OEISエントリA066931には、5つの用語のみがリストされています。

1, 1, 6, 113, 20174

最初の項は辺の長さでN = 0あり、最後の項は辺の長さであるN = 4

私たちはそれよりもうまくやれると確信しています!

あなたの仕事は、与えられた辺の長さのタイルの数を計算することです。

これはです。スコアは、私のマシンN30分以内にコードが正しい結果を生成する最大の辺の長さになります。同点の場合、私はその N最速の結果を生み出す提出を受け入れます。

いつものように、タイブレーカーに勝つためにすでに知っている結果をハードコードしてはいけません。解決するアルゴリズムは、解決するアルゴリズムN = 3と同一でなければなりませんN = 5

提出には4GBを超えるメモリを使用しないでください。あなたがその制限の近くで動作している場合、これについていくらかの余裕を与えますが、あなたが一貫してその制限を超えている場合、またはそれを大幅に超えている場合Nは、提出のためにそれをカウントしません。

Windows 8マシンですべての提出物をテストするので、選択した言語がWindowsで自由に利用できることを確認してください。唯一の例外はMathematicaです(たまたまライセンスを持っているからです)。コードをコンパイル/実行する方法の指示を含めてください。

もちろん、自分の時間にもっと自由に用語を計算してください(科学の場合や、他の人が数字をチェックする場合)が、答えのスコアは30分で決定されます。


4
以来という注意N = 6以上10 ^ 12の出力を与え、非建設的な解決策は、そこまでを取得するために、ほぼ確実に必要です。
ピーターテイラー

1
@PeterTaylor改善の余地が増えることを望んでいました。多分、問題に対するより深い洞察を得るためにN = 5を行うことができるいくつかの単純な建設的な答えと、すべてのタイルを構築する必要はないが、いくつかの構築されたものから合計数を推定できる潜在的にハイブリッドなアプローチ...その後、多分分析、何か私たちは本当に幸運場合。:)
マーティンエンダー

2
明白なことを述べるリスクがあるが、そのようなタイル張りはそれぞれ、たとえば(100、-100,100)からの遠い視点から見た単位立方体の集合の投影に対応するように思える。これにより、タイルを構築する負担が軽減されることがわかります。
DavidC

1
@DavidCarraher確かに。より具体的には、このような単位立方体の配置は、3D Youngダイアグラムです。(多分それは誰かを助ける。)
マーティンエンダー

@DavidCarraher大きな六角形をよく見ると、それをYoungダイアグラムとして解釈する2つの異なる方法があることがわかります。(少なくとも私にとっては)明白な方法は、左上隅に2x2x1の立方体が欠落した、上部と左の平坦な領域を確認することです。しかし、それを見る別の方法があります:その領域に空のゾーンがあり、その中に2x2x1の立方体が座っています。60度傾けることが役立つ場合があります。それは私の目を傷つけますが、2つの若い図は、おそらくそれらの1つを反映することによって、一緒に適合すると思います。OEIS A008793は、「若いダイアグラムを持つ平面パーティションの数...」
レベルリバーセント

回答:


80

代数、グラフ理論、メビウスの逆転、研究、Java

六角形の対称グループは12次の二面体グループであり、60度の回転と直径全体のミラーフリップによって生成されます。16個のサブグループがありますが、それらのいくつかは非自明な共役グループ(反射のみをもつグループには3つの軸の選択肢があります)であるため、六角形のタイルが持つことができる10の根本的に異なる対称性があります:

10の対称性の画像

三角格子のサブセットのダイヤモンドタイルの数は、行列式として計算できるため、最初のアプローチは、六角形の対称性ごとに1つの行列式を設定し、少なくともそれらの対称性を持つタイルの数を計算することでした; そして、それらのポゼットの入射代数でメビウス反転を使用して(基本的に包含-排除原理の一般化)、対称群が正確にそれぞれ10個のケースであるタイルの数を計算します。ただし、対称性の一部には厄介なエッジ条件があるため、指数関数的に多くの行列式を合計する必要がありました。幸いなことに、n < 10OEISで関連するシーケンスを識別し、閉じた形式(有限の製品を許可する「閉じた」という値の場合)をつなげるのに十分なデータを提供してくれました。OEISシーケンスの更新を正当化するために準備した正式な文書には、シーケンスと証拠への参照についての少しの議論があります。

ダブルカウントが処理されると、10個の値のうち4個がきれいに相殺されるため、残りの6個を計算してから加重和を計算するだけで済みます。

N=1000私のマシンでは、このコードは30秒未満で完了します。

import java.math.BigInteger;

public class OptimisedCounter {
    private static int[] minp = new int[2];

    public static void main(String[] args) {
        if (args.length > 0) {
            for (String arg : args) System.out.println(count(Integer.parseInt(arg)));
        }
        else {
            for (int n = 0; n < 16; n++) {
                System.out.format("%d\t%s\n", n, count(n));
            }
        }
    }

    private static BigInteger count(int n) {
        if (n == 0) return BigInteger.ONE;

        if (minp.length < 3*n) {
            int[] wider = new int[3*n];
            System.arraycopy(minp, 0, wider, 0, minp.length);
            for (int x = minp.length; x < wider.length; x++) {
                // Find the smallest prime which divides x
                for (wider[x] = 2; x % wider[x] != 0; wider[x]++) { /* Do nothing */ }
            }
            minp = wider;
        }

        BigInteger E = countE(n), R2 = countR2(n), F = countF(n), R3 = countR3(n), R = countR(n), FR = countFR(n);
        BigInteger sum = E.add(R3);
        sum = sum.add(R2.add(R).multiply(BigInteger.valueOf(2)));
        sum = sum.add(F.add(FR).multiply(BigInteger.valueOf(3)));
        return sum.divide(BigInteger.valueOf(12));
    }

    private static BigInteger countE(int n) {
        int[] w = new int[3*n];
        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j <= i + n; j++) w[j]--;
            for (int j = i + n + 1; j <= i + 2*n; j++) w[j]++;
        }
        return powerProd(w);
    }

    private static BigInteger countR2(int n) {
        int[] w = new int[3*n];
        for (int i = 0; i < n; i++) {
            w[3*i+2]++;
            for (int j = 3*i + 1; j <= 2*i + n + 1; j++) w[j]--;
            for (int j = 2*i + n + 1; j <= i + n + n; j++) w[j]++;
        }
        return powerProd(w);
    }

    private static BigInteger countF(int n) {
        int[] w = new int[3*n];
        for (int i = 0; i < n; i++) {
            for (int j = 2*i + 1; j <= 2*i + n; j++) w[j]--;
            for (int j = i + n + 1; j <= i + 2*n; j++) w[j]++;
        }
        return powerProd(w);
    }

    private static BigInteger countR3(int n) {
        if ((n & 1) == 1) return BigInteger.ZERO;
        return countE(n / 2).pow(2);
    }

    private static BigInteger countR(int n) {
        if ((n & 1) == 1) return BigInteger.ZERO;
        int m = n / 2;
        int[] w = new int[3*m-1];
        for (int i = 0; i < m; i++) {
            for (int j = 1; j <= 3*i+1; j++) w[j] += 2;
            for (int j = 1; j <= i + m; j++) w[j] -= 2;
        }
        return powerProd(w);
    }

    private static BigInteger countFR(int n) {
        if ((n & 1) == 1) return BigInteger.ZERO;
        int m = n / 2;
        int[] w = new int[3*n-2];
        for (int j = 1; j <= m; j++) w[j]--;
        for (int j = 2*m; j <= 3*m-1; j++) w[j]++;
        for (int i = 0; i <= 2*m-3; i++) {
            for (int j = i + 2*m + 1; j <= i + 4*m; j++) w[j]++;
            for (int j = 2*i + 3; j <= 2*i + 2*m + 2; j++) w[j]--;
        }
        return powerProd(w);
    }

    private static BigInteger powerProd(int[] w) {
        BigInteger result = BigInteger.ONE;
        for (int x = w.length - 1; x > 1; x--) {
            if (w[x] == 0) continue;

            int p = minp[x];
            if (p == x) result = result.multiply(BigInteger.valueOf(p).pow(w[p]));
            else {
                // Redistribute it. This should ensure we avoid negatives.
                w[p] += w[x];
                w[x / p] += w[x];
            }
        }

        return result;
    }
}

24
あなたは本当に人間の中の神です。あなたのソリューションが有名なジャーナルに掲載されることを期待しています。
アレックスA.

これはすごい。ところで私の(現在投稿されていない)コードはN = 5の22306956を与えます:22231176(12)+275(4)+75328(6)+352(2)、1の矛盾、奇数です。ここであなたがやっていることはわかりませんが、対称性による破壊に適していますか?N = 4の場合、私はあなたとoeis.org/A066931/a066931.txtより16低いです。その参照から、16の多重度12が多すぎるようです。驚いたことに、Nでさえ私にとっては難しいです。しかし、奇数のNには問題がなく、0 <N <4で正しい答えが得られます。明らかな問題を探して、明日コードを投稿します。
レベルリバーセント

@steveverrill、表記法が理解できれば、N = 5の場合、22231176(12)+ 75328(6)+ 275(4)+ 176(2)にします。インデックス2を2で割るのに失敗していると思います(奇数の場合、FWIWはすべて2つの頂点を通過する対称軸と3次の回転対称を持っています)。
ピーターテイラー

@steveverrill、およびN = 4の場合、2つのエッジの中点を通過する対称軸を持つ数に矛盾は完全に収まるようです。
ピーターテイラー

3
これを解決したことは印象的です。私はあなたが最終的に非数学者が従うことができる答えを投稿することを望んでいます。
DavidC

15

C

前書き

David Carraherがコメントしたように、六角形のタイルを分析する最も簡単な方法は、3次元Young Diagramの同型を利用することであると思われます。 z軸に近づくにつれて。

私は、3つのデカルト軸の1つへのバイアスに基づく公開されたアルゴリズムよりも、対称性のカウントに適応しやすい合計を見つけるためのアルゴリズムから始めました。

アルゴリズム

まず、x、y、z平面のセルに1を入力し、残りの領域にはゼロを含めます。それが終わったら、レイヤーごとにパターンを作成します。各レイヤーには、原点から共通の3Dマンハッタン距離を持つセルが含まれています。セルは、その下の3つのセルにも1が含まれている場合にのみ1を含むことができます。いずれかのセルに0が含まれている場合、セルは0でなければなりません。

この方法でパターンを作成する利点は、各レイヤーがx = y = z線に関して対称であることです。これは、各レイヤーの対称性を個別にチェックできることを意味します。

対称性チェック

ソリッドの対称性は次のとおりです。x= y = z線の周りの3回転->六角形の中心の周りの3回転。そして、x = y = zラインと各軸x、y、zを含む3つの平面に関する3 x反射->六角形の角を通るラインに関する反射。

これにより、合計で6回対称になります。六角形の完全な対称性を得るには、別の種類の対称性を考慮する必要があります。各ソリッド(1から構築)には補完的なソリッド(0から構築)があります。Nが奇数の場合、補完ソリッドは元のソリッドと異なる必要があります(同じ数のキューブを持つことはできないため)。しかし、相補的なソリッドが丸くなると、ダイアモンドタイリングとしての2D表現が元のソリッドと同じであることがわかります(2重対称操作を除く)。Nが偶数の場合、ソリッドが自己反転する可能性があります。

これは、質問のN = 2の例で見ることができます。左から見ると、最初の六角形は8個の小さな立方体のある立方体のように見え、最後の六角形は0個の小さな立方体のある空のシェルのように見えます。右側から見た場合、逆のことが当てはまります。3番目、4番目、5番目の六角形と16、17、18番目の六角形は、2個または6個の立方体を含むように見えるため、3次元で互いに補完します。これらは2次元対称操作(2回転、または六角形のエッジを通る軸の周りの反射)によって2次元で互いに関連しています。一方、9、10、11、12番目の六角形は3Dパターンを示し、独自の補数であるため、対称性が高くなります(したがって、これらは奇数の多重度を持つ唯一のパターンです)。

(N ^ 3)/ 2キューブを持つことは、自己補完するために必要な条件ですが、一般に、N> 2の場合は十分な条件ではないことに注意してください。このすべての結果は、奇数Nの場合、タイルは常にペア(N ^ 3)/ 2キューブで発生するため、慎重に検査する必要があります。

現在のコード(N = 1,2,3,5の正しい合計を生成します。N= 4で説明したエラー。)

int n;                     //side length

char t[11][11][11];        //grid sized for N up to 10

int q[29][192], r[29];     //tables of coordinates for up to 10*3-2=28 layers 

int c[9];                  //counts arrangements found by symmetry class. c[8] contains total.


//recursive layer counting function. m= manhattan distance, e= number of cells in previous layers, s=symmetry class.
void f(int m,int e,int s){

  int u[64], v[64], w[64]; //shortlists for x,y,z coordinates of cells in this layer
  int j=0;                 
  int x,y,z;

  for (int i=r[m]*3; i; i-=3){
    // get a set of coordinates for a cell in the current layer.
    x=q[m][i-3]; y= q[m][i-2]; z= q[m][i-1];
    // if the three cells in the previous layer are filled, add it to the shortlist u[],v[],w[]. j indicates the length of the shortlist.
    if (t[x][y][z-1] && t[x][y-1][z] && t[x-1][y][z]) u[j]=x, v[j]=y, w[j++]=z ;
  }


  // there are 1<<j possible arrangements for this layer.   
  for (int i = 1 << j; i--;) {

    int d = 0;

    // for each value of i, set the 1's bits of t[] to the 1's bits of i. Count the number of 1's into d as we go.
    for (int k = j; k--;) d+=(t[u[k]][v[k]][w[k]]=(i>>k)&1);

    // we have no interest in i=0 as it is the empty layer and therefore the same as the previous recursion step. 
    // Still we loop through it to ensure t[] is properly cleared.      

    if(i>0){
      int s1=s;    //local copy of symmetry class. 1's bit for 3 fold rotation, 2's bit for reflection in y axis.
      int sc=0;    //symmetry of self-complement.

      //if previous layers were symmetrical, test if the symmetry has been reduced by the current layer 
      if (s1) for (int k = j; k--;) s1 &= (t[u[k]][v[k]][w[k]]==t[w[k]][u[k]][v[k]]) | (t[u[k]][v[k]][w[k]]==t[w[k]][v[k]][u[k]])<<1;

      //if exactly half the cells are filled, test for self complement
      if ((e+d)*2==n*n*n){
        sc=1;
        for(int A=1; A<=(n>>1); A++)for(int B=1; B<=n; B++)for(int C=1; C<=n; C++) sc&=t[A][B][C]^t[n+1-A][n+1-B][n+1-C];
      }

      //increment counters for total and for symmetry class.
      c[8]++; c[s1+(sc<<2)]++;

      //uncomment for graphic display of each block stacking with metadata. not recommended for n>3.
      //printf("m=%d  j=%d  i=%d c1=%d-2*%d=%d c3=%d cy=%d(cs=%d) c3v=%d ctot=%d\n",m,j,i,c[0],c[2],c[0]-2*c[2],c[1],c[2],c[2]*3,c[3],c[8]);
      //printf("m=%d  j=%d  i=%d C1=%d-2*%d=%d C3=%d CY=%d(CS=%d) C3V=%d ctot=%d\n",m,j,i,c[4],c[6],c[4]-2*c[6],c[5],c[6],c[6]*3,c[7],c[8]);
      //for (int A = 0; A<4; A++, puts(""))for (int B = 0; B<4; B++, printf(" "))for (int C = 0; C<4; C++) printf("%c",34+t[A][B][C]);

      //recurse to next level.
      if(m<n*3-2)f(m + 1,e+d,s1);

    }
  } 
}

main()
{
  scanf("%d",&n);

  int x,y,z;

  // Fill x,y and z planes of t[] with 1's
  for (int a=0; a<9; a++) for (int b=0; b<9; b++) t[a][b][0]= t[0][a][b]= t[b][0][a]= 1;

  // Build table of coordinates for each manhattan layer
  for (int m=1; m < n*3-1; m++){
    printf("m=%d : ",m);
    int j=0;
    for (x = 1; x <= n; x++) for (y = 1; y <= n; y++) {
      z=m+2-x-y;
      if (z>0 && z <= n) q[m][j++] = x, q[m][j++] = y, q[m][j++]=z, printf(" %d%d%d ",x,y,z);
      r[m]=j/3;
    }
    printf(" : r=%d\n",r[m]);
  }

  // Set count to 1 representing the empty box (symmetry c3v)
  c[8]=1; c[3]=1; 

  // Start searching at f=1, with 0 cells occupied and symmetry 3=c3v
  f(1,0,3); 

  // c[2 and 6] only contain reflections in y axis, therefore must be multiplied by 3.
  // Similarly the reflections in x and z axis must be subtracted from c[0] and c[4].
  c[0]-=c[2]*2; c[2]*=3; 
  c[4]-=c[6]*2; c[6]*=3;



  int cr[9];cr[8]=0;
  printf("non self-complement                   self-complement\n");
  printf("c1  %9d/12=%9d           C1  %9d/6=%9d\n",   c[0], cr[0]=c[0]/12,     c[4], cr[4]=c[4]/6);
  if(cr[0]*12!=c[0])puts("c1 division error");if(cr[4]*6!=c[4])puts("C1 division error");

  printf("c3  %9d/4 =%9d           C3  %9d/2=%9d\n",   c[1], cr[1]=c[1]/4,      c[5], cr[5]=c[5]/2);
  if(cr[1]*4!=c[1])puts("c3 division error");if(cr[5]*2!=c[5])puts("C3 division error");

  printf("cs  %9d/6 =%9d           CS  %9d/3=%9d\n",   c[2], cr[2]=c[2]/6,      c[6], cr[6]=c[6]/3);
  if(cr[2]*6!=c[2])puts("cs division error");if(cr[6]*3!=c[6])puts("CS division error");

  printf("c3v %9d/2 =%9d           C3V %9d/1=%9d\n",   c[3], cr[3]=c[3]/2,      c[7], cr[7]=c[7]);
  if(cr[3]*2!=c[3])puts("c3v division error");  

  for(int i=8;i--;)cr[8]+=cr[i]; 
  printf("total =%d unique =%d",c[8],cr[8]);    
}

出力

プログラムは、ソリッドの8つの対称性に従って、8エントリの出力テーブルを生成します。ソリッドには、次の4つの対称性があります(シェーン表記)

c1: no symmetry
c3: 3-fold axis of rotation (produces 3-fold axis of rotation in hexagon tiling)
cs: plane of reflection (produces line of reflection in hexagon tiling)
c3v both of the above (produces 3-fold axis of rotation and three lines of reflection through the hexagon corners)

さらに、ソリッドのセルのちょうど半分が1で、残りの半分が0である場合、すべての1と0を反転させてから、キューブ空間の中心で座標を反転させる可能性があります。これは私が自己補数と呼んでいるものですが、より数学的な用語は「反転中心に関して非対称」です。

この対称操作により、六角形のタイルの回転軸が2倍になります。

この対称性を持つパターンは、別の列にリストされています。Nが偶数の場合にのみ発生します。

N = 4の場合、私のカウントは少しずれているようです。ピーターテイラーとの議論では、六角形のエッジを通る線の対称性のみを持つタイルを検出していないようです。これは、(inversion)x(identity。)以外の操作の自己補数(反対称性)をテストしていないためと思われます。 )欠落している対称性が明らかになる場合があります。N = 4のデータの最初の行は次のようになります(c1で16少ない、C1で32多い)。

c1   224064/12=18672          C1  534/6=89

これにより、合計がPeterの回答およびhttps://oeis.org/A066931/a066931.txtに沿ったものになります。

現在の出力は次のとおりです。

N=1
non self-complement     self-complement
c1      0/12= 0           C1  0/6= 0
c3      0/4 = 0           C3  0/2= 0
cs      0/6 = 0           CS  0/3= 0
c3v     2/2 = 1           C3V 0/1= 0
total =2 unique =1

non self-complement     self-complement
N=2
c1      0/12= 0           C1  0/6= 0
c3      0/4 = 0           C3  0/2= 0
cs     12/6 = 2           CS  3/3= 1
c3v     4/2 = 2           C3V 1/1= 1
total =20 unique =6

N=3
non self-complement     self-complement
c1    672/12=56           C1  0/6= 0
c3      4/4 = 1           C3  0/2= 0
cs    288/6 =48           CS  0/3= 0
c3v    16/2 = 8           C3V 0/1= 0
total =980 unique =113

N=4 (errors as discussed)
non self-complement     self-complement
c1   224256/12=18688          C1  342/6=57
c3       64/4 =16             C3  2/2= 1
cs     8064/6 =1344           CS  54/3=18
c3v      64/2 =32             C3V 2/1= 2
total =232848 unique =20158

N=5
non self-complement     self-complement
c1  266774112/12=22231176        C1  0/6= 0
c3       1100/4 =275             C3  0/2= 0
cs     451968/6 =75328           CS  0/3= 0
c3v       352/2 =176             C3V 0/1= 0
total =267227532 unique =22306955

予定リスト(更新済み)

現在のコードを整理します。

完了、多かれ少なかれ

現在のレイヤーの対称性チェックを実装し、前のレイヤーの対称性のパラメーターを渡します(最後のレイヤーが非対称かどうかをチェックするポイントはありません)。

完了、奇数Nの結果は公開データと一致

非対称図形のカウントを抑制するオプションを追加します(はるかに高速に実行されるはずです)

これは、再帰呼び出しに別の条件を追加することで実行できますif(s1 && m<n*3-2)f(m + 1,e+d,s1)。N= 5の実行時間を5分から約1秒に短縮します。その結果、出力の最初の行は(全体の合計と同様に)合計ガベージになりますが、合計がOEISから既にわかっている場合は、少なくとも奇数Nの場合、非対称タイルの数を再構成できます。

しかし、Nであっても、自己補完的な非対称(c3v対称性による)ソリッドの数は失われます。この場合、1の正確に(N ** 3)/ 2セルを持つソリッド専用の別個のプログラムが役立つ場合があります。これが利用できる(そして正しくカウントされる)場合、N = 6を試すことが可能かもしれませんが、実行には長い時間がかかります。

セルのカウントを実装して、検索を最大(N ^ 3)/ 2キューブに減らします。

行われていない、節約はわずかであると予想される

正確に(N ^ 3)/ 2個の立方体を含むパターンの対称(相補ソリッド)チェックを実装します。

完了しましたが、省略されているようです。N= 4を参照してください。

非対称の数字から字句的に最も低い数字を選択する方法を見つけます。

節約はそれほど大きくないと予想されます。非対称の図形を抑制すると、このほとんどがなくなります。チェックされる唯一の反射は、y軸を通る平面です(xとzは、後で3を掛けて計算されます)。回転対称のみの図形は、両方の鏡像体でカウントされます。おそらく、1つだけがカウントされた場合、ほぼ2倍の速度で実行されるでしょう。

これを容易にするために、各レイヤーの座標がリストされる方法を改善する可能性があります(レイヤーの正確な中心に1のグループが含まれる可能性がある、6または3の縮退グループを形成します)。

興味深いですが、おそらくサイトには他にも質問があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.