OEIS'in Genişletilmesi: Elmas Döşemelerin Sayılması


46

Söz veriyorum, bu diamong tiltleri için son mücadelem olacak (yine de). Parlak tarafta, bu mücadelenin ASCII sanatı ile ilgisi yok ve bir kod golfü de değil, bu yüzden bu aslında tamamen farklı.

Bu yüzden, sadece bir hatırlatma olarak, her altıgen üç farklı elmasla başlıklanabilir:

Sorulması gereken ilginç bir soru, belirli bir altıgen boyut için bu eğimlerin kaç tanesinin mevcut olduğudur. Görünüşe göre bu rakamlar oldukça iyi çalışılmıştı ve OEIS A008793'te bulunabilir .

Ancak, dönme ve yansıma için ne kadar eğim bulunduğunu sorarsak sorun daha da zorlaşıyor . Örneğin, N = 2 kenar uzunluğu için aşağıdaki 20 eğim mevcuttur:

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

Ancak bunların çoğu rotasyon ve yansıma altında aynıdır. Bu simetrileri hesaba katarsak , sadece 6 farklı eğim kalır:

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

   2        2        6        6        1        3

sayılar her döşemenin çokluğunu gösterir. Daha büyük altıgenler için ayrıca 4 ve 12 katlarına sahip eğimlerin de olduğunu unutmayın.

Simetriye kadar olan tilt sayısının daha az incelendiği anlaşılıyor. OEIS A066931 girişi yalnızca beş terimi listeler:

1, 1, 6, 113, 20174

burada birinci terim yan uzunluk N = 0ve son terim yan uzunluk içindir N = 4.

Bundan daha iyisini yapabileceğimize eminim!

Göreviniz, belirli bir yan uzunluk için eğim sayısını hesaplamaktır.

Bu . Puanım , makinemde 30 dakikaN içinde kodunuzun doğru sonucu ürettiği en yüksek kenar uzunluğu olacaktır . Bir eşitlik olması durumunda, ben sonucunu üretir gönderimi kabul edecek o en hızlı. N

Her zaman olduğu gibi, bağlayıcıyı kazanmayı zaten bildiğiniz sonuçları kodlamamalısınız. Çözülen algoritma çözen N = 3ile aynı olmalıdır N = 5.

Gönderiniz 4GB'tan fazla bellek kullanmamalıdır. Bu sınırın yakınında çalışıyorsanız, bunun için bir miktar boşluk bırakacağım, ancak sürekli olarak bu sınırın üzerindeyseniz veya çok fazla ötesine geçerseniz N, gönderiminiz için bunu hesaba katmayacağım.

Tüm gönderilerimi Windows 8 makinemde test edeceğim, bu nedenle tercih ettiğiniz dilin Windows'ta serbestçe kullanılabilir olduğundan emin olun. Bunun tek istisnası Mathematica'dır (çünkü bunun için lisansım var). Lütfen kodunuzu nasıl derleyeceğiniz / çalıştıracağınızla ilgili talimatları ekleyiniz.

Elbette, kendi zamanınızla daha fazla terim hesaplamaktan çekinmeyin (bilim ve diğerlerinin sayılarını kontrol etmeleri için), ancak cevabınızın puanı bu 30 dakika içinde belirlenecektir.


4
Çünkü o Not N = 6fazla 10 ^ 12 bir çıkış verir, yapıcı olmayan bir çözüm neredeyse kesin gerekli uzakta olduğunu elde etmektir.
Peter Taylor,

1
@PeterTaylor Geliştirilmesi için daha fazla yer sağlayacak umuyordum. Belki de önce sorun hakkında daha fazla bilgi edinmek için N = 5 yapabilen basit yapıcı cevaplar ve ardından tüm eğimleri inşa etmek zorunda kalmayan, ancak toplam sayıyı birkaç inşa edilmiş olandan daha fazla değerlendirebilen potansiyel hibrit yaklaşımlar ... ve eğer gerçekten şanslıysak belki analitik bir şey. :)
Martin Ender

2
Açık olanı belirtme riski altında, bana öyle geliyor ki, her bir fayans, örneğin (100, -100,100) gibi uzak bir bakış açısıyla bakıldığı gibi, birim küplerin bir tertibatının bir projeksiyonuna tekabül ediyor. Bunun, tilt yapma yükünü hafiflettiğini biliyorum.
DavidC

