C(GCC) ,288个 285 282 293 292 272 271字节
- 通过摆弄两个后增量并用于循环放置,节省了三个字节。
- 通过摆弄另一个后置增量来节省三个字节,将两个变量初始化都移到分支之前-跳转
if(...)...k=0...else...,j=0...
到if(k=j=0,...)...else...
-并执行了索引移位。
- 通过支持
float
矩阵需要11个字节。
- 多亏了Xcoder先生,节省了一个字节;打高尔夫球
2*j+++1
去j-~j++
。
- 通过删除多余的
int
变量类型声明而不使用阶乘函数,而是使用已经存在的for循环来计算阶乘值,从而节省了20个字节。
- 通过高尔夫保存一个字节
S=S/F/(1<<n);
来S/=F*(1<<n);
。
float S,p,F;j,i;s(A,n,P,l,o,k)float*A;int*P;{if(k=j=0,o-l)for(;k<l;s(A,n,P,l,o+1))P[o]=k++;else{for(p=-l;j<l;j++)for(i=0;i<l;)p+=P[j]==P[i++];if(!p){for(F=p=1,j=0;j<n;F*=j)p*=A[P[2*j]*2*n+P[j-~j++]];S+=p;}}}float h(A,n)float*A;{int P[j=2*n];S=0;s(A,n,P,j,0);S/=F*(1<<n);}
在线尝试!
说明
float S,p,F; // global float variables: total sum, temporary, factorial
j,i; // global integer variables: indices
s(A,n,P,l,o,k)float*A;int*P;{ // recursively look at every permutation in S_n
if(k=j=0,o-l) // initialize k and j, check if o != l (possible permutation not yet fully generated)
for(;k<l;s(A,n,P,l,o+1)) // loop through possible values for current possible permuation position
P[o]=k++; // set possible permutation, recursively call (golfed into the for loop)
else{for(p=-l;j<l;j++) // there exists a possible permutation fully generated
for(i=0;i<l;) // test if the possible permutation is a bijection
p+=P[j]==P[i++]; // check for unique elements
if(!p){ // indeed, it is a permutation
for(F=p=1,j=0;j<n;F*=j) // Hafnian product loop and calculate the factorial (over and over to save bytes)
p*=A[P[2*j]*2*n+P[j-~j++]]; // Hafnian product
S+=p;}}} // add to sum
float h(A,n)float*A;{ // Hafnian function
int P[j=2*n];S=0; // allocate permutation memory, initialize sum
s(A,n,P,j,0); // calculate Hafnian sum
S/=F*(1<<n);} // calculate Hafnian
在线尝试!
在程序的核心是循环的以下生成器S_n
。所有Hafnian计算都基于此-并进一步打高尔夫球。
j,i,p;Sn(A,l,o,k)int*A;{ // compute every element in S_n
if(o-l) // o!=l, the permutation has not fully been generated
for(k=0;k<l;k++) // loop through the integers [0, n)
A[o]=k,Sn(A,l,o+1); // modify permutation, call recursively
else{ // possible permutation has been generated
for(p=-l,j=0;j<l;j++) // look at the entire possible permutation
for(i=0;i<l;i++)p+=A[j]==A[i]; // check that all elements appear uniquely
if(!p) // no duplicat elements, it is indeed a permutation
for(printf("["),j=0;j<l // print
||printf("]\n")*0;) // the
printf("%d, ",A[j++]);}} // permutation
main(){int l=4,A[l];Sn(A,l,0);} // all permutations in S_4
在线尝试!