OEIS 확장 : 다이아몬드 타일링 계산


46

나는 이것이 diamong 바둑판 식 배열에 대한 나의 마지막 도전이 될 것이라고 약속한다 (어쨌든). 밝은면에서이 과제는 ASCII 아트와 관련이 없으며 코드 골프도 아니므로 실제로 완전히 다릅니다.

따라서 각 육각형에는 세 가지 다이아몬드가 있습니다.

흥미로운 질문은 주어진 육각형 크기에 대해 이러한 타일링이 몇 개나 존재하는지입니다. 이 수치는 상당히 철저하게 연구되었으며 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입니다.

우리가 그보다 더 잘할 수 있다고 확신합니다!

당신의 임무는 주어진 측면 길이에 대한 타일링 수를 계산하는 것입니다.

이것은 입니다. 귀하의 점수는 N코드가 내 컴퓨터 에서 30 분 이내에 올바른 결과를 생성 하는 가장 높은 측면 길이 입니다. 동점 인 경우, 가장 빠른 결과를 제공 하는 제출을 수락합니다 N.

평소와 같이, 타이 브레이커에서이기는 것으로 이미 알고있는 결과를 하드 코딩해서는 안됩니다. 해결하는 알고리즘은 해결하는 알고리즘 N = 3과 동일해야합니다 N = 5.

제출시 4GB 이상의 메모리를 사용해서는 안됩니다. 당신이 그 한도에 가까워 질 경우, 이것에 대해 약간의 여유를 줄 것이나, 그 한도를 계속해서 초과하거나, 그 이상으로 급등하면, 나는 N당신의 제출에 대해 그것을 세지 않을 것입니다 .

Windows 8 컴퓨터에서 모든 제출물을 테스트하므로 선택한 언어를 Windows에서 자유롭게 사용할 수 있는지 확인하십시오. 이것에 대한 유일한 예외는 Mathematica입니다 (왜냐하면 라이센스가 있기 때문입니다). 코드를 컴파일 / 실행하는 방법에 대한 지침을 포함하십시오.

물론 자신의 시간에 더 많은 용어를 계산하고 (과학 및 다른 사람들이 숫자를 비교할 수 있도록) 자유롭게 대답하십시오. 그러나 30 분 안에 답의 점수 가 결정됩니다.


4
N = 610 ^ 12 이상의 출력을 제공하기 때문에이를 달성 하기 위해서는 비 확실한 솔루션이 거의 필요합니다.
피터 테일러

1
@PeterTaylor 개선의 여지가 더 많이 생길 것으로 기대했습니다. 어쩌면 문제에 대한 더 많은 통찰력을 얻기 위해 N = 5를 수행 할 수있는 몇 가지 간단한 건설적인 대답이있을 수 있습니다. 그런 다음 모든 기와 를 구성 할 필요는 없지만 소수의 건설 된 것에서 총 수를 추정 할 수 있는 잠재적 인 하이브리드 접근법 ... 다음 어쩌면 뭔가 분석 우리는 정말 운이 좋다면. :)
Martin Ender 2016 년

2
명백한 진술의 위험에 따라, 그러한 각 타일링은 예를 들어 (100, -100,100)과 같은 원격 관점에서 볼 때 단위 큐브의 조립의 투영에 해당하는 것으로 보인다. 타일링 구성의 부담을 덜어줍니다.
DavidC

1
@DavidCarraher 실제로. 보다 구체적으로, 이러한 단위 큐브의 배열은 3D 영 다이어그램 이다. (아마도 도움이 될 것입니다.)
Martin Ender

@DavidCarraher 큰 육각형을 충분히 살펴보면 젊은 다이어그램으로 해석하는 두 가지 방법이 있습니다. 명백한 방법 (적어도 나를 위해)은 왼쪽 상단에서 2x2x1 입방체가 누락되어 상단과 왼쪽에 평평한 영역을 보는 것입니다. 그러나 그것을 보는 또 다른 방법이 있습니다 : 2x2x1 입방체가있는 그 지역의 빈 영역. 60도 기울이면 도움이 될 수 있습니다. 그것은 눈을 아프게하지만 두 개의 젊은 다이어그램이 아마도 하나를 반영하여 함께 적합하다고 생각합니다. OEIS A008793은 " 젊은 도표를 가진 비행기 파티션 의 수 ..."
Level River St

답변:


80

대수, 그래프 이론, 뫼비우스 역전, 연구 및 Java

육각형의 대칭 그룹은 12 차 다면체 그룹이고, 직경을 가로 지르는 60도 회전 및 미러 플립에 의해 생성된다. 여기에는 16 개의 하위 그룹이 있지만 그중 일부는 사소하지 않은 활용 그룹 (반사 만있는 축에는 3 가지 선택)이 있으므로 육각형의 타일링이 가질 수있는 기본적으로 10 개의 다른 대칭이 있습니다.

10 개의 대칭 이미지

삼각 격자의 하위 집합의 다이아몬드 타일링 수 는 결정 요인 으로 계산할 수 있으므로 초기 접근 방식은 육각형의 각 대칭에 대해 하나의 결정 요인을 설정하여 적어도 해당 대칭 을 갖는 타일링 수를 계산하는 것이 었습니다 ; 그리고 Möbius 역전 을 그들의 포셋 의 발생 대수 (기본적으로 포함-배제 원리의 일반화)에 사용하여 대칭 그룹이 정확히 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
당신은 필사자들 사이에서 진정으로 신입니다. 귀사의 솔루션이 저명한 저널에 게재되기를 바랍니다.
Alex A.

