337 - Interpreting Control Sequences

All about problems in Volume 3. If there is a thread about your problem, please use it. If not, create one with its number in the subject.

Moderator: Board moderators

htl
Experienced poster
Posts: 185
Joined: Fri Jun 28, 2002 12:05 pm
Location: Taipei, Taiwan

337 - Interpreting Control Sequences

Post by htl »

The code I sent doesn't get accepted. It got runtime error. But I rewrite it and check it, I don't know where the bugs are. Can someone help me?

[c]
#include<stdio.h>
#define YES 1
#define NO 0
void main(void)
{
int count,line,command,overwrite,move,row,col,x,y,tempx,tempy,z;
char screen[10][11],c,buffer[1000];
for(count=1;;count++)
{
scanf("%d",&line);
if(!line)
break;
for(x=0,y=0;x<line;x++)
{
fflush(stdin);
for(;(c=getchar())!='\n';y++)
buffer[y]=c;
}
buffer[y]='\0';
command=move=NO;
overwrite=YES;
row=col=0;
for(x=0;x<10;x++)
for(y=0;y<10;y++)
screen[x][y]=' ';
for(x=0;x<10;x++)
screen[x][10]='\0';
for(x=0;buffer[x]!='\0';x++)
{
if(buffer[x]=='^' && !command)
{
command=YES;
continue;
}
if(command && buffer[x]>='0' && buffer[x]<='9' && !move)
{
move=YES;
tempx=buffer[x]-'0';
continue;
}
if(command && !move)
{
if(buffer[x]=='b')
col=0;
else if(buffer[x]=='c')
for(y=0;y<10;y++)
for(z=0;z<10;z++)
screen[y][z]=' ';
else if(buffer[x]=='d' && row<9)
row++;
else if(buffer[x]=='e')
for(y=col;y<10;y++)
screen[row][y]=' ';
else if(buffer[x]=='h')
row=col=0;
else if(buffer[x]=='i')
overwrite=NO;
else if(buffer[x]=='l' && col>0)
col--;
else if(buffer[x]=='o')
overwrite=YES;
else if(buffer[x]=='r' && col<9)
col++;
else if(buffer[x]=='u' && row>0)
row--;
else if(buffer[x]=='^')
{
if(overwrite)
screen[row][col]='^';
else
{
for(y=9;y>col;y--)
screen[row][y]=screen[row][y-1];
screen[row][col]='^';
}
}
command=NO;
continue;
}
if(move)
{
tempy=buffer[x]-'0';
row=tempx;
col=tempy;
move=NO;
command=NO;
continue;
}
if(!overwrite)
for(y=9;y>col;y--)
screen[row][y]=screen[row][y-1];
screen[row][col]=buffer[x];
if(col<9)
col++;
}
printf("Case %d\n",count);
printf("+----------+\n");
for(x=0;x<10;x++)
printf("|%s|\n",screen[x]);
printf("+----------+\n");
}
}
[/c]

Caesum
Experienced poster
Posts: 225
Joined: Fri May 03, 2002 12:14 am
Location: UK
Contact:

Post by Caesum »

The only bug is in the way you handle the input, where you miss a linefeed out.

htl
Experienced poster
Posts: 185
Joined: Fri Jun 28, 2002 12:05 pm
Location: Taipei, Taiwan

Post by htl »

Caesum wrote:The only bug is in the way you handle the input, where you miss a linefeed out.
for(x=0,y=0;x<line;x++)
{
fflush(stdin);
for(;(c=getchar())!='\n';y++)
^^-->you mean this?
buffer[y]=c;
}

But the problem says "ends of lines in the input are to be ignored"
So I think the bugs should be in the other part of the code. Please
explain what you really mean exactly if I misunderstand.

Kamp
New poster
Posts: 18
Joined: Tue Mar 05, 2002 2:00 am
Location: Poland (3-city)
Contact:

Post by Kamp »

I sent your program to judge, and I got "Compile Error" :cry:

Check once again your code :)

Good Luck :P

10153EN
Experienced poster
Posts: 148
Joined: Sun Jan 06, 2002 2:00 am
Location: Hong Kong
Contact:

Post by 10153EN »

No, I just got runtime error~

Caesum
Experienced poster
Posts: 225
Joined: Fri May 03, 2002 12:14 am
Location: UK
Contact:

Post by Caesum »

If you do
scanf("%d",&line);
and then
scanf("%c",&c);
what do you think c is ?

10153EN
Experienced poster
Posts: 148
Joined: Sun Jan 06, 2002 2:00 am
Location: Hong Kong
Contact:

Post by 10153EN »

Yes. And to htl, the fflush(stdin) only works for stdin inputs.

In OJ system, the inputs are fed from files, so in this case, this is what Caesum said, for example the input is as follows:
1
abcde
the first character c got is '\n', which means termination of the loop.