1
@DidCidher Gerçekten. Daha spesifik olarak, birim küplerin bu şekilde düzenlenmesi 3D Genç bir diyagramdır . (Belki bu birine yardımcı olur.)
Martin Ender

@DavidCarraher Büyük altıgene yeterince bakarsanız, onu Genç diyagramı olarak yorumlamanın 2 farklı yolu olduğunu göreceksiniz. Açıkça görünen yol (en azından benim için) üstte ve solda üst köşeden eksik 2x2x1 küboid ile düz bir alan görmek. Ama onu görmenin başka bir yolu var: 2x2x1 küboid içinde oturan o bölgede boş bir bölge. 60 derece eğmek yardımcı olabilir. Gözlerimi acıtıyor, ancak iki genç diyagramın da muhtemelen birinin yansımasıyla birbirine uyduğunu düşünüyorum. OEIS A008793 ifadelerinde çok dikkatli: " Genç diyagramları olan uçak bölümlerinin sayısı ..."
Level River St

Yanıtlar:


80

Cebir, grafik teorisi, Möbius inversiyonu, araştırma ve Java

Altıgenin simetri grubu, 12. sıradaki dihedral gruptur ve 60 derecelik bir dönme ve bir çap boyunca bir ayna çevirme ile üretilir. 16 alt gruba sahiptir, ancak bazıları önemsiz eşlenik olmayan gruplar halindedir (sadece yansımaları olanları 3 eksen seçeneği vardır), bu nedenle altıgen bir döşemenin sahip olabileceği temelde 10 farklı simetri vardır:

10 simetrinin görüntüleri

Üçgen bir kafes alt kümesinin elmas döşeme sayısı belirleyici olarak hesaplanabilir , bu nedenle ilk yaklaşımım altıgen simetrilerinin her biri için en az bu simetrilere sahip olan eğim sayısını hesaplamak için bir belirleyici oluşturmaktı. ; ve simetri grubu tam olarak her 10 vakadan her biri olan eğim sayısını hesaplamak için Möbius inversiyonunu pozetlerinin cebirinde (temel olarak dahil etme-hariç tutma ilkesinin genellemesi) kullanın . Bununla birlikte, simetrilerin bazıları kötü kenar koşullarına sahipti, bu yüzden üssel olarak birçok belirleyici üzerinde toplanmaya zorlandım. Neyse ki, elde edilen değerlern < 10OEIS'deki ilgili sekansları tanımlayabilmem ve bana kapalı bir formda (sonlu ürünlere izin veren "kapalı" bir değer için) bir araya getirebilmem için yeterli veri verdi. OEIS dizisi güncellemelerini haklı çıkarmak için hazırladığım resmi yazımda dizilerin bir kısmı ve ispatlara referanslar var .

İkili sayıma dikkat edildiğinde, on değerden dördünün düzgün bir şekilde iptal edildiği anlaşılıyor, bu yüzden sadece kalan altı taneyi hesaplamamız ve ağırlıklı bir toplam yapmamız gerekiyor.

Bu kod N=1000makinemde 30 saniyeden az sürüyor .

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
Sen gerçekten ölümlülerin arasında bir tanrısın. Çözümünüzü prestijli bir dergide yayınlamayı umuyorum.
Alex A.

Bu harika. BTW my (şu anda gönderilmedi) kodu, N = 5: 22231176 (12) +275 (4) +75328 (6) +352 (2) için 22306956 değerini verir; gariptir. Burada ne yaptığını bilmiyorum, simetrilerin parçalanması için uygun mu? N = 4 için ben senden 16 yaşındayım ve oeis.org/A066931/a066931.txt Bu referanstan, 16 çokluk 12'ye sahip olduğum gibi görünüyor. çok şaşırdım, hatta N bile benim için daha zor. Fakat garip N ile hiçbir sorunum yok ve 0 <N <4 için doğru cevapları alıyorum. Belirgin problemleri arayacak ve yarın kodumu postalayacağım.
Seviye River St

@steveverrill, gösterimi anlarsam, N = 5 için bunu 22231176 (12) + 75328 (6) + 275 (4) + 176 (2) yapar. Sanırım endeksi 2 olanları 2'ye bölülemiyorsunuz. (Tek sayılar için FWIW, hepsinde iki köşeden geçen bir simetri eksenine ve 3. sıradaki dönme simetrisine sahip).
Peter Taylor,

