Estensione dell'OEIS: conteggio dei massimali diamantati


46

Lo prometto, questa sarà la mia ultima sfida sui tetti diamantati (almeno per un po '). Il lato positivo è che questa sfida non ha nulla a che fare con l'arte ASCII e non è nemmeno un codice golf, quindi in realtà è completamente diverso.

Quindi, come promemoria, ogni esagono può essere intitolato con tre diversi diamanti:

Una domanda interessante da porre è quanti di questi soffitti esistono per una data dimensione esagonale. Sembra che questi numeri siano stati studiati abbastanza accuratamente e possono essere trovati nell'OEIS A008793 .

Tuttavia, il problema diventa più complicato se chiediamo quanti limiti esistono fino alla rotazione e alla riflessione . Ad esempio, per la lunghezza del lato N = 2, esistono i seguenti 20 tetti:

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

Ma molti di questi sono identici sotto rotazione e riflessione. Se prendiamo in considerazione queste simmetrie, rimangono solo 6 distinzioni distinte:

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

   2        2        6        6        1        3

dove i numeri indicano la molteplicità di ogni piastrellatura. Si noti che per esagoni più grandi ci sono anche tetti con molteplicità 4 e 12.

Sembra che il numero di massimali fino alla simmetria sia stato studiato in modo meno approfondito. La voce OEIS A066931 elenca solo i cinque termini:

1, 1, 6, 113, 20174

dove il primo termine è per la lunghezza del lato N = 0e l'ultimo termine per la lunghezza del lato N = 4.

Sono sicuro che possiamo fare di meglio!

Il tuo compito è calcolare il numero di tasselli per una data lunghezza laterale.

Questo è . Il tuo punteggio sarà la massima lunghezza laterale Nper la quale il tuo codice produce il risultato corretto entro 30 minuti sulla mia macchina. In caso di pareggio, accetterò l'invio che produce il risultato per quello N più veloce.

Come al solito, non è necessario codificare i risultati che già conosci per vincere il tie-breaker. L'algoritmo che risolve N = 3dovrebbe essere identico a quello che risolve N = 5.

L'invio non deve utilizzare più di 4 GB di memoria. Daremo un po 'di margine su questo se stai operando vicino a quel limite, ma se sei costantemente al di sopra di quel limite, o se vai molto al di là di esso, non lo conto Nper la tua presentazione.

Proverò tutti gli invii sul mio computer Windows 8, quindi assicurati che la tua lingua preferita sia liberamente disponibile su Windows. L'unica eccezione a questo è Mathematica (perché mi capita di avere una licenza per questo). Includi le istruzioni su come compilare / eseguire il codice.

Naturalmente, sentiti libero di calcolare più termini nel tuo tempo (per la scienza e per gli altri per verificare il loro numero), ma il punteggio della tua risposta sarà determinato in quei 30 minuti.


4
Si noti che poiché N = 6fornisce un output superiore a 10 ^ 12, una soluzione non costruttiva è quasi certamente necessaria per arrivare così lontano.
Peter Taylor,

1
@PeterTaylor Speravo che potesse consentire più margini di miglioramento. Forse un paio di semplici risposte costruttive prima che possono fare N = 5 per ottenere maggiori informazioni sul problema, e quindi approcci potenzialmente ibridi che non hanno bisogno di costruire tutti i limiti ma possono estrapolare il numero totale da alcuni costruiti ... e poi forse qualcosa di analitico se siamo davvero fortunati. :)
Martin Ender il

2
A rischio di affermare l'ovvio, mi sembra che ognuna di queste piastrellature corrisponda a una proiezione di un assemblaggio di cubi di unità visti da un punto di vista distante, ad esempio da (100, -100,100). Trovo che questo alleggerisca l'onere della costruzione dei soffitti.
DavidC,

1
@DavidCarraher In effetti. Più specificamente, una tale disposizione di cubi unità è un diagramma di Young 3D . (Forse questo aiuta qualcuno.)
Martin Ender,

