home *** CD-ROM | disk | FTP | other *** search
- /*
- Problem 18:Expanding square codes
-
- One method of encoding messages is known as the "expanding square
- code." This method encodes messages by placing the characters of the
- message to be encoded in an odd order(1,3,5,7,9) square matrix row by
- row, and then retrieves them (decoding) in a clockwise expanding
- square spiral from the center of the matrix. If the message is not
- exactly the right length to fill the matrix, the rest of the matrix
- is filled with asterisk characters (*).
-
- For example, the two square matrices below show the order in which
- the characters are placed in a matrix(order 5), and the order in which
- they are to be retrieved. Notice that the order of retrieval begins
- at the center, then proceeds to the right, and then spirals
- clockwise.
-
- order in order out
-
- 1 2 3 4 5 21 22 23 24 25
- 6 7 8 9 10 20 7 8 9 10
- 11 12 13 14 15 19 6 1 2 11
- 16 17 18 19 20 18 5 4 3 12
- 21 22 23 24 25 17 16 15 14 13
-
- Examples:
-
- encode:
- message in: "This is a test message!"
-
- message out: "stssees a a**!egmtiThis "
-
- decode:
- message in: "anreh is io *.enotshAnd t"
-
- message out: "And this is another one."
-
- Your program should be able to encode and to decode messages by
- this method. The input will consist of pairs of lines; the first
- line in each pair will contain either the word encode or the word
- decode in lower case characters. The second line in each pair will
- consist of a message to be either encoded or decoded by the above
- method, containing a maximum of 80 characters. There will be no
- quotation marks (") surrounding the messages, and you should not
- output your messages with "'s.
-
- From the length of the message, you should determine the minimum
- odd order required for the matrix, and perform the specified operation.
- The output for each operation will consist of one blank line, the
- given message, and the resultant message. Each message should be
- on a separate line. A decoded message may not contain the asterisk
- characters used to fill the matrix in the encoding process. You
- may assume that no actual message contains an asterisk.
-
- Your program should continue reading input lines and performing
- operations until something other than the words encode or
- decode is encountered.
-
- Here is an actual run; the input file consisted of exactly four lines.
- The output file consists of exactly six lines; lines 1 and 4 are
- blank lines.
- This was the input file (the next four lines):
- encode
- now is the time for all
- decode
- imroft thee **lla snow i
- Here was the output file (the next six lines, NOTICE the blank lines!):
-
- now is the time for all
- imroft thee **lla snow i
-
- imroft thee **lla snow i
- now is the time for all
- */
- #include <stdio.h>
- #include <kindex.c>
- #define newline '\n'
- #define null '\0'
- int E[]={0,1};
- int S[]={1,0};
- int W[]={0,-1};
- int N[]={-1,0};
- int *dir;
- int x,y;
- int size;
- #define SZ 55
- int a[SZ+3][SZ+3];
-
- main(){
- int len,d,n,i,k,j,jj;
- char line[256];
-
- while( gets(line)==line){
- if(kindex(line,"encode")==0)goto encode;
- if(kindex(line,"decode")==0)goto decode;
- exit(0);
- encode:
- putchar(newline);
- gets(line);
- puts(line);
- for(i=0;i<=90;i++)if(line[i]==newline ||line[i]==null)break;
- line[i]=null;
- len=i;
- for(size=1;;size++,size++)if(size*size>=len)break;
- for(i=len;i<size*size;i++)line[i]='*';line[i]=null;
- for(i=1;i<=SZ;i++)for(k=1;k<=SZ;k++){a[i][k]= 0;}
- j=0;
- for(i=1;i<=size;i++)for(k=1;k<=size;k++){a[i][k]=line[j++];}
- /*
- for(i=1;i<=size;i++)
- {
- for(k=1;k<=size;k++){
- printf("%c",a[i][k]);
- }
- putchar(newline);}
- */
- x=y=(size+1)/2;
- n=size*size;
- dir=E;
- printf("%c",a[x][y]);
- for(k=1;k<=size;k++){
- for(j=1;j<=k;j++){
- d=godir();if(d>0)printf("%c",d); if(d<0)goto out;
- }
- nextdir();
- for(j=1;j<=k;j++){
- d=godir();if(d>0)printf("%c",d); if(d<0)goto out;
- }
- nextdir();
- }
- out:putchar(newline);
- goto getnextline;
-
- decode:
- /*for(i=0;i<=SZ;i++)for(j=0;j<=SZ;j++)a[i][j]=1;*/
- putchar(newline);
- gets(line);
- for(i=0;i<=90;i++)if(line[i]==newline ||line[i]==null)break;
- line[i]=null;
- puts(line);
- len=i;
- for(size=1;;size++,size++)if(size*size>=len)break;
- for(i=len;i<size*size;i++)line[i]=' ';line[i]=null;
- x=y=(size+1)/2;
- n=size*size;
- dir=E;
- jj=0;
- a[x][y]=line[jj++];
- for(k=1;k<=size;k++){
- for(j=1;j<=k;j++){
- d=godir();a[x][y]=line[jj++]; if(jj>n)goto out1;
- /* printf("x,y= %d %d\n",x,y);*/
- }
- nextdir();
- for(j=1;j<=k;j++){
- d=godir();a[x][y]=line[jj++]; if(jj>n)goto out1;
- /* printf("x,y= %d %d\n",x,y);*/
- }
- nextdir();
- }
- out1:
- jj=0;
- for(i=1;i<=size;i++)for(j=1;j<=size;j++)line[jj++]=a[i][j];
- for(i=0;i<100;i++)if(line[i]=='*')line[i]=null;
- puts(line);
- getnextline: ;
- }
- }
- godir()
- {
- x= x+ dir[0];
- y= y+ dir[1];
- if(y<1 || y>size)return -1;
- if(x<1 || x>size)return -1;
- return a[x][y];
-
- }
- nextdir()
- {
- if(dir==E){dir=S;return;}
- if(dir==S){dir=W;return;}
- if(dir==W){dir=N;return;}
- if(dir==N){dir=E;return;}
-
- }
-