C 929 878 Bytes
Das ist ein Monster, Leute. Es tut uns leid.
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);}}
Definiert 3 Funktionen f(int*,int), P(int*,int,int,int,int)und L(int). Rufen Sie auf L(n), und es wird an STDOUT ausgegeben.
Ausgabe für n=5:
14352
15342
31452
31542
41352
51342
41532
51432
24153
25143
34152
35142
23415
23514
24513
25413
24315
25314
24351
25341
Update: Ich habe Trennzeichen entfernt und den Code korrigiert. Der alte Code schlug nicht nur für n = 7 + fehl, sondern gab für n = 10 überhaupt nichts aus (oops!). Ich habe diesen Haufen gründlicher getestet. Es werden jetzt Eingaben von bis zu n = 13 unterstützt (obwohl "%d"geändert werden sollte, "%x"damit hexadezimal gedruckt wird). Die Größe der Eingabe ist abhängig von sizeof(long)und wird 8in der Praxis angenommen.
Hier ist eine Erklärung, wie es funktioniert und warum es so eine merkwürdige Einschränkung gibt:
Diese wurden häufig verwendet, daher definieren wir sie, um ein paar Bytes zu sparen:
typedef unsigned long U; typedef unsigned char C;
Hier ist 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;
}
fnimmt eine Reihe von ganzen Zahlen der Größe nund nsich. Das einzig clevere daran ist, dass es eine zurückgibt unsigned long, die char[8]von der aufrufenden Funktion in eine umgewandelt wird . Jedes Zeichen in dem Array wird somit entweder auf 0xFFeinen Index gesetzt oder auf einen Index, der auf ein gültiges Urinal für die nächste Person zeigt. Denn n<10wir brauchen nie mehr als 5 Bytes, um jedes gültige Urinal aufzunehmen, das die nächste Person benutzen kann.
Hier ist 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);
}
}
Pnimmt ein Array mit uder Größe an, auf das ngenau ein Element gesetzt ist 1, und der Rest ist 0. Es findet und druckt dann jede mögliche Permutation rekursiv.
Hier ist 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);
}
}
Lruft einfach P nmal mit unterschiedlichen startpositionen jedes mal auf.
Für die Interessierten wird dies (weniger Golf) fdie Sequenz in A095236 erzeugen .
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;
}