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

Best approachTime O(n^3) per multiplySpace O(size)

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.

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * 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)
  1. Which method checks the sizes for multiply?
  2. Why return null and not stop the program?