CS246-Position-and-Matrix

Note

You must use the C++ I/O streaming and memory management facilities on this request. Moreover, the only standard headers you may #include are iostream, fstream, sstream, iomanip, string, and utility. Marmoset will be programmed to reject submissions that violate these restrictions.

Each question on this request asks you to write a C++ program, and the programs you write on this request each span multiple files. Moreover, each question asks you to submit a Makefile for building your program. For these reasons, we strongly recommend that you develop your solution for each question in a separate directory. Just remember that, for each question, you should be in that directory when you create your zip file, so that your zip file does not contain any extra directory structure.

Questions on this request will be hand-marked to ensure that you are writing high quality code, and to ensure that your solutions employ the programming techniques mandated by each question.

Position

In this exercise, you will write a C++ class (implemented as a struct) to control a simple robotic drone exploring some terrain. Your drone starts at coordinates (0,0), facing north. Use the following structure definition for coordinates:

1
2
3
4
struct Position {
int ew, ns;
Position( int ew = 0, int ns = 0 );
};

The east-west direction is the first component of a position, and the north-south direction is the second. Your Drone class must be properly initialized via a constructor, and must provide the following methods:






























Method Description
void forward() Move the drone one unit forward.
void backward() Move the drone one unit backward.
void left() Turns the drone 90 degrees to the left, while remaining in the same location.
void right() Turns the drone 90 degrees to the right, while remaining in the same location.
Position current() Returns the current position of the drone.
int manhattanDistance() Returns the total units of distance travelled by the drone.

For simplicity, you may assume that the drone will never visit more than 50 positions before running out of fuel or otherwise breaking down.

Implement the specified operations for the Drone. (Some starter code has been provided for you in the file drone.h, along with a sample executable.) You may not change the contents of drone.h other than by adding your instance variables and comments i.e. the interface must stay exactly the same.

The test harness a3q1.cc is provided with which you may interact with your drone for testing purposes. The test harness is not robust and you are not to devise tests for it, just for the Drone class. Do not change this file.

Matrix

Consider the following class definition for a two-dimensional integer Matrix class:

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
class Matrix {
public:
// Requires numRows >= 0 && numCols >= 0.
// If both dimensions are 0, then array pointer is set to nullptr.
// If only one dimension is 0, also treat as 0x0 matrix; otherwise,
// allocate space and set values in 2-D array to 0--fill later using
// either operator>> or set().
Matrix( int numRows = 0, int numCols = 0 );
Matrix( const Matrix & ); // copy constructor
Matrix( Matrix && ); // move constructor
~Matrix();
Matrix & operator=( const Matrix & ); // copy request operator
Matrix & operator=( Matrix && ); // move request operator
Matrix operator+( const Matrix & ) const; // add two matrices
Matrix operator*( const Matrix & ) const; // multiply two matrices
int rows() const; // returns the number of rows in the matrix
int cols() const; // returns the number of columns in the matrix// Requires 0 <= row < this->rows() && 0 <= col < this->cols()
// Sets this's [row][col] == value
void set( int row, int col, int value );

// Requires 0 <= row < this->rows() && 0 <= col < this->cols()
// Returns this's [row][col]
int get( int row, int col ) const;

private:
// add your helper and instance variables here
};

Implement the specified constructors, destructor and request operators for the Matrix. (Some starter code has been provided for you in the file Matrix.h, along with a sample executable.) Further, you are to overload the input, output, addition, and multiplication operators as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Creates an empty matrix whose dimensions are 0x0 and the 2-D pointer is
// set to nullptr
Matrix m0;
cout << "m0 = " << m0 << endl; // Outputs "[]"
Matrix m1(2,3); // Creates a 2x3 matrix filled with 0s
m1.set(0,0,1); // Sets m1[0][0] = 1
Matrix m2(m1); // Calls the copy constructor to make a deep copy of m1 in m2
Matrix m3;

// Reads in the number of rows, the number of columns, and then the values from
// standard input.
cin >> m3;

// Outputs the matrix that is the sum of m1 and m2 (dimensions must be equal).
cout << "m1 + m2 =\n" << m1 + m2 << endl;

// Outputs the matrix that is the multiplication of m2 by m3, assuming
// their dimensions are compatible.
cout << "m2 * m3 =\n" << m2 * m3 << endl;

which produces the following output.

1
2
3
4
5
6
7
8
9
10
11
$ ./matrix < in.txt
m0 = []
m1 + m2 = 2 0 0
0 0 0
m2 * m3 = 1 0
0 0

$ cat in.txt
3 2
1 1 1
2 2 2

Some implementation notes follow:

  • In order to work more easily with the move operations (move constructor, move request operator), we have defined an empty matrix as one where the row and column dimensions are both set to 0 and the two-dimensional array pointer is set to nullptr.
    Thus, a matrix whose information is “stolen” becomes an empty matrix. The matrix “stealing” the information must be able to grow or shrink as necessary and not throw an error.

  • Use the language features to simplify how you handle reading in the matrix dimensions and values. It should be possible for any white space to be used to separate the numbers (spaces, tabs, newlines, etc.) and have the input operator work properly. You shouldn’t need to do anything complex, so don’t over-think it.

  • When outputting the values of the matrix, an empty matrix produces the string “[]”. A non-empty matrix outputs each row’s values on a separate line, and sets the width of the value to 4 (see the setw operator in the iomanip library). You are not required to handle values whose width (including the sign) exceed this size.

  • The declaration of the Matrix type can be found in the provided Matrix.h file. For your submission you must add all requisite declarations to Matrix.h and all routine and member definitions to Matrix.cc. The public interface to Matrix may not be changed.

  • The provided test harness, a3q2.cc, can be compiled with your solution to test (and then debug) your code. The test harness is not robust and you are not to devise tests for it, just for the Matrix class. Do not change this file. The test harness allows you to have up to 10 matrices defined at one time, identified as m0 to m9. If a matrix has not been initialized, it consists of a nullptr. Most of the test harness commands cannot be performed upon an uninitialized matrix, and the harness enforces this. Additionally, the user prompts are printed to standard error so that they will not interfere with the output produced, and thus make it easier to write your test files. The test harness also provides some simple error checking, such as ensuring that get/set are within the bounds of the matrix,and that matrix dimensions are compatible for addition and multiplication. If the commands do not meets its criteria, they are silently ignored. Thus, you are not required to test these cases and only need to test valid input.

  • Your Makefile must create an executable named matrix. Note that the executable name is case-sensitive.