C, 929 878 byte
Đây là một con quái vật, các bạn. Lấy làm tiếc.
typedef unsigned long U;typedef unsigned char C;U f(int*u,n){C c[8],a[8];*(U*)(&c)=-1;int i,b=0,l=-9,s=-2,f=0,d;for (i=0; i<n; i++) {if (!u[i]&&s<0)s=i,l=0;if(!u[i])l++;if(u[i]&&s>=0){if(!s)l=2*l-1;d=(l-1)/2;if(b<d)*(U*)(a)=0,*(U*)(c)=-1,*c=s,*a=l,f=1,b=d;else if(b==d)c[f]=s,a[f++]=l;s=-1;}}if(s>=0&&l){l=2*l-1;d=(l-1)/2;if(b<d)*(U*)(c)=-1,*c=s,*a=l,f=1,b=d;else if(b==d)c[f]=s,a[f++]=l;}d=f;for(i=0;i<d;i++){if((c[i]+1)&&c[i]){if(c[i]+a[i]==n)c[i]=n-1;else{if(!(a[i]%2))c[f++]=b+c[i]+1;c[i]+=b;}}}return*(U*)c;}void P(int*u,n,i,c,m){for(i=0;i<n;i++){if(!u[i])c++;if(u[i]>m)m=u[i];}if(!c){for(i=0;i<n;i++)printf("%d",u[i]==10?0:u[i]);printf("\n");}else{int s[8][n];for(i=0;i<8;i++)for(c=0;c<n;c++)s[i][c]=u[c];U t=f(u,n);C*H=&t;for(i=0;i<8;i++)if((C)(H[i]+1))s[i][H[i]]=m+1,P(s[i],n,0,0,0);}}void L(n){int u[n],i,j;for(i=0;i<n;i++){for(j=0;j<n;j++)u[j]=j==i?1:0;P(u,n,0,0,0);}}
Định nghĩa 3 chức năng, f(int*,int)
, P(int*,int,int,int,int)
, và L(int)
. Gọi L(n)
và nó xuất ra STDOUT.
Đầu ra cho n=5
:
14352
15342
31452
31542
41352
51342
41532
51432
24153
25143
34152
35142
23415
23514
24513
25413
24315
25314
24351
25341
Cập nhật: Tôi đã xóa các dấu phân cách và sửa mã. Mã cũ không chỉ thất bại cho n = 7 +, mà còn không thể xuất bất cứ thứ gì cho n = 10 (rất tiếc!). Tôi đã kiểm tra kỹ hơn bó này. Bây giờ nó hỗ trợ đầu vào lên tới n = 13 (mặc dù "%d"
nên thay đổi thành để "%x"
in theo hệ thập lục phân). Kích thước của đầu vào phụ thuộc vào sizeof(long)
và nó được giả định là 8
trong thực tế.
Dưới đây là một số giải thích về cách thức hoạt động của nó và tại sao lại tồn tại một hạn chế kỳ lạ như vậy:
Chúng được sử dụng rất nhiều, vì vậy chúng tôi xác định chúng để lưu một vài byte:
typedef unsigned long U; typedef unsigned char C;
Đây là f
:
U f(int*u,n){
C c[8],a[8];
*(U*)(&c)=-1;
int i,b=0,l=-9,s=-2,f=0,d;
for (i=0; i<n; i++) {
if (!u[i]&&s<0)
s=i,l=0;
if(!u[i])
l++;
if(u[i]&&s>=0){
if(!s)
l=2*l-1;
d=(l-1)/2;
if(b<d)
*(U*)(a)=0,
*(U*)(c)=-1,
*c=s,
*a=l,
f=1,
b=d;
else if(b==d)
c[f]=s,a[f++]=l;
s=-1;
}
}
if(s>=0&&l){
l=2*l-1;
d=(l-1)/2;
if(b<d)
*(U*)(c)=-1,
*c=s,
*a=l,
f=1,
b=d;
else if(b==d)
c[f]=s,a[f++]=l;
}
d=f;
for(i=0;i<d;i++){
if((c[i]+1)&&c[i]){
if(c[i]+a[i]==n)
c[i]=n-1;
else{
if(!(a[i]%2))
c[f++]=b+c[i]+1;
c[i]+=b;
}
}
}
return*(U*)c;
}
f
mất một mảng các số nguyên kích thước n
, và n
chính nó. Thông minh duy nhất ở đây là nó trả về một unsigned long
, được chuyển đổi thànhchar[8]
bởi chức năng gọi. Do đó, mỗi ký tự trong mảng được đặt thành 0xFF
hoặc chỉ mục trỏ đến một bồn tiểu hợp lệ cho người tiếp theo. Đối với n<10
, chúng tôi không bao giờ cần nhiều hơn 5 byte để giữ mỗi bồn tiểu hợp lệ mà người tiếp theo có thể sử dụng.
Đây là P
:
void P(int*u,n,i,c,m){
for(i=0;i<n;i++){
if(!u[i])c++;
if(u[i]>m)m=u[i];
}
if(!c){
for(i=0;i<n;i++)
printf("%d",u[i]==10?0:u[i]);
printf("\n");
}
else{
int s[8][n];
for(i=0;i<8;i++)
for(c=0;c<n;c++)
s[i][c]=u[c];
U t=f(u,n);
C*H=&t;
for(i=0;i<8;i++)
if((C)(H[i]+1))
s[i][H[i]]=m+1,P(s[i],n,0,0,0);
}
}
P
mất một mảng u
kích thướcn
trong đó chính xác một phần tử được đặt thành 1
và phần còn lại là 0
. Sau đó, nó tìm và in mọi hoán vị có thể đệ quy.
Đây là L
:
void L(n){
int u[n],i,j;
for(i=0;i<n;i++){
for(j=0;j<n;j++)
u[j]=j==i?1:0;
P(u,n,0,0,0);
}
}
L
gọi đơn giản P
n
thời gian với các vị trí bắt đầu khác nhau mỗi lần.
Đối với người quan tâm, điều này (ít chơi gôn) f
sẽ tạo ra chuỗi trong A095236 .
U f(int*u,n) {
C c[8];
*(U*)(&c) = -1;
int i,b=0,l=-10,s=-2,f=0,d;
for (i=0; i<n; i++) {
if (!u[i]&&s<0) {
s=i,l=0;
}
if(!u[i]){
l++;
}
if (u[i]&&s>=0) {
if (!s) {
l=2*l-1;
}
if (b<l) {
*(U*)(&c)=-1;
c[0]=s;
f=1;
b=l;
}
else if (b==l)
c[f++]=s;
s=-1;
}
}
if (s>=0&&l) {
l=2*l-1;
if (b<l) {
*(U*)(&c)=-1;
c[0]=s;
f=1;
b=l;
}
else if (b==l)
c[f++]=s;
}
d=f;
for (i=0; i<d; i++) {
if ((c[i]+1)&&c[i]) {
if (c[i]+b==n) {
c[i]=n-1;
}
else{
if (!(b%2)) {
c[f++]=(b-1)/2+c[i]+1;
}
c[i]+=(b-1)/2;
}
}
}
return *(U*)c;
}