# MatrixManipulator practice problem

The `MatrixManipulator` practice problem is intended as practice with 2D arrays and with the nested loops commonly used to traverse them.

The `MatrixManipulator` practice problem requires extensive manipulation of 2D arrays of integers, including declaration, traversal and partial traversal. You must declare new 2D arrays with the correct dimensions and fill them with the correct values.

`MatrixManipulator` is not intended to simulate an AP style free response question and should not be used as part of a practice test or for practicing timing.

`Arrays.deepToString` is a method to quickly produce formatted output. It is not covered on the AP CS A Exam. The format of the output below has been adjusted for readability.

The Java files below include skeleton code for each method and a JUnit 5 tester for each method. See Running JUnit 5 tests.

## `addable` method

``````/**
* Determines if (first + second) is defined where +
* indicates matrix addition.
* @return true if matrix addition is defined, false otherwise.
*/
public static boolean addable(int[][] first, int[][] second)
``````

### `addable` explanation

`first` and `second` are addable if `first` has the same number of rows as `second` and `first` has the same number of `columns` as `second`.

### `addable` examples

``````int[][] mat1 = {
{1, 2, 3, 4, 5},
{6, 7, 8, 9, 10}
};

int[][] mat2 = {
{11, 12, 13, 14, 15},
{16, 17, 18, 19, 20}
};

System.out.println(MatrixManipulator.addable(mat1, mat2)); // prints true

mat2 = new int[][] {
{11, 12, 13, 14, 15, 21},
{16, 17, 18, 19, 20, 22}
};

System.out.println(MatrixManipulator.addable(mat1, mat2)); // prints false
``````

## `add` method

``````/**
* Performs (first + second) where + indicates matrix addition.
* Precondition: addable(first, second)
* @return the result of first + second.
*/
public static int[][] add(int[][] first, int[][] second)
``````

### `add` explanation

The sum of 2 matrices is a matrix with the same number of rows and columns as both operands. Each position in the result matrix is the sum of the values at the same position in each of the operands.

### `add` example

``````int[][] mat1 = {
{1, 2, 3, 4, 5},
{6, 7, 8, 9, 10}
};

int[][] mat2 = {
{11, 12, 13, 14, 15},
{16, 17, 18, 19, 20}
};

int[][] result = MatrixManipulator.add(mat1, mat2);

System.out.println(Arrays.deepToString(result)); // prints:
// [[12, 14, 16, 18, 20]
//  [22, 24, 26, 28, 30]]
``````

## `multiplyByScalar` method

``````/**
* Performs (scalar * matrix) where * indicates
* scalar multiplication of a matrix.
* Precondition: matrix.length > 0 && matrix[0].length > 0
* @return the result of scalar * matrix.
*/
public static int[][] multiplyByScalar(int scalar, int[][] matrix)
``````

### `multiplyByScalar` explanation

The result of multiplying a matrix by a scalar is a matrix with the same number of rows and columns. Each value in the result matrix is the result of multiplying the value at the corresponding position in the original matrix by the scalar.

### `multiplyByScalar` example

``````int[][] mat = {
{1, 2, 3, 4, 5},
{6, 7, 8, 9, 10}
};

int scalar = 2;

int[][] result = MatrixManipulator.multiplyByScalar(scalar, mat);

System.out.println(Arrays.deepToString(result)); // prints:
// [[2, 4, 6, 8, 10],
//  [12, 14, 16, 18, 20]]
``````

## `multipliable` method

``````/**
* Determines if (first * second) is defined where *
* indicates matrix multiplication.
* @return true if matrix multiplication is defined, false otherwise.
*/
public static boolean multipliable(int[][] first, int[][] second)
``````

### `multipliable` explanation

`first` and `second` are multipliable if the number of columns in `first` is equal to the number of rows in `second`.

### `multipliable` example

``````int[][] mat1 = {
{20, 21, 22, 23},
{24, 25, 26, 27},
{28, 29, 30, 31}
};

