Розширення OEIS: підрахунок алмазних плит


46

Обіцяю, це буде моїм останнім викликом щодо діамантових накладок (все одно на деякий час). З іншого боку, цей виклик не має нічого спільного з мистецтвом ASCII, і не є кодом для гольфу, тому це насправді зовсім інше.

Тож як нагадування, кожен шестикутник можна назвати трьома різними діамантами:

Цікаве запитання - скільки цих перекриттів існує для заданого розміру шестикутника. Здається, ці цифри були вивчені досить ретельно і їх можна знайти в OEIS A008793 .

Однак проблема стає складнішою, якщо ми запитаємо, скільки нахилів існує до обертання та відбиття . Наприклад, для довжини бічної сторони N = 2 існує 20 таких нахилів:

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

Але багато з них ідентичні при обертанні та відбитті. Якщо взяти до уваги ці симетрії, залишається лише 6 різних нахилів:

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

   2        2        6        6        1        3

де цифри вказують на кратність кожної плитки. Зверніть увагу, що для більших шестикутників також існують обрешітки з кратністю 4 і 12.

Схоже, кількість нахилів до симетрії вивчена менш ретельно. Запис OEIS A066931 містить лише п'ять термінів:

1, 1, 6, 113, 20174

де перший член - для бічної довжини, N = 0а останній - для бічної довжини N = 4.

Я впевнений, що ми можемо зробити краще!

Ваше завдання - обчислити кількість нахилів для заданої довжини сторони.

Це . Ваш результат буде найвищою стороною, Nдля якої ваш код дає правильний результат протягом 30 хвилин на моїй машині. У разі вирівнювання, я прийму подання, яке дає результат для цього N найшвидшого.

Як завжди, ви не повинні твердо кодувати результати, які ви вже знаєте, щоб виграти тай-брейк. Алгоритм, що вирішує, N = 3повинен бути ідентичним алгоритму, який вирішує N = 5.

Ваше повідомлення не повинно використовувати більше 4 Гб пам'яті. Я дам деяку свободу для цього, якщо ви працюєте близько до цієї межі, але якщо ви постійно перевищуєте цю межу, або якщо ви значно перевищуєте її, я не буду вважати це 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 Якщо ви досить складно дивитесь на великий шестикутник, ви побачите два різні способи інтерпретувати його як діаграму Янг. Очевидний спосіб (як мінімум, для мене) - побачити рівну ділянку вгорі і зліва, кубоїд 2x2x1 відсутній у верхньому лівому куті. Але є й інший спосіб бачити це: порожня зона в цій місцевості з кубоїдом 2x2x1. Нахил на 60 градусів може допомогти. Мені болять очі, але я думаю, що дві молоді діаграми поєднуються разом, можливо, відбиваючи одну з них. OEIS A008793 дуже обережний зі своїм формулюванням: "кількість площинних перегородок, чиї молоді діаграми ..."
Level River St

Відповіді:


80

Алгебра, теорія графів, інверсія Мебіуса, дослідження та Java

Група симетрії шестикутника - це двогранна група порядку 12 і породжена обертанням на 60 градусів і дзеркальним переворотом по діаметру. Він має 16 підгруп, але деякі з них знаходяться в нетривіальних групах сполучення (ті, у яких є лише відбиття, мають 3 варіанти осі), тому існує 10 принципово різних симетрій, які може мати плитка шестикутника:

Зображення 10 симетрій

Кількість алмазних накладок підмножини трикутної решітки можна обчислити як визначальну , тому мій початковий підхід полягав у встановленні одного визначального значення для кожної із симетрій шестикутника, щоб обчислити кількість накладок, які мають принаймні ті симетрії ; а потім використати інверсію Мебіуса в алгебрі випадковості їх групи (в основному це узагальнення принципу включення-виключення), щоб опрацювати кількість накладок, група симетрії яких становить саме кожен із 10 випадків. Однак деякі з симетрій мають неприємні крайові умови, тому я був змушений підсумовувати експоненціально багато визначників. На щастя, значення, отримані дляn < 10дав мені достатньо даних, щоб можна було визначити відповідні послідовності в OEIS і скласти разом закриту форму (для деякого значення "закритого", що дозволяє обмежувати продукти). Трохи обговорюються послідовності та посилання на докази, в офіційному описі, який я підготував для обґрунтування оновлень послідовності OEIS.

Після подвійного підрахунку виявляється, що чотири з десяти значень акуратно скасовуються, тому нам залишається лише обчислити решту шість, а потім зробити зважену суму.

Цей код займає менше 30 секунд N=1000на моїй машині.

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
Ти справді бог серед смертних. Я сподіваюся побачити ваше рішення опубліковане в престижному журналі.
Олексій А.

Це круто. BTW мій (наразі не розміщений) код дає 22306956 для N = 5: 22231176 (12) +275 (4) +75328 (6) +352 (2), невідповідність 1, що непарно. Я не знаю, що ти тут робиш, чи підходить це для розбивки по симетрії? Для N = 4 я на 16 нижче, ніж ти, і oeis.org/A066931/a066931.txt З цього посилання здається, що у мене є 16 занадто багато кратності 12, що мені потрібно перетворити на 32 кратності. Я не занадто здивований, навіть N для мене складніше. Але у мене немає проблем з непарним N, і я отримую правильні відповіді на 0 <N <4. Буде шукати очевидних проблем і опублікувати мій код завтра.
Рівень річки Св.

@steveverrill, якщо я розумію позначення, для N = 5 я роблю це 22231176 (12) + 75328 (6) + 275 (4) + 176 (2). Я думаю, вам не вдається розділити індекс 2 на 2. (FWIW для непарних чисел, всі вони мають вісь симетрії, що проходить через дві вершини та обертальну симетрію порядку 3).
Пітер Тейлор

@steveverrill, а для N = 4 ваша невідповідність здається ідеальною для числа, у якого вісь симетрії проходить через середину двох ребер.
Пітер Тейлор

3
Вражає, що ви вирішили це. Я сподіваюся, що ви зрештою опублікуєте відповідь, яку можуть слідувати не-математики.
DavidC

15

С

Вступ

Як зауважив Девід Каррахер, найпростішим способом аналізу шестигранної плитки здавалося, було б скористатися її ізоморфізмом за допомогою 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 у точному центрі шару.)

Цікаво, але, напевно, є інші питання на сайті, які слід вивчити.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.