#include < stdio.h >
#include < memory.h >
int LookUpTable[ 26 * 3 ];
void inverse( int size, int src[] )
... {
static int tmp[26],i;
for ( i = 0; i < size ; i++ ) ...{
tmp[src[i]] = i;
}
memcpy(src,tmp,sizeof(int)*size);
}
void multiply( int size, int src0[], int src1[], int dst[] )
... {
int i;
for ( i = 0 ; i < size; i++ ) ...{
dst[i] = src1[src0[i]];
}
}
void rotate( int size , int rotor[], int offset[], int * start)
... {
int idx,i;
// Rotate r1^{-1}
start[0] = (start[0] + size - 1) % size;
idx = start[0];
for ( i = 0 ; i < size ; i++ ) ...{
rotor[i] = LookUpTable[i + offset[idx] + size ];
idx = LookUpTable[idx + 1];
}
}
// Denote the rotor0, rotor1, rotor2 as r0, r1, r2.
int main()
... {
int size,i,j,cnt;
int enigmaCnt = 1;
int rotor[5][26];
char string[26][1001];
int flags[26];
int listLen;
int start,cur;
int curChar;
int starter[3];
int offset[3][26];
bool bChange;
int counter0,counter1;
int sizeSquare;
int *pTable;
do ...{
scanf( "%d ", &size );
if ( !size ) ...{
break;
}
if ( enigmaCnt != 1 ) ...{
printf(" ");
}
pTable = LookUpTable;
for ( j = 0 ; j< 3 ; j++ ) ...{
gets(string[0]);
for ( i = 0 ; i < size ; i++ )...{
rotor[j][i] = string[0][i]-'A';
offset[j][rotor[j][i]] = i - rotor[j][i];
// Init lookup table here.
*pTable++ = i;
}
// Let l = r0*r1*r2
// l^{-1} = r2^{-1}*r1^{-1}*r0^{-1}
inverse(size,rotor[j]);
}
// r3 = r2^{-1}*r1^{-1}
multiply(size,rotor[2],rotor[1],rotor[3]);
scanf( "%d ", &cnt );
printf( "Enigma %d: ",enigmaCnt++);
for ( i = 0; i < cnt - 1; i++ ) ...{
// Init input and linked list.
gets(string[i]);
flags[i] = i + 1;
}
gets(string[i]);
flags[i] = -1;
listLen = cnt;
// Init stage.
start = curChar = cur = 0;
bChange = false;
starter[0] = starter[1] = starter[2] = 0;
sizeSquare = size*size;
counter0 = counter1 = 0;
do...{
int last = cur;
int thisLen = listLen;
cur = start;
// Compute l^{-1} for current stage
// r2 changed.
if ( 0 == counter1 && curChar ) ...{
bChange = true;
rotate(size,rotor[2],offset[2],starter + 2);
}
// r1 changed.
if ( 0 == counter0 && curChar ) ...{
bChange = true;
rotate(size,rotor[1],offset[1],starter + 1);
}
if ( bChange ) ...{
bChange = false;
multiply(size,rotor[2],rotor[1],rotor[3]);
}
multiply(size,rotor[3],rotor[0],rotor[4]);
for ( i = 0 ; i < thisLen; i ++ ) ...{
// When current string is processed, delete it from list.
if
(
'