int[][] mat2 = {
{32, 33},
{34, 35},
{36, 37},
{38, 39}
};

System.out.println(MatrixManipulator.multipliable(mat1, mat2)); // prints true

mat2 = new int[][]{
{32, 33, 36},
{34, 35, 37},
{36, 37, 38},
{38, 39, 39}
};

System.out.println(MatrixManipulator.multipliable(mat1, mat2)); // prints true

mat2 = new int[][]{
{32, 33, 36},
{34, 35, 37},
{36, 37, 38},
{38, 39, 39},
{40, 41, 42}
};

System.out.println(MatrixManipulator.multipliable(mat1, mat2)); // prints false
``````

## `multiply(int[][], int, int[][], int)` method

``````/**
* Multiplies the specified row of first by the specified column of second.
* Precondition: first[row].length > 0 && first[row].length == second.length
* @return the result of multiplying the specified row and column.
*/
public static int multiply(int[][] first, int row, int[][] second, int col)
``````

### `multiply(int[][], int, int[][], int)` explanation

Multiplying a row of one matrix by a column of another matrix results in a single `int`. The value is calculated as the sum of the products of the corresponding values in the row of the first matrix and the column of the second matrix.

In the example below, the result of multiplying row `0` of `mat1` by column `0` of `mat2` is calculated as:
`20 * 32 + 21 * 34 + 22 * 36 + 23 * 38` is `3020`

The result of multiplying row `0` of `mat1` by column `1` of `mat2` is calculated as:
`20 * 33 + 21 * 35 + 22 * 37 + 23 * 39` is `3106`

### `multiply(int[][], int, int[][], int)` examples

``````int[][] mat1 = {
{20, 21, 22, 23},
{24, 25, 26, 27},
{28, 29, 30, 31}
};

int[][] mat2 = {
{32, 33},
{34, 35},
{36, 37},
{38, 39}
};

int row = 0, col = 0;
System.out.println(MatrixManipulator.multiply(mat1, row, mat2, col)); // prints 3020

row = 0; col = 1;
System.out.println(MatrixManipulator.multiply(mat1, row, mat2, col)); // prints 3106

row = 1; col = 0;
System.out.println(MatrixManipulator.multiply(mat1, row, mat2, col)); // prints 3580

row = 1; col = 1;
System.out.println(MatrixManipulator.multiply(mat1, row, mat2, col)); // prints 3682
``````

## `multiply(int[][], int[][])` method

``````/**
* Performs (first * second) where * indicates matrix multiplication.
* Precondition: multipliable(first, second)
* @return the result of first * second.
*/
public static int[][] multiply(int[][] first, int[][] second)
``````

### `multiply(int[][], int[][])` explanation

The result of multiplying `mat1` by `mat2` is a new matrix with the same number of rows as `mat`1 and the same number of columns as `mat2`. Each value in the product matrix is obtained by multiplying the corresponding row from `mat1` by the corresponding column from `mat2`.

In the example below, `result[0][1]`, `3106`, was obtained by multiplying row `0` in `mat1` by column `1` in `mat2`.

`result[2][1]`, `4258`, was obtained by multiplying row `2` in `mat1` by column `1` in `mat2`.

### `multiply(int[][], int[][])` example

``````int[][] mat1 = {
{20, 21, 22, 23},
{24, 25, 26, 27},
{28, 29, 30, 31}
};

int[][] mat2 = {
{32, 33},
{34, 35},
{36, 37},
{38, 39}
};

int[][] result = MatrixManipulator.multiply(mat1, mat2);

System.out.println(Arrays.deepToString(result)); // prints:
// [[3020, 3106],
//  [3580, 3682],
//  [4140, 4258]]
``````

## Solution & comments

See the MatrixManipulator solution or review it with AP CS Tutor Brandon Horn.

Comment on MatrixManipulator