Matrix Calculator
Time limit1sMemory limit128 MB
Parse and evaluate a matrix expression language with block matrices, transpose, indexing, and modular arithmetic, printing each assignment's resulting matrix.
- Level
Hard8 of 10
- Topics
- Recursion, Matrix, Implementation, String
- Solved
- No attempts yet
Problem
Dr. Jimbo is an applied mathematician who spends his days computing with matrices. In his lab he has a powerful program for manipulating matrix expressions, but it is too resource-hungry to run on his handheld computer. Write him a small program that evaluates matrix expressions.
Expressions are written in the simple language whose grammar is given below in BNF (a newline is written NL). Spaces and newlines are significant.
program ::= assignment | program assignment
assignment ::= var "=" expr "." NL
var ::= "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H"
| "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P"
| "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X"
| "Y" | "Z"
expr ::= term | expr "+" term | expr "-" term
term ::= factor | term "*" factor
factor ::= primary | "-" factor
primary ::= inum | var | matrix | "(" expr ")"
| indexed-primary | transposed-primary
indexed-primary ::= primary "(" expr "," expr ")"
transposed-primary ::= primary "'"
matrix ::= "[" row-seq "]"
row-seq ::= row | row-seq ";" row
row ::= expr | row " " expr
inum ::= digit | inum digit
digit ::= "0" | "1" | "2" | "3" | "4"
| "5" | "6" | "7" | "8" | "9"
A program is a sequence of assignments. Each assignment puts a variable (an uppercase letter A-Z) on the left of =, and a matrix expression on the right, terminated by a period . and a newline. It assigns the value of the expression to the variable. A value is a matrix of integers, and a scalar integer is interchangeable with the 1x1 matrix holding that integer.
An expression is one or more terms joined by + or -; a term is one or more factors joined by *; these binary operators are left-associative. A factor is a primary, or - followed by a factor, so unary minus is right-associative. For matrices A and B, A+B, A-B, A*B, and -A are the usual sum, difference, product, and negation. Addition and subtraction require equal sizes; multiplication requires the number of columns of A to equal the number of rows of B.
Every operation (+, -, *, and unary -) is computed modulo , so every value is an integer from to . For instance, 2-3 is 32767, not -1. An inum is a non-negative decimal integer less than , and a var denotes the matrix most recently assigned to it.
A matrix is a row-seq inside square brackets. A row-seq is a sequence of rows separated by semicolons ;; a row is a sequence of expressions separated by single spaces. For example, [1 2 3;4 5 6] is the 2x3 matrix with rows 1 2 3 and 4 5 6.
Row elements may themselves be matrices, so matrices can be nested (block matrices). Within a row the element matrices must all have the same number of rows and are joined side by side; the resulting row-blocks must all have the same number of columns and are stacked top to bottom. For example, [[1 2 3;4 5 6] [7 8;9 10] [11;12];13 14 15 16 17 18] is the 3x6 matrix
Sizes must stay consistent: [[1 2;3 4] [5;6;7];6 7 8] is invalid because in its first row a 2x2 matrix sits beside a 3x1 matrix, and [1 2;3 4 5] is invalid because its two rows have different widths.
Because a 1x1 matrix is a scalar, multiplying a 1x1 matrix by any m x n matrix is always defined and means scalar multiplication. For example 2*[1 2;3 4] and [1 2;3 4]*3 both scale the matrix, as do [2]*[1 2;3 4] and [1 2;3 4]*[3].
An indexed-primary is a primary followed by two index expressions, written P(rows,cols). The first index is a 1xk integer matrix and the second a 1xL integer matrix. The result is the kxL matrix whose (a,b) entry is the (i_a, j_b) entry of P, where the indices are one-based and may repeat. For example ([1 2;3 4]+[3 0;0 2])([1],[2]) is 2 (the (1,2) entry of [4 2;3 6]), and [1 2;3 4]([2 1 1],[2 1]) is the 3x2 matrix
A transposed-primary is a primary followed by a single quote ', denoting transpose: the transpose of an m x n matrix A=(a_ij) is the n x m matrix B with b_ij = a_ji. For example [1 2;3 4]' is [1 3;2 4].
Input
The input is several datasets, followed by a line containing a single 0. Each dataset has the form
n
program
where n () is the number of assignment statements, and program is those n assignments, one per line, each following the grammar above. All variables are undefined at the start of each dataset.
You may assume that each line has at most 80 characters (excluding the newline), that there are no syntax or semantic errors (for example, no use of an undefined variable), and that every matrix arising during evaluation has at most 100 rows and at most 100 columns.
Output
For each dataset, print the value of every assignment's expression, in order. Print each value as non-negative integers less than : for an m x n matrix print m lines, and on the k-th line print that row's entries separated by single spaces (a scalar is a single number on its own line).
After the last value of a dataset, print a line of exactly five minus signs -----. Print nothing else.