@DavidCarraher Se guardi abbastanza bene al grande esagono, vedrai che ci sono 2 modi diversi di interpretarlo come un diagramma Young. Il modo ovvio (almeno per me) è vedere un'area piatta in alto e a sinistra con un cuboide 2x2x1 mancante nell'angolo in alto a sinistra. Ma c'è un altro modo di vederlo: una zona vuota in quella zona, con un cuboide 2x2x1 seduto in essa. Inclinare di 60 gradi può aiutare. Mi fa male agli occhi ma penso che i due giovani diagrammi si incastrino, forse riflettendo uno di essi. OEIS A008793 è molto attento con la sua formulazione: "numero di partizioni piane i cui giovani diagrammi ..."
Level River St

Risposte:


80

Algebra, teoria dei grafi, inversione di Möbius, ricerca e Java

Il gruppo di simmetria dell'esagono è il gruppo diedrico dell'ordine 12 ed è generato da una rotazione di 60 gradi e da uno specchio che attraversa un diametro. Ha 16 sottogruppi, ma alcuni di essi sono in gruppi di coniugazione non banali (quelli che hanno solo riflessi hanno 3 scelte di assi), quindi ci sono 10 simmetrie fondamentalmente diverse che una piastrellatura dell'esagono può avere:

Immagini delle 10 simmetrie

Il numero di piastrellature diamantate di un sottoinsieme di un reticolo triangolare può essere calcolato come determinante , quindi il mio approccio iniziale era quello di impostare un determinante per ciascuna delle simmetrie dell'esagono, per calcolare il numero di tassellature che hanno almeno quelle simmetrie ; e quindi utilizzare l'inversione di Möbius nell'algebra dell'incidenza del loro poset (sostanzialmente una generalizzazione del principio di inclusione-esclusione) per calcolare il numero di tetti il ​​cui gruppo di simmetria è esattamente ciascuno dei 10 casi. Tuttavia, alcune delle simmetrie hanno condizioni sfavorevoli ai margini, quindi sono stato costretto a riassumere in modo esponenziale molti determinanti. Fortunatamente, i valori ottenuti pern < 10mi ha dato dati sufficienti per poter identificare sequenze rilevanti in OEIS e mettere insieme una forma chiusa (per un certo valore di "chiuso" che consente prodotti finiti). C'è un po 'di discussione sulle sequenze e riferimenti alle prove, nel redattore formale che ho preparato per giustificare gli aggiornamenti della sequenza OEIS.

Una volta preso in considerazione il doppio conteggio, si scopre che quattro dei dieci valori si annullano ordinatamente, quindi dobbiamo solo calcolare i sei rimanenti e quindi fare una somma ponderata.

Questo codice impiega meno di 30 secondi per N=1000sulla mia macchina.

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
Sei veramente un dio tra i mortali. Spero di vedere la tua soluzione pubblicata su una prestigiosa rivista.
Alex A.

Questo e spettacolare. A proposito il mio codice (attualmente non pubblicato) fornisce 22306956 per N = 5: 22231176 (12) +275 (4) +75328 (6) +352 (2), una discrepanza di 1, che è dispari. Non ho idea che tu stia facendo qui, è adatto per una ripartizione per simmetrie? Per N = 4 sono 16 più in basso di te e oeis.org/A066931/a066931.txt Da quel riferimento sembra che ho 16 troppi di molteplicità 12, che devo convertire in 32 di molteplicità 6. Non lo sono troppo sorpreso, anche N sono più difficili per me. Ma non ho problemi con N dispari e ottengo le risposte giuste per 0 <N <4. Cercherà ovvi problemi e pubblicherà il mio codice domani.
Level River St,

@steveverrill, se capisco la notazione, per N = 5 la faccio 22231176 (12) + 75328 (6) + 275 (4) + 176 (2). Penso che non riesci a dividere l'indice 2 per 2. (FWIW per i numeri dispari hanno tutti un asse di simmetria che passa attraverso due vertici e una simmetria rotazionale dell'ordine 3).
Peter Taylor,

