Mở rộng OEIS: Đếm kim cương


46

Tôi hứa, đây sẽ là thử thách cuối cùng của tôi về diamong nghiêng (dù sao đi nữa, dù sao đi nữa). Về mặt sáng sủa, thử thách này không liên quan gì đến nghệ thuật ASCII và cũng không phải là một môn đánh gôn, vì vậy điều này thực sự hoàn toàn khác.

Vì vậy, như một lời nhắc nhở, mỗi hình lục giác có thể được đặt tiêu đề với ba viên kim cương khác nhau:

Một câu hỏi thú vị được đặt ra là có bao nhiêu trong số các nghiêng này tồn tại cho một kích thước hình lục giác nhất định. Có vẻ như những con số này đã được nghiên cứu khá kỹ lưỡng và có thể được tìm thấy trong OEIS A008793 .

Tuy nhiên, vấn đề trở nên phức tạp hơn nếu chúng ta hỏi có bao nhiêu nghiêng tồn tại để xoay và phản xạ . Chẳng hạn, đối với chiều dài cạnh N = 2, tồn tại 20 nghiêng sau:

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

Nhưng nhiều trong số này là giống hệt nhau dưới sự luân chuyển và phản xạ. Nếu chúng ta tính đến các đối xứng này, chỉ còn 6 nghiêng khác nhau:

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

   2        2        6        6        1        3

trong đó các con số biểu thị bội số của mỗi ốp lát. Lưu ý rằng đối với các hình lục giác lớn hơn cũng có các độ nghiêng với bội số 4 và 12.

Có vẻ như số lượng nghiêng cho đến đối xứng đã được nghiên cứu ít kỹ lưỡng. Mục nhập OEIS A066931 chỉ liệt kê năm điều khoản:

1, 1, 6, 113, 20174

trong đó thuật ngữ đầu tiên là chiều dài bên N = 0và thuật ngữ cuối cùng cho chiều dài bên N = 4.

Tôi chắc rằng chúng ta có thể làm tốt hơn thế!

Nhiệm vụ của bạn là tính toán số lượng nghiêng cho một chiều dài cho trước.

Đây là . Điểm của bạn sẽ là độ dài phụ cao nhất Nmà mã của bạn tạo ra kết quả chính xác trong vòng 30 phút trên máy của tôi. Trong trường hợp của một cà vạt, tôi sẽ chấp nhận việc nộp trong đó sản xuất kết quả cho rằng N nhanh nhất.

Như thường lệ, bạn không được kết quả mã hóa cứng mà bạn đã biết để giành được break-breaker. Thuật toán giải quyết N = 3phải giống hệt với thuật toán giải N = 5.

Trình của bạn không được sử dụng nhiều hơn 4GB bộ nhớ. Tôi sẽ đưa ra một số chậm trễ về vấn đề này nếu bạn hoạt động gần với giới hạn đó, nhưng nếu bạn luôn vượt quá giới hạn đó hoặc nếu bạn tăng đột biến vượt quá giới hạn đó, tôi sẽ không tính đến Nviệc bạn nộp.

Tôi sẽ kiểm tra tất cả các lần gửi trên máy Windows 8 của mình, vì vậy hãy đảm bảo ngôn ngữ bạn chọn có sẵn miễn phí trên Windows. Ngoại lệ duy nhất cho điều này là Mathematica (vì tôi tình cờ có giấy phép cho nó). Vui lòng bao gồm các hướng dẫn về cách biên dịch / chạy mã của bạn.

Tất nhiên, hãy thoải mái tính toán nhiều thuật ngữ hơn trong thời gian của bạn (đối với khoa học và cho người khác kiểm tra số của họ), nhưng điểm số câu trả lời của bạn sẽ được xác định trong 30 phút đó.


4
Lưu ý rằng vì N = 6cho đầu ra hơn 10 ^ 12, một giải pháp phi xây dựng gần như chắc chắn là cần thiết để đạt được điều đó.
Peter Taylor

1
@PeterTaylor Tôi đã hy vọng rằng sẽ cho phép nhiều phòng hơn để cải thiện. Trước tiên, có thể một vài câu trả lời mang tính xây dựng đơn giản có thể thực hiện N = 5 để hiểu rõ hơn về vấn đề, và sau đó các phương pháp lai có khả năng không cần xây dựng tất cả các góc nhưng có thể ngoại suy tổng số từ một số được xây dựng ... và sau đó có thể là một cái gì đó phân tích nếu chúng ta thực sự may mắn. :)
Martin Ender

2
Với nguy cơ nói rõ ràng, dường như mỗi lát gạch như vậy tương ứng với một hình chiếu của một tập hợp các khối đơn vị khi nhìn từ một quan điểm xa, ví dụ, từ (100, -100,100). Tôi thấy rằng điều này làm nhẹ gánh nặng của việc xây dựng nghiêng.
DavidC

