C
介绍
正如David Carraher所评论的那样,分析六边形拼贴的最简单方法似乎是利用3维杨氏图的同构性,本质上是一个x,y正方形,其中填充了整数高度条,其z高度必须保持相同或增加接近z轴时。
我以一种算法为基础,该算法用于查找总数,该算法比已发布的算法更适合于对称计数,该算法基于对三个笛卡尔轴之一的偏向。 
算法
我首先用1填充x,y和z平面的像元,而其余区域包含零。完成此操作后,我将逐层构建图案,其中每一层都包含与原点具有共同3D曼哈顿距离的像元。如果单元格下面的三个单元格也包含1,则该单元格只能包含1。如果其中任何一个包含0,则该单元格必须为0。
以这种方式建立图案的优势在于,每一层都围绕x = y = z线对称。这意味着可以独立检查每一层的对称性。
对称检查
实体的对称性如下:围绕x = y = z线旋转3倍->围绕六边形中心旋转3倍;关于包含x = y = z线的3个平面和每个轴x,y,z的3个x反射->关于穿过六边形角的线的反射。
这总共只增加了6倍的对称性。为了获得六边形的完全对称性,必须考虑另一种对称性。每个实体(从1构造)具有互补的实体(从0构造)。当N为奇数时,互补实体必须与原始实体不同(因为它们不可能具有相同数量的立方体)。然而,当互补实体旋转时,会发现它的2D表示为钻石拼贴,与原始实体相同(除了2倍对称操作)。在N为偶数的情况下,固体可能是自逆的。
这可以在问题的N = 2的示例中看到。如果从左侧看,第一个六边形看起来像是带有8个小立方体的实心立方体,而最后一个六边形看起来像是带有0个小立方体的空壳。如果从右边看,则相反。第3,第4和第5六角形以及第16、17和18六角形看起来包含2个或6个立方体,因此它们在3个维度上互补。它们通过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种对称形式中的任何一种(Schoenflies表示法)
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,我的计数似乎略有下降。在与Peter Taylor的讨论中,似乎我没有检测到仅具有穿过六边形边缘的直线对称性的平铺。大概是因为我没有针对除(反转)x(同一性)以外的操作测试自补(反对称)。针对操作数(反转)x(反射)和(反转)x(3倍旋转)的自补测试)可能会发现缺失的对称性。然后,我希望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分钟减少到大约一秒钟。结果,输出的第一行变成了总垃圾(总总数也是如此),但是如果已经从OEIS中得知了总垃圾,那么可以重新构造非对称平铺的数量,至少对于奇数N是可以的。  
但是,即使是N,也会丢失自补体的不对称(根据c3v对称性)实体的数量。对于这种情况,可能需要一个单独的程序,该程序专门用于具有(N ** 3)/ 2个单元格正好为1的实体。使用此功能(并正确计数),可以尝试N = 6,但是运行将花费很长时间。
  实现对单元格的计数,以减少对多达(N ^ 3)/ 2个立方体的搜索。 
未完成,预计节省的成本很小
  对包含正好(N ^ 3)/ 2个立方体的图案实施对称性(互补固体)检查。
完成,但似乎有遗漏,请参阅N = 4。
  找到一种从不对称的数字中选择词法最低的数字的方法。 
节省不会那么大。抑制不对称图形可以消除大多数情况。唯一检查的反射是通过y轴的平面(x和z随后乘以3计算得出。)仅具有旋转对称性的图形都以其两种对映体形式计数。如果只计算一个,则运行速度可能快将近两倍。
  为了简化此过程,可能会改进列出每一层中的坐标的方式(它们由简并的6或3组组成,在该层的正中央可能有1组)。 
有趣,但网站上可能还有其他问题需要探讨。
               
              
N = 6输出的结果大于10 ^ 12,因此几乎肯定需要采用非建设性的解决方案。