@steveverrill, e per N = 4 la tua discrepanza sembra adattarsi perfettamente al numero che ha un asse di simmetria che passa attraverso i punti medi di due bordi.
Peter Taylor

3
Impressionante che tu abbia risolto questo. Spero che alla fine pubblichi una risposta che i non matematici possono seguire.
DavidC,

15

C

introduzione

Come commentato da David Carraher, il modo più semplice di analizzare la piastrellatura esagonale sembrava essere quello di sfruttare il suo isomorfismo con il diagramma giovane tridimensionale, essenzialmente un quadrato x, y riempito con barre di altezza intere le cui altezze z devono rimanere le stesse o aumentare quando si avvicina l'asse z.

Ho iniziato con un algoritmo per trovare i totali che è più suscettibile all'adattamento per il conteggio di simmetria rispetto all'algoritmo pubblicato, che si basa su una propensione per uno dei tre assi cartesiani.

Algoritmo

Comincio riempiendo le celle dei piani x, ye z con 1, mentre il resto dell'area contiene zeri. Una volta fatto ciò, costruisco il modello strato per strato, con ogni strato contenente le celle che hanno una distanza 3D comune di Manhattan dall'origine. Una cella può contenere un 1 solo se le tre celle sottostanti contengono anche un 1. se una di esse contiene uno 0, la cella deve essere uno 0.

Il vantaggio di costruire il modello in questo modo è che ogni livello è simmetrico rispetto alla linea x = y = z. Ciò significa che ogni strato può essere controllato indipendentemente per simmetria.

Verifica della simmetria

Le simmetrie del solido sono le seguenti: rotazione di 3 volte attorno alla linea x = y = z -> rotazione di 3 volte intorno al centro esagonale; e 3 x riflessioni sui 3 piani contenenti la linea x = y = z e ciascuno degli assi x, y, z -> riflessione sulle linee attraverso gli angoli esagonali.

Ciò aggiunge solo una simmetria di 6 volte. Per ottenere la simmetria completa dell'esagono, è necessario considerare un altro tipo di simmetria. Ogni solido (costruito da 1) ha un solido complementare (costruito da 0). Dove N è dispari, il solido complementare deve essere diverso dal solido originale (perché non è possibile che abbiano lo stesso numero di cubi). Tuttavia, quando il solido complementare viene girato, si scoprirà che la sua rappresentazione 2D come piastrellatura a diamante è identica (tranne per un'operazione di simmetria doppia) al solido originale. Dove N è pari, è possibile che il solido sia auto-inverso.

Questo può essere visto negli esempi per N = 2 nella domanda. Se visto da sinistra, il primo esagono sembra un cubo solido con 8 cubetti piccoli, mentre l'ultimo esagono sembra un guscio vuoto con 0 cubetti piccoli. Se visto da destra, è vero il contrario. Il 3 °, 4 ° e 5 ° esagono e il 16 °, 17 ° e 18 ° esagoni sembrano contenere 2 o 6 cubi, e quindi si completano a vicenda in 3 dimensioni. Sono collegati tra loro in 2 dimensioni mediante un'operazione di simmetria 2 volte (rotazione 2 volte o riflessione attorno ad un asse attraverso i bordi dell'esagono). D'altra parte gli esagoni 9, 10, 11 e 12 mostrano modelli 3D che sono i loro complementi e quindi hanno una simmetria più elevata (questi sono quindi gli unici schemi con strana molteplicità).

Notare che avere (N ^ 3) / 2 cubi è una condizione necessaria per essere auto-complemento, ma in generale non è una condizione sufficiente se N> 2. Il risultato di tutto ciò è che per N dispari, i soffitti si verificano sempre in coppie (N ^ 3) / 2 cubi devono essere attentamente ispezionati.

Codice corrente (genera il totale giusto per N = 1,2,3,5. Errore come discusso per 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]);    
}

Produzione

