Matrix Class with Dimension Checks
Problem
Make a Matrix type. Commands: set NAME R C v1 ... v(R*C) (store a matrix, filled row by row, print ok), add A B C (store A + B in C, print ok), mul A B C (store the matrix product of A and B in C, print ok), show NAME (print the rows, one line per row, numbers separated by spaces). If add needs equal sizes, or mul needs the columns of A to equal the rows of B, and this is not true, print dimension mismatch and change nothing.
Constraints
- 1 <= commands <= 50
- matrices up to 5 x 5
- values are small ints
Examples
Input
set a 2 2 1 2 3 4 set b 2 2 5 6 7 8 mul a b c show c
Output
ok ok ok 19 22 43 50
Solutions
The Matrix class holds the size together with the numbers, and the size rules live in the methods plus and times. The command loop never touches the numbers directly.
/*
* Problem : Run the commands.
* Input : Command lines.
* Output : Answer lines.
* Approach: Matrix class
* Time : O(n^3) per multiply
* Space : O(size)
* Java : 8 or newer.
*/
import java.util.Scanner;
public class Main {
// Step 1: A Matrix knows its size and its numbers. It checks the size rules itself.
static class Matrix {
final int rows;
final int cols;
final long[][] cells;
Matrix(int rows, int cols) {
this.rows = rows;
this.cols = cols;
this.cells = new long[rows][cols];
}
// Step 2: add and multiply return null when the sizes do not fit. The caller prints the message.
Matrix plus(Matrix other) {
if (rows != other.rows || cols != other.cols) {
return null;
}
Matrix result = new Matrix(rows, cols);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
result.cells[i][j] = cells[i][j] + other.cells[i][j];
}
}
return result;
}
Matrix times(Matrix other) {
if (cols != other.rows) {
return null;
}
Matrix result = new Matrix(rows, other.cols);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < other.cols; j++) {
for (int k = 0; k < cols; k++) {
result.cells[i][j] += cells[i][k] * other.cells[k][j];
}
}
}
return result;
}
}
// This method solves the task. It receives the input and returns the answer.
static String[] solve(String[] lines) {
java.util.Map<String, Matrix> store = new java.util.HashMap<String, Matrix>();
java.util.List<String> out = new java.util.ArrayList<String>();
for (String line : lines) {
String[] part = line.split(" ");
if (part[0].equals("set")) {
Matrix matrix = new Matrix(Integer.parseInt(part[2]), Integer.parseInt(part[3]));
for (int i = 0; i < matrix.rows * matrix.cols; i++) {
matrix.cells[i / matrix.cols][i % matrix.cols] = Long.parseLong(part[4 + i]);
}
store.put(part[1], matrix);
out.add("ok");
} else if (part[0].equals("show")) {
for (long[] row : store.get(part[1]).cells) {
StringBuilder text = new StringBuilder();
for (int j = 0; j < row.length; j++) {
text.append(j > 0 ? " " : "").append(row[j]);
}
out.add(text.toString());
}
} else {
Matrix left = store.get(part[1]);
Matrix right = store.get(part[2]);
Matrix result = part[0].equals("add") ? left.plus(right) : left.times(right);
if (result == null) {
out.add("dimension mismatch");
} else {
store.put(part[3], result);
out.add("ok");
}
}
}
return out.toArray(new String[0]);
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
java.util.List<String> all = new java.util.ArrayList<>();
while (scanner.hasNextLine()) {
String line = scanner.nextLine().trim();
if (!line.isEmpty()) {
all.add(line);
}
}
String[] lines = all.toArray(new String[0]);
System.out.println(String.join("\n", solve(lines)));
}
}
Hints (2)
- Which method checks the sizes for multiply?
- Why return null and not stop the program?