대단해. BTW my (현재 게시되지 않은) 코드는 N = 5에 22306956을 제공합니다. 22231176 (12) +275 (4) +75328 (6) +352 (2), 1의 불일치. 나는 당신이 여기서하고있는 것을 전혀 몰라요, 그것은 대칭에 의한 분석에 적합합니까? N = 4의 경우 나는 당신과 oeis.org/A066931/a066931.txt 보다 16 낮습니다 . 그 참조에서 나는 16의 너무 많은 수의 12를 가지고 있는데, 이것은 32의 다중 도로 변환해야합니다. N조차도 나를 위해 더 어려워요. 그러나 홀수 N에는 아무런 문제가 없으며 0 <N <4에 대한 정답을 얻습니다. 명백한 문제를 찾아 내일 내 코드를 게시합니다.
Level River St

@ steveverrill, 표기법을 이해하면 N = 5의 경우 22231176 (12) + 75328 (6) + 275 (4) + 176 (2)로 만듭니다. 인덱스 2를 2로 나누지 못하는 것 같습니다. 홀수의 FWIW에는 두 개의 정점을 통과하는 대칭 축과 3의 회전 대칭이 있습니다.
피터 테일러

@ steveverrill 및 N = 4의 경우 불일치는 대칭 축이 두 가장자리의 중간 점을 통과하는 숫자에 완벽하게 맞는 것 같습니다.
피터 테일러

3
이 문제를 해결 한 것이 인상적입니다. 나는 당신이 결국 비 수학자들이 따라 할 수있는 답변을 게시하기를 희망합니다.
DavidC

15

소개

David Carraher가 언급 한 것처럼, 육각형 타일링을 분석하는 가장 간단한 방법은 3 차원 영 다이어그램, 본질적으로 z 높이가 동일하게 유지되거나 증가해야하는 정수 높이 막대로 채워진 x, y 정사각형을 사용하여 동 형사상을 이용하는 것 같습니다. z 축에 접근하면

필자는 세 가지 직교 축 중 하나에 대한 편향을 기반으로하는 게시 된 알고리즘보다 대칭 계산에 더 적합한 총계를 찾기위한 알고리즘으로 시작했습니다.

연산

x, y 및 z 평면의 셀을 1로 채우는 것으로 시작하고 나머지 영역에는 0이 포함됩니다. 이 작업이 완료되면 각 레이어마다 원점에서 공통 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 가지 대칭 중 하나를 가질 수 있습니다 (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와의 토론에서 육각형 모서리를 통과하는 선의 대칭 만있는 타일링을 감지하지 못하는 것 같습니다. 아마도 (inversion) x (identity) 이외의 작업에 대해 자기 보완 (비대칭)을 테스트하지 않았기 때문일 수 있습니다. )가 누락 된 대칭을 발견 할 수 있습니다. 그런 다음 N = 4에 대한 데이터의 첫 번째 줄이 다음과 같이 보일 것으로 기대합니다 (c1에서 16 줄, C1에서 32 줄).

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 분에서 약 1 초로 줄입니다. 결과적으로 출력의 첫 번째 줄은 전체 가비지가되지만 (전체 총계와 마찬가지로) 총계가 이미 OEIS에서 알려진 경우 적어도 홀수 N에 대해 비대칭 타일링 수를 재구성 할 수 있습니다.

그러나 N조차도 자기 보완적인 비대칭 (c3v 대칭에 따라) 고체의 수는 없어 질 것입니다. 이 경우 정확히 1 (N ** 3) / 2 개의 셀이있는 솔리드 전용 프로그램이 유용 할 수 있습니다. 이것을 사용할 수 있고 올바르게 계산하면 N = 6을 시도 할 수 있지만 실행하는 데 시간이 오래 걸립니다.

검색을 최대 (N ^ 3) / 2 큐브까지 줄이기 위해 셀 수를 구현합니다.

완료되지 않음, 절감 효과는 미미할 것으로 예상

정확히 (N ^ 3) / 2 큐브를 포함하는 패턴에 대한 대칭 (보완 솔리드) 검사를 구현하십시오.

완료되었지만 생략 된 것으로 보입니다 (N = 4 참조).

비대칭 그림에서 어휘 적으로 가장 낮은 그림을 선택하는 방법을 찾으십시오.

저축이 그렇게 크지는 않을 것으로 예상됩니다. 비대칭 수치를 억제하면 대부분이 제거됩니다. 확인 된 유일한 반사는 y 축을 통한 평면입니다 (x와 z는 나중에 3을 곱하여 계산 됨). 회전 대칭 만있는 숫자는 거울상 이성질체 형태로 계산됩니다. 아마도 하나만 세면 거의 두 배나 빠르게 실행될 것입니다.

이를 용이하게하기 위해 각 레이어의 좌표가 나열되는 방식을 개선 할 수 있습니다 (층의 정확한 중심에 그룹이 1 또는 3 인 축퇴 그룹을 형성 함).

흥미롭지 만 사이트에서 다른 질문이있을 수 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.