@ steveverrill ve N = 4 için tutarsızlığınız, iki kenarın orta noktalarından geçen bir simetri eksenine sahip numaraya mükemmel bir şekilde uyuyor gibi görünüyor.
Peter Taylor,

3
Bunu çözmen etkileyici. Sonunda matematikçi olmayanların izleyebileceği bir cevap göndereceğini umuyorum.
DavidC

15

C

Giriş

David Carraher tarafından yorumlandığı gibi, altıgen döşemeyi analiz etmenin en basit yolu, z yüksekliğinin aynı kalması veya artması gereken tamsayı yükseklik çubuklarıyla dolu bir x, y karesinin 3 boyutlu Genç Diyagramı ile izomorfizminden faydalanmak gibi görünüyordu. z ekseni yaklaştığında.

Simetri sayımı için uyarlanmaya daha elverişli toplamları bulmak için algoritmayı, üç kartezyen ekseninden birine olan önyargılı olan yayınlanmış algoritmadan daha fazla kullanmaya başladım.

Algoritma

Alanın geri kalanı sıfır içerdiğinde, x, y ve z düzlemlerinin hücrelerini 1'lerle doldurmaya başladım. Bu yapıldıktan sonra, desen katmanını katman katman yapıyorum, her katman menşe ile ortak bir 3D manhattan mesafesine sahip hücreleri içeren hücreleri oluşturuyorum. Bir hücre ancak altındaki üç hücrede 1 varsa 1 de içerebilir, bunlardan herhangi biri 0 içeriyorsa, hücre 0 olmalıdır.

Deseni bu şekilde oluşturmanın avantajı, her katmanın x = y = z çizgisi etrafında simetrik olmasıdır. Bu, her bir katmanın simetri için bağımsız olarak kontrol edilebileceği anlamına gelir.

Simetri kontrolü

Katı simetrileri aşağıdaki gibidir: x = y = z çizgisi etrafında 3 kat rotasyonu - altıgen merkez etrafında 3 kat rotasyonu; ve x = y = z çizgisini ve x, y, z -> eksenlerinin her birini altıgen köşelerden geçen çizgiler hakkında yansıtan 3 düzlem hakkında 3 x yansıma.

Bu sadece 6 kat simetriye kadar ekler. Altıgenin tam simetrisini elde etmek için başka tür bir simetri düşünülmelidir. Her katı (1'lerden inşa edilmiş) tamamlayıcı bir katıya sahiptir (0'dan yapılan). N'nin tuhaf olduğu yerlerde, tamamlayıcı katı, orijinal katıdan farklı olmalıdır (çünkü aynı sayıda küpü olması mümkün değildir). Yine tamamlayıcı katı yuvarlak hale getirildiğinde, bir elmas karo olarak 2D gösteriminin orijinal katı ile aynı olduğu (2 kat simetri işlemi hariç) olduğu görülecektir. N'nin olduğu yerde, katının kendi kendine ters olması mümkündür.

Bu, sorudaki N = 2 örneklerinde görülebilir. Soldan bakıldığında, ilk altıgen 8 küçük küp ile dolu bir küp gibi görünürken, son altıgen 0 küçük küp içeren boş bir kabuk gibi görünür. Sağdan bakıldığında, tersi geçerlidir. 3, 4 ve 5'inci altıgenler ve 16, 17 ve 18'inci altıgenler 2 veya 6 küp içeriyor gibi görünür ve böylece birbirlerini 3 boyutta tamamlarlar. 2-boyutlu bir simetri operasyonu (2-kat rotasyon veya altıgen kenarlarından bir eksen etrafındaki yansıma) ile 2 boyutta birbirleriyle ilgilidirler. bunlar kendi tamamlayıcılarıdır ve bu nedenle daha yüksek bir simetriye sahiptirler (bunlar bu nedenle tek çeşitlilikteki tek kalıplardır).

(N ^ 3) / 2 küpün olmasının kendi tamamlayıcısı olmak için gerekli bir şart olduğunu, ancak genel olarak N> 2 olması durumunda yeterli bir koşul olmadığını unutmayın. Tüm bunların sonucu, garip N için, her zaman çiftler halinde meydana gelen eğimlerin (N ^ 3) / 2 küplerin dikkatlice incelenmesi gerektiğidir.

Geçerli kod (N = 1,2,3,5 için doğru toplamı oluşturur. N = 4 için tartışıldığı gibi hata.)

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]);    
}

Çıktı