1
@DavidCarraher Thật vậy. Cụ thể hơn, sự sắp xếp các khối đơn vị như vậy là sơ đồ 3D Young . (Có lẽ điều đó giúp được ai đó.)
Martin Ender

@DavidCarraher Nếu bạn đủ chăm chỉ nhìn vào hình lục giác lớn, bạn sẽ thấy có 2 cách khác nhau để diễn giải nó như một sơ đồ Trẻ. Cách rõ ràng (ít nhất là đối với tôi) là nhìn thấy một khu vực bằng phẳng ở trên cùng và bên trái với một hình khối 2x2x1 bị thiếu ở góc trên cùng bên trái. Nhưng có một cách khác để nhìn thấy nó: một vùng trống trong khu vực đó, với một hình khối 2x2x1 ngồi trong đó. Nghiêng 60 độ có thể giúp đỡ. Nó làm đau mắt tôi nhưng tôi nghĩ hai sơ đồ trẻ khớp với nhau, có thể là do sự phản chiếu của một trong số chúng. OEIS A008793 rất cẩn thận với cách diễn đạt: "số lượng phân vùng máy bay có sơ đồ trẻ ..."
Level River St

Câu trả lời:


80

Đại số, lý thuyết đồ thị, nghịch đảo Möbius, nghiên cứu và Java

Nhóm đối xứng của hình lục giác là nhóm dih thờ của trật tự 12, và được tạo ra bởi một vòng quay 60 độ và một gương lật trên một đường kính. Nó có 16 nhóm con, nhưng một số trong chúng thuộc các nhóm liên hợp không tầm thường (những nhóm chỉ có phản xạ có 3 lựa chọn trục), do đó, có 10 đối xứng cơ bản khác nhau mà một hình lục giác có thể có:

Hình ảnh của 10 đối xứng

Số lượng kim cương của một tập hợp con của mạng tam giác có thể được tính là một yếu tố quyết định , vì vậy cách tiếp cận ban đầu của tôi là thiết lập một định thức cho mỗi đối xứng của hình lục giác, để tính số lượng các góc có ít nhất các đối xứng đó ; và sau đó sử dụng nghịch đảo Möbius trong đại số tỷ lệ mắc của vị trí của chúng (về cơ bản là khái quát hóa nguyên tắc loại trừ bao gồm) để tìm ra số lượng nghiêng có nhóm đối xứng chính xác trong 10 trường hợp. Tuy nhiên, một số đối xứng có điều kiện cạnh khó chịu, vì vậy tôi buộc phải tổng hợp theo nhiều yếu tố quyết định theo cấp số nhân. May mắn thay, các giá trị thu được chon < 10đã cung cấp cho tôi đủ dữ liệu để có thể xác định các chuỗi có liên quan trong OEIS và ghép thành một dạng đóng (đối với một số giá trị "đóng" cho phép các sản phẩm hữu hạn). Có một chút thảo luận về các trình tự và các tài liệu tham khảo về bằng chứng, trong bài viết chính thức mà tôi đã chuẩn bị để biện minh cho các cập nhật trình tự OEIS.

Sau khi tính toán kép, hóa ra bốn trong số mười giá trị hủy bỏ gọn gàng, vì vậy chúng ta chỉ phải tính sáu số còn lại và sau đó thực hiện một tổng số có trọng số.

Mã này mất dưới 30 giây cho N=1000máy của tôi.

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
Bạn thực sự là một vị thần giữa những người phàm trần. Tôi hy vọng sẽ thấy giải pháp của bạn được công bố trên một tạp chí uy tín.
Alex A.

Điều này thật tuyệt. Mã BTW của tôi (hiện chưa được đăng) cung cấp 22306956 cho N = 5: 22231176 (12) +275 (4) +75328 (6) +352 (2), chênh lệch 1, là số lẻ. Tôi không biết bạn đang làm gì ở đây, nó có phù hợp với sự cố do sự đối xứng không? Với N = 4 Tôi thấp hơn bạn 16 và oeis.org/A066931/a066931.txt Từ tham chiếu đó, có vẻ như tôi có 16 quá nhiều bội số 12, mà tôi cần chuyển đổi thành 32 bội số 6. Tôi không quá ngạc nhiên, ngay cả N cũng khó khăn hơn với tôi. Nhưng tôi không có vấn đề gì với N lẻ và tôi nhận được câu trả lời đúng cho 0 <N <4. Sẽ tìm kiếm các vấn đề rõ ràng và gửi mã của tôi vào ngày mai.
Cấp sông St