You can try to run your program by feeding inputs from file, like
p337 < p337.in
where p337.in is the input file

htl
Experienced poster
Posts: 185
Joined: Fri Jun 28, 2002 12:05 pm
Location: Taipei, Taiwan

Post by htl »

I've tested my code.(337 < a.in) I tested it with the data below

1
abcde
0

and the output is

Case 1
+----------+
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
+----------+
Case 2
+----------+
|abcde |
| |
| |
| |
| |
| |
| |
| |
| |
| |
+----------+

I use fflush() because I want to clear the '\n' in the buffer to
prevent the termination of reading string from reading the '\n'.
Is there another way to solve the reading data problem? I hope
someone can teach me how to do it.

10153EN
Experienced poster
Posts: 148
Joined: Sun Jan 06, 2002 2:00 am
Location: Hong Kong
Contact:

Post by 10153EN »

If you don't want to change your codes a lot, just change the line
scanf("%d",&line);
to
scanf("%d\n",&line);
A more convenient and faster way (but need to change your code :wink: ) is to use gets. gets will get a line until the \n character is read. So you don't need to read every character each time.
For example using the previous example:
1
abcde
0
The following program can read:
[c]
char aline[1000], buffer[1000];
int line;

gets(aline);
line = atoi(aline);
gets(buffer);
[/c]

htl
Experienced poster
Posts: 185
Joined: Fri Jun 28, 2002 12:05 pm
Location: Taipei, Taiwan

Post by htl »

I eventually got accepted and very thanks! I think I will change my way of giving data to the program. I always giving data by key in but now I think I should do it by file.

aakash_mandhar
New poster
Posts: 38
Joined: Thu Dec 11, 2003 3:40 pm
Location: Bangalore

Post by aakash_mandhar »

Plz help me. What seems to be the problem .. I guess one of the conditions is messed up somewher...

[c]
# include<stdio.h>
# include<conio.h>

char ch,c1,c2;
int n,i,j,k,insert,cc;
char a[10][10];
int r,c;

void write(char x)
{
/*
//printf("%d %d\n",r,c);
for(i=0;i<10;i++)
{
for(j=0;j<10;j++)
{
//if(a[j])
printf("%c",a[j]);
//else printf(" ");
}
printf("\n");
}
printf("\n");
*/
if(insert==1)
{
for(int i=8;i>=c;i--) a[r][i+1]=a[r];
}
a[r][c]=x;
if(c<9) c++;
return;
}

int main()
{
while(1)
{
scanf("%d",&n);
if(n==0) return 1;
++cc;
printf("Case %d\n",cc);
for(i=0;i<10;i++) for(j=0;j<10;j++) a[j]='\0';
r=0;c=0;
insert=0;
ch=fgetc(stdin);
for(k=0;k<n;k++)
{
ch=fgetc(stdin);
while(ch!='\n')
{
if(ch=='^') {
c1=fgetc(stdin);
if(c1>='0' && c1<='9') {c2=fgetc(stdin);r=c1-'0';c=c2-'0';}
if(c1=='b') c=0;
if(c1=='c') for(i=0;i<10;i++) for(j=0;j<10;j++) a[j]='\0';
if(c1=='d') if(r!=9) r++;
if(c1=='e') for(i=c;i<=10;i++) a[r]='\0';
if(c1=='h') {r=0;c=0;}
if(c1=='i') {insert=1;}
if(c1=='l') if(c) c--;
if(c1=='o') {insert=0;}
if(c1=='r') if(c<9) c++;
if(c1=='u') if(r) r--;
if(c1=='^') write('^');
}
else {if(ch!='\n') write(ch);}
//printf("%d %d\n",r,c);
ch=fgetc(stdin);
}
}
for(i=0;i<10;i++)
{
if(i==0) printf("+----------+\n");
printf("|");
for(j=0;j<10;j++)
{
//if(a[j])
printf("%c",a[j]);
//else printf(" ");
}
printf("|\n");
}
printf("+----------+\n");
}
}
[/c]

Thx in advance

Aakash :)
...I was born to code...

murtaza
New poster
Posts: 7
Joined: Tue Jul 20, 2004 7:42 pm
Location: India

337: Got TLE plz help

Post by murtaza »

I don't know why its giving TLE

CODE:
#include <stdio.h>
/**Getting a TLE ... i think for some input it might be
* getting stuck in a loop .... but can't figure out for which
* input
*/
#define OVERWRT 0
#define INSERT 1

int curXPos = 0;
int curYPos = 0;
char screen[ 10 ][ 11 ];
int mode = OVERWRT;