Program, katının 8 simetrisi uyarınca 8 girişli bir çıktı tablosu oluşturur. Katı, aşağıdaki gibi 4 simetriden birine sahip olabilir (Schoenflies notasyonu)

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)

Ek olarak, katı, hücrelerin 1 'i ve yarısı 0'lı hücrelerin tam yarısına sahip olduğunda, tüm 1'leri ve 0'ları çevirip, koordinatları küp boşluğun ortasından tersine çevirme olasılığı vardır. Ben buna kendi tamamlayıcı derim, ama daha matematiksel bir terim "bir inversiyon merkezine göre antisimetrik" olacaktır.

Bu simetri işlemi, altıgen döşemede 2 kat dönme ekseni sağlar.

Bu simetriye sahip desenler ayrı bir sütunda listelenir. Sadece N'nin olduğu yerde meydana gelirler.

Sayılarım N = 4 için biraz kapalı görünüyor. Peter Taylor ile tartışırken, altıgen kenarlardan sadece bir çizgi simetrisine sahip eğimleri tespit edemediğim anlaşılıyor. Bu muhtemelen (ters) x (kimlik) dışındaki işlemler için kendinden tamamlayıcı (antisimetri) testi yapmadığım için (inversiyon) x (kimlik). ) eksik simetrileri ortaya çıkarabilir. Daha sonra N = 4 için verilerin ilk satırının şöyle görünmesini beklerdim (c1'de 16, C1'de 32 daha):

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

Bu toplamları Peter'ın cevabına uygun hale getirir ve https://oeis.org/A066931/a066931.txt

akım çıkışı aşağıdaki gibidir.

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

Yapılacaklar listesi (güncellendi)

Mevcut kodu düzenleyin.

Yapıldı, az ya da çok

Mevcut katman için simetri kontrolü uygular ve önceki katmanın simetrisi için bir parametre iletir (son katmanın asimetrik olup olmadığını kontrol etmenin bir anlamı yoktur).

Bitti, garip N sonuçları yayınlanmış verilerle aynı fikirde

Asimetrik sayıları saymak için bir seçenek ekleyin (çok daha hızlı çalışması gerekir)

Bu özyineleme çağrısına başka bir koşul ekleyerek yapılabilir: if(s1 && m<n*3-2)f(m + 1,e+d,s1)N = 5 için çalışma süresini 5 dakikadan bir saniyeye düşürür. Sonuç olarak, çıktının ilk satırı toplam çöp haline gelir (toplam toplamlar gibi), ancak toplam OEIS'ten zaten biliniyorsa, asimetrik eğim sayısı, en azından garip N için sulandırılabilir.

Ancak N için bile, kendi kendine tamamlayıcı olan asimetrik (c3v simetrilerine göre) katıların sayısı kaybedilir. Bu durumda, katı maddelere adanmış tam bir (N ** 3) / 2 hücreli 1 ayrı bir program faydalı olabilir. Bu kullanılabilir durumdayken (ve doğru sayımla) N = 6 denemek mümkün olabilir, ancak çalışması uzun zaman alabilir.

Aramayı (N ^ 3) / 2 küp kadar azaltmak için hücre sayımı uygulayın.

Yapılmadı, tasarrufların marjinal olması bekleniyor

Tam (N ^ 3) / 2 küp içeren kalıpları kontrol etmek için simetri (tamamlayıcı katı) kontrolü uygulayın.

Tamam, ama ihmaller var gibi görünüyor, bakınız N = 4.

Asimetrik olandan en düşük en düşük rakamı seçmenin bir yolunu bul.

Tasarrufların bu kadar büyük olması beklenmiyor. Asimetrik şekilleri bastırmak, bunların çoğunu ortadan kaldırır. Kontrol edilen tek yansıma y ekseni boyunca düzlemdir (x ve z, daha sonra 3 ile çarpılarak hesaplanır). Sadece dönme simetrisine sahip şekiller, her iki enantiyomerik formunda sayılır. Belki sadece bir kişi sayılırsa neredeyse iki kat daha hızlı koşardı.

Bunu kolaylaştırmak için, muhtemelen her katmandaki koordinatların listelenme şeklini geliştirmek (katmanın tam merkezinde muhtemelen 1 olan bir grupla birlikte 6 veya 3 dejenere gruplar oluştururlar.)

İlginç ama muhtemelen sitede keşfedilecek başka sorular var.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.