Il programma genera una tabella di output di 8 voci, in conformità con le 8 simmetrie del solido. Il solido può avere una delle 4 simmetrie come segue (notazione di 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)

Inoltre, quando il solido ha esattamente metà delle celle con 1 e metà con 0, esiste la possibilità di capovolgere tutti gli 1 e gli 0, quindi invertire le coordinate attraverso il centro dello spazio del cubo. Questo è ciò che chiamo auto-complemento, ma un termine più matematico sarebbe "antisimmetrico rispetto a un centro di inversione".

Questa operazione di simmetria fornisce un asse di rotazione di 2 volte nella piastrellatura esagonale.

I motivi che presentano questa simmetria sono elencati in una colonna separata. Si verificano solo dove N è pari.

Il mio conteggio sembra essere leggermente fuori per N = 4. Discutendo con Peter Taylor sembra che non stia rilevando dei tetti che hanno solo una simmetria di una linea attraverso i bordi esagonali. Questo è presumibilmente perché non ho testato l'auto-complemento (antisimmetria) per operazioni diverse da (inversione) x (identità.) Test per l'auto-complemento per gli operatoni (inversione) x (riflessione) e (inversione) x (rotazione 3 volte ) può scoprire le simmetrie mancanti. Mi aspetto quindi che la prima riga dei dati per N = 4 sia simile a questa (16 in meno in c1 e 32 in più in C1):

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

Ciò porterebbe i totali in linea con la risposta di Peter e https://oeis.org/A066931/a066931.txt

l'uscita corrente è la seguente.

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

Elenco di cose da fare (aggiornato)

Riordina il codice attuale.

Fatto, più o meno

Implementa il controllo di simmetria per il livello corrente e passa un parametro per la simmetria del livello precedente (non ha senso verificare se l'ultimo livello era asimmetrico).

Fatto, i risultati per N dispari concordano con i dati pubblicati

Aggiungi un'opzione per sopprimere il conteggio delle figure asimmetriche (dovrebbe essere eseguito molto più velocemente)

Questo può essere fatto aggiungendo un'altra condizione alla chiamata di ricorsione: if(s1 && m<n*3-2)f(m + 1,e+d,s1)riduce il tempo di esecuzione di N = 5 da 5 minuti a circa un secondo. Di conseguenza, la prima riga dell'output diventa immondizia totale (così come i totali complessivi) ma se il totale è già noto dall'OEIS, il numero di riquadri asimmetrici può essere ricostituito, almeno per N. dispari

Ma anche per N, il numero di solidi asimmetrici (secondo simmetrie c3v) che sono auto-complementi andrebbe perso. In questo caso, può essere utile un programma separato dedicato ai solidi con esattamente (N ** 3) / 2 celle con un 1. Con questo disponibile (e contando correttamente) potrebbe essere possibile provare N = 6, ma ci vorrà molto tempo per eseguirlo.

Implementa il conteggio delle celle per ridurre la ricerca fino a (N ^ 3) / 2 cubi.

Non fatto, il risparmio dovrebbe essere marginale

Implementare la simmetria (solido complementare) controllando gli schemi che contengono esattamente (N ^ 3) / 2 cubi.

Fatto, ma sembra avere omissioni, vedi N = 4.

Trova un modo per scegliere la figura lessicamente più bassa da una asimmetrica.

Non ci si aspetta che il risparmio sia così grande. Sopprimere le figure asimmetriche elimina gran parte di ciò. L'unica riflessione verificata è il piano attraverso l'asse y (x e z vengono calcolati successivamente moltiplicando per 3.) Le figure con solo simmetria rotazionale vengono contate in entrambe le loro forme enantiomeriche. Forse sarebbe quasi due volte più veloce se ne fosse contato solo uno.

Per facilitare ciò, possibilmente migliorare il modo in cui sono elencate le coordinate in ciascun livello (formano gruppi degeneri di 6 o 3, con possibilmente un gruppo di 1 nell'esatto centro del livello).

Interessante ma probabilmente ci sono altre domande sul sito da esplorare.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.