@steveverrill, nếu tôi hiểu ký hiệu, với N = 5 tôi làm cho nó 22231176 (12) + 75328 (6) + 275 (4) + 176 (2). Tôi nghĩ rằng bạn không thể chia chỉ số 2 cho 2. (FWIW cho các số lẻ, tất cả chúng đều có trục đối xứng đi qua hai đỉnh và đối xứng quay theo thứ tự 3).
Peter Taylor

@steveverrill và với N = 4 sự khác biệt của bạn dường như là một sự phù hợp hoàn hảo cho số có trục đối xứng đi qua trung điểm của hai cạnh.
Peter Taylor

3
Ấn tượng rằng bạn đã giải quyết điều này. Tôi hy vọng cuối cùng bạn sẽ đăng một câu trả lời mà những người không phải là nhà toán học có thể làm theo.
DavidC

15

C

Giới thiệu

Theo nhận xét của David Carraher, cách đơn giản nhất để phân tích ốp hình lục giác dường như là tận dụng sự đồng hình của nó với Biểu đồ trẻ 3 chiều, về cơ bản là một hình vuông x, y chứa đầy các thanh có chiều cao nguyên có chiều cao z phải giữ nguyên hoặc tăng khi trục z được tiếp cận.

Tôi đã bắt đầu với một thuật toán để tìm ra các tổng có thể thích ứng với việc tính đối xứng hơn so với thuật toán được công bố, dựa trên sự thiên vị đối với một trong ba trục cartesian.

Thuật toán

Tôi bắt đầu bằng cách lấp đầy các ô của các mặt phẳng x, y và z bằng 1, trong khi phần còn lại của khu vực chứa các số 0. Khi đã xong, tôi xây dựng lớp mẫu theo từng lớp, với mỗi lớp chứa các ô có khoảng cách manhattan 3D chung từ gốc. Một ô chỉ có thể chứa 1 nếu ba ô bên dưới cũng chứa 1. nếu bất kỳ ô nào chứa 0, thì ô đó phải là 0.

Ưu điểm của việc xây dựng mô hình theo cách này là mỗi lớp đối xứng với đường x = y = z. Điều này có nghĩa là mỗi lớp có thể được kiểm tra độc lập về tính đối xứng.

Kiểm tra đối xứng

Các đối xứng của vật rắn như sau: Xoay 3 lần về đường x = y = z -> Xoay 3 lần về tâm hình lục giác; và 3 x phản xạ về 3 mặt phẳng chứa đường thẳng x = y = z và mỗi trục phản xạ x, y, z -> về các đường thẳng qua các góc lục giác.

Điều này chỉ thêm tối đa 6 lần đối xứng. Để có được sự đối xứng đầy đủ của hình lục giác, một loại đối xứng khác phải được xem xét. Mỗi vật rắn (được xây dựng từ 1) có một vật rắn bổ sung (được xây dựng từ 0). Trong đó N là số lẻ, chất rắn bổ sung phải khác với chất rắn ban đầu (vì chúng không thể có cùng số khối). Tuy nhiên, khi vật rắn bổ sung được quay tròn, người ta sẽ thấy rằng biểu diễn 2D của nó như là một viên kim cương giống hệt nhau (ngoại trừ thao tác đối xứng 2 lần) với vật rắn ban đầu. Trong đó N là chẵn, có thể cho vật rắn tự nghịch đảo.

Điều này có thể được nhìn thấy trong các ví dụ cho N = 2 trong câu hỏi. Nếu nhìn từ bên trái, hình lục giác đầu tiên trông giống như một khối lập phương rắn với 8 hình khối nhỏ, trong khi hình lục giác cuối cùng trông giống như một cái vỏ rỗng với 0 hình khối nhỏ. Nếu nhìn từ bên phải, điều ngược lại là đúng. Các hình lục giác thứ 3, 4 và 5 và các hình lục giác thứ 16, 17 và 18 trông giống như chúng chứa 2 hoặc 6 khối, và do đó chúng bổ sung cho nhau theo 3 chiều. Chúng có liên quan với nhau theo 2 chiều bằng thao tác đối xứng 2 lần (xoay 2 lần hoặc phản chiếu về một trục qua các cạnh của hình lục giác.) Mặt khác, các hình lục giác 9, 10, 11 và 12 hiển thị các mẫu 3D. là những bổ sung riêng của họ, và do đó có tính đối xứng cao hơn (do đó đây là những mẫu duy nhất có bội số lẻ).

Lưu ý rằng có (N ^ 3) / 2 hình khối là điều kiện cần để tự bổ sung, nhưng nói chung nó không phải là điều kiện đủ nếu N> 2. Kết quả của tất cả điều này là đối với N lẻ, độ nghiêng luôn xảy ra theo cặp (N ^ 3) / 2 khối phải được kiểm tra cẩn thận.

Mã hiện tại (tạo tổng số đúng cho N = 1,2,3,5. Lỗi như đã thảo luận cho 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]);    
}

