C, 7 ข้อกำหนด
คำที่เจ็ดเป็น19846102 (หกตัวแรกคือ 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 ใช้เวลา 2m23s N = 8 อาจใช้เวลาสองสามสัปดาห์