С
Вступ
Як зауважив Девід Каррахер, найпростішим способом аналізу шестигранної плитки здавалося, було б скористатися її ізоморфізмом за допомогою 3-х мірної діаграми Юнга, по суті це квадрат x, y, заповнений цілими смугами висоти, висота z яких повинна залишатися однаковою або збільшуватися у міру наближення осі z.
Я почав з алгоритму пошуку підсумків, який піддається адаптації для підрахунку симетрії, ніж опублікований алгоритм, який базується на зміщенні однієї з трьох декартових осей.
Алгоритм
Я починаю із заповнення осередків площин x, y і z 1, а решта області містить нулі. Після цього я будую шари за шаром, при цьому кожен шар містить клітини, що мають загальну відстань у 3D-манхеттені від початку. Клітина може містити 1, лише якщо три комірки під нею також містять 1. Якщо будь-яка з них містить 0, то комірка повинна бути 0.
Перевага побудови малюнка таким чином полягає в тому, що кожен шар симетричний щодо лінії x = y = z. Це означає, що кожен шар можна перевірити незалежно на симетрію.
Перевірка симетрії
Симетрії твердого тіла такі: 3-кратне обертання навколо лінії x = y = z -> 3-кратне обертання навколо центру шестикутника; і 3 x відбиття про 3 площини, що містять лінію x = y = z та кожну з осей x, y, z -> відбиття про лінії через кути шестикутника.
Це додає лише 6-кратну симетрію. Для отримання повної симетрії шестикутника необхідно розглянути ще один вид симетрії. Кожна тверда речовина (побудована з 1-х років) має взаємодоповнювальну тверду речовину (побудовану з 0-х). Там, де N непарне, комплементарний твердий матеріал повинен відрізнятися від вихідного твердого речовини (оскільки для них неможливо мати однакову кількість кубів). Однак, коли комплементарне тверде тіло повернеться, буде встановлено, що його 2D-представлення у вигляді алмазної плитки ідентичне (за винятком 2-кратної операції симетрії) вихідному твердому тілу. Там, де N парне, тверде тіло може бути самооберненим.
Це можна побачити на прикладах до N = 2 у питанні. Якщо дивитися зліва, перший шестикутник виглядає як суцільний кубик з 8 маленькими кубиками, тоді як останній шестикутник виглядає як порожня оболонка з 0 маленькими кубиками. Якщо дивитися з правого боку, реверс справжній. 3-й, 4-й та 5-й шестикутники та 16-й, 17-й та 18-й шестикутники виглядають так, що містять 2 або 6 кубів, і таким чином вони доповнюють один одного у 3 вимірах. Вони пов'язані один з одним у двох вимірах за допомогою 2-кратної симетрії (2-кратне обертання або відображення навколо осі через ребра шестикутника.) є їх власними доповненнями, і тому мають вищу симетрію (тому це єдині візерунки з непарною кратністю).
Зауважимо, що наявність (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, а потім перевернути координати через центр простору куба. Це я називаю самодоповненням, але більш математичним терміном було б «антисиметричне відносно центру інверсії».
Ця операція симетрії дає двократну вісь обертання в шестигранному плитці.
Шаблони, що мають цю симетрію, вказані в окремому стовпчику. Вони трапляються лише там, де N парне.
Моя кількість, здається, трохи знижена для N = 4. Під час обговорення з Пітером Тейлором виявляється, що я не виявляю нахилів, які мають лише симетрію лінії через краї шестикутника. Це, мабуть, тому, що я не перевіряв самодоповнення (антисиметрія) для інших операцій, ніж (інверсія) х (ідентичність.) Тестування самодоповнення для опетонів (інверсія) х (відбиття) та (інверсія) х (триразове обертання) ) може виявити відсутні симетрії. Тоді я б очікував, що перший рядок даних для N = 4 буде виглядати так (на 16 менше в c1 і на 32 більше в C1):
c1 224064/12=18672 C1 534/6=89
Це приведе у відповідність до відповіді Петра та 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 (х і z обчислюються пізніше, помноживши на 3.) Цифри, що мають лише обертальну симетрію, підраховуються в обох їх енантіомерних формах. Можливо, він би пробіг майже вдвічі швидше, якби рахувався лише один.
Щоб полегшити це, можливо, покращити перелік координат у кожному шарі (вони утворюють вироджені групи з 6 або 3, можливо група з 1 у точному центрі шару.)
Цікаво, але, напевно, є інші питання на сайті, які слід вивчити.
N = 6
дає вихід більше 10 ^ 12, неконструктивне рішення майже напевно необхідно, щоб досягти цього далеко.