C、7項
7番目の用語は19846102です。(最初の6つは、質問で述べたように、1、1、2、22、515、56734です)。
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#define N 7
#define ctz __builtin_ctzl
typedef uint64_t u64;
static u64 board[N*N] = { 0 };
static u64 adjacency_matrix[N*N] = { 0 };
static u64 count = 0;
static u64 check_symmetry()
{
static const u64 symmetries[7][3] = {
{ 0, +N, +1 },
{ N-1, -1, +N },
{ N-1, +N, -1 },
{ N*N-1, -1, -N },
{ N*N-1, -N, -1 },
{ N*N-N, +1, -N },
{ N*N-N, -N, +1 },
};
int order[N];
for (u64 i = 0; i < 7; ++i) {
u64 start = symmetries[i][0];
u64 dcol = symmetries[i][1];
u64 drow = symmetries[i][2];
memset(order, 0xFF, N*sizeof(int));
for (u64 row = 0, col = 0; col < N || (col = 0, ++row < N); ++col) {
u64 base = board[col + N*row];
u64 symmetry = board[start + dcol*col + drow*row];
u64 lex = 0;
while (order[lex] != symmetry && order[lex] != -1)
++lex;
order[lex] = symmetry;
if (lex < base)
return 0;
if (base < lex)
break;
}
}
return 1;
}
static void recurse(u64 mino, u64 cell, u64 occupied, u64 adjacent, u64 forbidden)
{
if (cell >= N) {
++mino;
if (mino == N) {
count += check_symmetry();
return;
}
u64 next = ctz(~occupied);
board[next] = mino;
recurse(mino, 1, occupied | 1ul << next, adjacency_matrix[next], 0);
return;
}
adjacent &= ~occupied & ~forbidden;
while (adjacent) {
u64 next = ctz(adjacent);
adjacent &= ~(1ul << next);
forbidden |= 1ul << next;
board[next] = mino;
recurse(mino, cell + 1, occupied | 1ul << next, adjacent | adjacency_matrix[next], forbidden);
}
}
int main(void)
{
for (u64 i = 0; i < N*N; ++i) {
if (i % N)
adjacency_matrix[i] |= 1ul << (i - 1);
if (i / N)
adjacency_matrix[i] |= 1ul << (i - N);
if (i % N != N - 1)
adjacency_matrix[i] |= 1ul << (i + 1);
if (i / N != N - 1)
adjacency_matrix[i] |= 1ul << (i + N);
}
recurse(0, 2, 3, 4 | 3 << N, 0);
printf("%ld\n", count);
}
オンラインでお試しください!(N = 6の場合、N = 7はタイムアウトになるため。)
私のマシンでは、N = 6は0.171秒かかり、N = 7は2m23秒かかりました。N = 8には数週間かかります。