void printScreen( );
void clearScreen( );
main( )
{
int numLines;
char c;
int i , j;
int cases = 0;
scanf( "%d" , &numLines );
getchar( );
while( numLines > 0 )
{
cases ++;
clearScreen( );
curXPos = curYPos = 0;
mode = OVERWRT;
for( i = 0 ; i < numLines ; i++ )
{

while( ( c = getchar( ) ) != '\n' )
{
if( c == '^' )
{
/*control sequence*/
c = getchar( );
switch( c )
{
case 'b' :
curXPos = 0;
break;
case 'c' :
/*clear screen*/
clearScreen( );
break;
case 'd' :
curYPos = ( curYPos == 9 ? curYPos : curYPos + 1 );
break;
case 'e' :
i = curXPos;
while( i >= 0 )
{
screen[ curYPos ][ i ] = ' ';
i --;
}
break;
case 'h' :
curXPos = curYPos = 0;
break;
case 'i' :
mode = INSERT;
break;
case 'l' :
curXPos = ( curXPos == 0 ? curXPos : curXPos - 1 );
break;
case 'o' :
mode = OVERWRT;
break;
case 'r' :
curXPos = ( curXPos == 9 ? curXPos : curXPos + 1 );
break;
case 'u' :
curYPos = ( curYPos == 0 ? curYPos : curYPos - 1 );
break;
case '^' :
goto l1;
break;
default :{
curYPos = c - '0';
curXPos = getchar( ) - '0';
}
}
}
else
{
l1: /*non-control sequence*/
if( mode == OVERWRT )
{
screen[ curYPos ][ curXPos ] = c;
curXPos = ( curXPos == 9 ? curXPos : curXPos + 1 );
}
else
{
i = 9;
while( i > curXPos )
{
screen[ curYPos ][ i ] = screen[ curYPos ][ i - 1 ];
i --;
}
screen[ curYPos ][ curXPos ] = c;
curXPos = ( curXPos == 9 ? curXPos : curXPos + 1 );
}

}
}
}
printf( "Case %d\n" , cases );
printScreen( );
scanf( "%d" , &numLines );
getchar( );
}
}

void printScreen( )
{
int i , j , l;
printf( "+----------+\n" );
for( i = 0 ; i < 10 ; i ++ )
{
putchar( '|' );
printf( "%s" , screen[ i ] );
printf( "|\n" );
}
printf( "+----------+\n" );
}

void clearScreen( )
{
int i , j;
for( i = 0 ; i < 10 ; i ++ )
{
for( j = 0 ; j < 10 ; j ++ )
screen[ i ][ j ] = ' ';
screen[ i ][ 10 ] = '\0';
}
}

dumb dan
Learning poster
Posts: 67
Joined: Tue Aug 05, 2003 1:02 am

Post by dumb dan »

Code: Select all

for( i = 0 ; i < numLines ; i++ ) 
{

...

    case 'e' : 
      i = curXPos;

...

}
You use i for two different things at the same time!

beloni
Learning poster
Posts: 66
Joined: Thu Jan 05, 2006 1:41 pm
Location: Pelotas, RS, Brazil

Post by beloni »

hello, I think you have forget something:

first: your printScreen function

Code: Select all

void printScreen( )
{
   int i , j , l;
   printf( "+----------+\n" );
   for( i = 0 ; i < 10 ; i ++ )
      {
         putchar( '|' );
         printf( "%s" , screen[ i ] );
         printf( "|\n" );
     }
    printf( "+----------+\n" );
} 
must to write a box, according to the problem: Enclose the screen image in a "box;"
so if your screen have only 3 chars, the box won't be printed correctly, take my C++ code as example

Code: Select all

void Terminal::print() const
{
	cout << "+----------+" << endl;
	for( int w = 0; w < SIZE; w++ )
		{
			cout << "|";
			for( int i = 0; i < SIZE; i++ )
				if( !screen[w][i] )   // I used the 0 to indicates empty place
					cout << " ";
				else
					cout << screen[w][i];
			cout << "|" << endl;
		}
	cout << "+----------+" << endl;
}
second is just a sugestion: use gets to read your numLines input string (instead char-by-char), so you must to scan the input string to process each char. See below my C++ code as example:

Code: Select all

			for( int w = 0; w < numLines; w++ )
				{
					cin.getline( line, MAX );    // in C, use gets		
					for( int i = 0; line[i] != 0; i++ )
                                 // do something here
				}
I think is it, good luck
"A machine can do the work of fifty ordinary men, but no machine can do the work of one extraordinary man.", Shahriar Manzoor

avu
New poster
Posts: 1
Joined: Fri Sep 29, 2006 3:42 am

337 WA

Post by avu »

I'm stuck on 337 (Interpreting Control Sequences).
It works for test cases.
Can anyone provide a complicated input and output?

Post Reply

Return to “Volume 3 (300-399)”