How do I stop this program if it achieves it's objective

Basically we got rover and its movement is coded with number 1-4 ( 1 = x+1, y+1 and 2 = x+1, y-1 and so on). It's starting position is x0 and y0, BUT it's also it's objective ( It has to move in full circle from where it started ). What I wrote can complete it's orders, BUT I can't figure out how to stop it when it reaches it's target early.
this is data file:
1
2
3
4
5
1 1
3
9 1 4 1 2 3 2 3 4 1
1 1
3 2 3 2

First two numbers are x0 and y0.
second number is the amount of command sequences.(Next three strings of numbers )
first number in the sequence is the length of the string. So first has 9 commands and third has 3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <iostream>
#include <fstream>

using namespace std;

struct misija
{
    int seka[30];
    int sekosIlg;
    int komand=0;
    int galX, galY;
};

int main()
{
    misija uzd[10];
    ifstream duom ("U2.txt");

    int x0,y0;
    duom >> x0 >> y0;

    int n;
    duom >> n;

    for (int i=0; i<n; i++)
    {
        duom>>uzd[i].sekosIlg;
        for(int j=0; j<uzd[i].sekosIlg; j++)
        {
            duom >> uzd[i].seka[j];
        }
    }

    int dabarX=0,dabarY=0;
    for(int i=0; i<n; i++)
    {
        for (int j=0; j<uzd[i].sekosIlg; j++)
        {

            if(uzd[i].seka[j]==1)
            {
                dabarX+=1;
                dabarY+=1;
                uzd[i].komand++;
            }
            else if(uzd[i].seka[j]==2)
            {
                dabarX+=1;
                dabarY-=1;
                uzd[i].komand++;
            }
            else if(uzd[i].seka[j]==3)
            {
                dabarX-=1;
                dabarY-=1;
                uzd[i].komand++;
            }
            else if(uzd[i].seka[j]==4)
            {
                dabarX-=1;
                dabarY+=1;
                uzd[i].komand++;
            }

        }
        cout << dabarX << dabarY << endl;
    }

    return 0;
}


I have been trying lots of things, using while and do-while, if statements, but I can't find a way to solve it fully.
The results should be:
first sequence: "Completed" 1 1 after completing 8 commands.
second: "Failed" 2 2 after completing 1 given command
third: "Failed" 2 -2 after completing it's commands.
Splitting code into functions tends to help seeing the logic.
Pseudocode can do the same.
1. Get data
2. For each sequence
  - Process sequence


What should you do with one sequence?
1. Put rover to (x0,y0)
2. For each command
  a. handle command; move rover
  b. check if rover is at (x0,y0). If yes, then break
3. After commands rover is either at (x0,y0) [Completed] or not [Failed]
Last edited on
Put your sequence operation in a void function and return from that when you either get back to your starting point ("Completed") or reach the end of the sequence without ("Failed"). If you complete early then make sure to dump the rest of the sequence (which may or may not be on the same input line).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <iostream>
#include <sstream>
using namespace std;

struct pt{ int x, y; };

pt operator +( pt p, pt q ){ return { p.x + q.x, p.y + q.y }; }
bool operator ==( pt p, pt q ){ return p.x == q.x && p.y == q.y; }

ostream & operator <<( ostream &out, const pt &p ){ return out << p.x << " " << p.y; }
istream & operator >>( istream &in, pt &p ){ return in >> p.x >> p.y; }


void sequence( istream &in, pt p0 )
{
   pt moves[4] = { { 1, 1 }, { 1, -1 }, { -1, -1 }, { -1, 1 } };
   int nMoves, dir;
   
   pt p = p0;
   in >> nMoves;
   for ( int m = 0; m < nMoves; m++ )
   {
      in >> dir;
      p = p + moves[dir-1];
      if ( p == p0 ) 
      {
         cout << "Completed " << p0 << " after " << m + 1 << " commands\n";
         for ( int dump = m + 1; dump < nMoves; dump++ ) in >> dir;    // dump rest of sequence
         return;
      }
   }
   cout << "Failed " << p << " after " << nMoves << " commands\n";
}


int main()
{
   stringstream in( "1 1\n"
                    "3\n"
                    "9 1 4 1 2 3 2 3 4 1\n"
                    "1 1\n"
                    "3 2 3 2\n" );
   int numSeq;
   pt p0;
   
   in >> p0;
   in >> numSeq;
   for ( int seq = 0; seq < numSeq; seq++ ) sequence( in, p0 );
}


Completed 1 1 after 8 commands
Failed 2 2 after 1 commands
Failed 2 -2 after 3 commands
Last edited on
sadly it's bit too complicated for me, especially that it's high school level exercise, is there a simplier way of achieving the same result?
You are right, the actual program does not look short and simple:
1
2
3
4
5
6
7
8
9
10
11
int main()
{
   ifstream in( "U2.txt" );
   int numSeq;
   pt p0;
   in >> p0;
   in >> numSeq;
   for ( int seq = 0; seq < numSeq; seq++ ) {
      sequence( in, p0 );
   }
}

... or does it?

Is the "bit too" in the main(), in the sequence(), or elsewhere? We can explain some bits.

Sure, there are many ways to do it.
I'd imagine what wuwy means is that they haven't encountered operator overloading or stringstreams yet, and didn't realize that the stringstreams in this case are just being used as a convenient way to avoid having to create a file. And the operator overloading isn't bad, it's very intuitive to use with points/vectors.

wuwy, I suggest just slowly reading the program, line by line, and asking about what particular part looks too complicated or foreign.
Last edited on
Is this any easier, @wuwy?
I still think doing the sequence in a function makes things easier, because, where necessary, you could return early.

The switch block replaces your sequence of if statements.
The stringstream is just to fake file input, because that wouldn't be possible for demonstration purposes in CPP shell.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
#include <sstream>
#include <fstream>
using namespace std;

//=====================================================================================

void sequence( istream &in, int x0, int y0 )     // Carries out a single sequence
{                                                //    in is the stream; x0, y0 is the start point
   int nMoves, dir;
   
   int x = x0, y = y0;                           // Begin at x0, y0
   in >> nMoves;                                 // The first item on the sequence line is the number of commands
   for ( int m = 0; m < nMoves; m++ )
   {
      in >> dir;                                 // Read the command (1 - 4)
      switch( dir )                              // Make a move depending on the integer read (dir)
      {
          case 1: x++; y++; break;
          case 2: x++; y--; break;
          case 3: x--; y--; break;
          case 4: x--; y++; break;
      }
      if ( x == x0 && y == y0 )                  // Check if back at start; tidy up and return if so 
      {
         cout << "Completed " << x0 << " " << y0 << " after " << m + 1 << " commands\n";
         for ( int dump = m + 1; dump < nMoves; dump++ ) in >> dir;    // dump rest of sequence
         return;                                 // Returns early here if successful
      }
   }
   cout << "Failed " <<  x << " " << y << " after " << nMoves << " commands\n";
}

//=====================================================================================

int main()
{
// ifstream in( "U2.txt" );                      // File input
   stringstream in( "1 1\n"                      // Stringstream input just to simulate it in CPP shell
                    "3\n"
                    "9 1 4 1 2 3 2 3 4 1\n"
                    "1 1\n"
                    "3 2 3 2\n" );
   int numSeq;
   int x0, y0;
   
   in >> x0 >> y0;                               // First line: start point
   in >> numSeq;                                 // Second line: number of sequences
   for ( int seq = 0; seq < numSeq; seq++ )      // For each sequence, carry out the function
   {
      sequence( in, x0, y0 );
   }
}
Last edited on
Topic archived. No new replies allowed.