Đầu ra

Chương trình tạo ra một bảng đầu ra gồm 8 mục, phù hợp với 8 đối xứng của vật rắn. Vật rắn có thể có bất kỳ 4 đối xứng như sau (ký hiệu Schoenfly)

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)

Ngoài ra, khi vật rắn có chính xác một nửa các ô có 1 và một nửa bằng 0, sẽ tồn tại khả năng lật tất cả các số 1 và 0, sau đó đảo ngược tọa độ qua tâm của không gian khối. Đây là những gì tôi đang gọi là tự bổ sung, nhưng một thuật ngữ toán học hơn sẽ là "đối xứng đối với một trung tâm đảo ngược."

Thao tác đối xứng này cho trục xoay 2 lần trong lát hình lục giác.

Các mẫu có đối xứng này được liệt kê trong một cột riêng. Chúng chỉ xảy ra khi N chẵn.

Số lượng của tôi có vẻ hơi giảm cho N = 4. Trong cuộc thảo luận với Peter Taylor, có vẻ như tôi không phát hiện ra những con nghiêng chỉ có sự đối xứng của một đường thẳng qua các cạnh lục giác. Điều này có lẽ là do tôi chưa thử nghiệm tự bổ sung (đối xứng) cho các hoạt động khác ngoài (đảo ngược) x (nhận dạng.) Thử nghiệm để tự bổ sung cho các toán hạng (đảo ngược) x (phản xạ) và (đảo ngược) x (xoay 3 lần ) có thể phát hiện ra các đối xứng bị thiếu. Sau đó, tôi sẽ mong đợi dòng đầu tiên của dữ liệu cho N = 4 trông như thế này (16 ít hơn ở c1 và 32 nữa ở C1):

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

Điều này sẽ mang lại tổng số phù hợp với câu trả lời của Peter và https://oeis.org/A066931/a066931.txt

sản lượng hiện tại như sau.

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

Danh sách việc cần làm (cập nhật)

Dọn dẹp mã hiện tại.

Xong, nhiều hay ít

Thực hiện kiểm tra đối xứng cho lớp hiện tại và truyền tham số cho tính đối xứng của lớp trước đó (không có điểm nào trong việc kiểm tra xem lớp cuối cùng có bất đối xứng không.)

Xong, kết quả cho N lẻ đồng ý với dữ liệu được công bố

Thêm một tùy chọn để chặn số đếm không đối xứng (nên chạy nhanh hơn nhiều)

Điều này có thể được thực hiện bằng cách thêm một điều kiện khác vào lệnh gọi đệ quy: if(s1 && m<n*3-2)f(m + 1,e+d,s1)Nó giảm thời gian chạy cho N = 5 từ 5 phút xuống còn khoảng một giây. Kết quả là dòng đầu tiên của đầu ra trở thành tổng rác (cũng như tổng số tổng thể) nhưng nếu tổng số đã được biết từ OEIS, số lượng nghiêng không đối xứng có thể được hoàn nguyên, ít nhất là cho số lẻ N.

Nhưng đối với N, số lượng chất rắn không đối xứng (theo đối xứng c3v) tự bù sẽ bị mất. Trong trường hợp này, một chương trình riêng dành riêng cho chất rắn có chính xác (N ** 3) / 2 ô có 1 có thể hữu ích. Với tính năng này có sẵn (và đếm chính xác), có thể thử N = 6, nhưng sẽ mất nhiều thời gian để chạy.

Thực hiện đếm các ô để giảm tìm kiếm lên tới (N ^ 3) / 2 khối.

Không được thực hiện, tiết kiệm dự kiến ​​sẽ được cận biên

Thực hiện kiểm tra đối xứng (rắn bổ sung) cho các mẫu chứa chính xác (N ^ 3) / 2 khối.

Xong, nhưng dường như có thiếu sót, xem N = 4.

Tìm một cách để chọn con số thấp nhất từ ​​vựng từ một con số không đối xứng.

Tiết kiệm không được mong đợi là tuyệt vời. Các số liệu bất đối xứng loại bỏ hầu hết điều này. Sự phản xạ duy nhất được kiểm tra là mặt phẳng qua trục y (x và z được tính sau bằng cách nhân với 3.) Các hình chỉ có đối xứng quay được tính ở cả hai dạng đối xứng của chúng. Có lẽ nó sẽ chạy nhanh gần gấp đôi nếu chỉ có một người được tính.

Để tạo điều kiện cho điều này, có thể cải thiện cách liệt kê các tọa độ trong mỗi lớp (chúng tạo thành các nhóm thoái hóa 6 hoặc 3, có thể là một nhóm 1 ở trung tâm chính xác của lớp.)

Thú vị nhưng có lẽ có những câu hỏi khác trên trang web để khám phá.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.