APL 是一种数组编程语言,使用 Ken Iverson 于 1957 年发明的符号系统。在本题中,我们仅考虑该语言的一个小子集,我们称之为 apl(即 small APL)。
每个 apl 表达式单独占一行,每个表达式都有一个值,该值会在输入表达式后立即显示。apl 中的运算符不像 C、C++ 或 Java 那样具有优先级,而是从右向左应用。不过,可以使用括号来控制求值顺序。同样,二元运算符的操作数也按从右向左的顺序求值。以下是一些 apl 表达式的示例。
var = 1 2 3 |
将向量 1 2 3 存储在 var 中,替换其先前的值。表达式的值为 1 2 3。= 运算符的左操作数必须是一个变量。 |
var + 4 |
显示 var 的值,并将 4 加到其每个元素上(结果:5 6 7);var 的存储版本未被修改。 |
- / var |
显示 var 的值,就像在每一行的元素之间插入了 - 运算符一样(结果:2)。如果 var 有两个维度,结果是一个向量。如果 var 有三个维度,结果是一个二维数组。* / 和 + / 具有类似的行为。 |
iota 5 |
生成一个包含值 1 2 3 4 5 的向量。 |
2 2 rho 1 2 3 4 |
将向量 1 2 3 4 重塑为 2x2 数组;1 和 2 在第一行,3 和 4 在第二行。 |
2 2 rho 1 2 3 4 5 6 |
结果与上同。 |
2 3 rho 1 2 3 4 |
另一种重塑,产生第一行 1 2 3 和第二行 4 1 2;如果右参数没有足够的元素,则从头开始以行优先顺序重复使用右操作数的元素。 |
2 drop iota 5 |
结果:3 4 5。从 iota 5 中丢弃前两个元素。 |
1 2 * 3 4 |
结果:3 8。说明逐元素乘法。操作数必须是可兼容的——要么它们具有相同的形状,要么至少有一个是单元素向量(见第二个示例)。 |
( ( a = 1 ) drop 1 2 3 ) – 5 |
结果:-3 -2。说明括号的使用。 |
a + ( a = 5 ) + a + ( a = 6 ) |
结果:22。说明求值顺序。 |
在本题中,你需要编写一个 apl 解释器。输入中的整数是非负的且小于 $10^4$。所有计算出的整数值(包括中间值)的绝对值都小于 $10^4$。任何矩阵中的条目数始终小于或等于 $10^4$。变量名由一到三个小写字母组成,名称 iota、rho 和 drop 始终被解释为运算符。语句的元素(常量、变量、运算符和括号)之间恰好用一个空格分隔。
输入中的常量是向量。所有中间值都是具有正维度的一维、二维或三维数组。这限制了一些操作数的范围:“2 0 rho 1 2 3”、“2 3 2 1 rho 5”和“3 drop iota 3”是非法的。提供的唯一算术运算符是 +(加法)、-(减法)和 *(乘法)。它们的操作数是可兼容的,如示例所示。请注意,“1 1 rho 1”和“1 rho 1”具有不同的形状。iota 的操作数求值为一个单元素正向量。drop 的左操作数求值为一个单元素非负向量,其右操作数求值为一个向量。rho 的两个操作数都求值为向量。
输入格式
输入包含多个测试用例,每个用例单独占一行。在一个测试用例中分配的变量值可供后续测试用例使用。没有任何表达式的长度超过 80 个字符(包括空格)。没有任何测试用例会产生无效结果(例如,空向量)。
最后一个测试用例后面是一行包含单个字符 # 的行。
输出格式
对于每个测试用例,显示一行包含用例编号和输入行。然后,从下一行开始,显示求值表达式的结果。向量显示为单行整数;$m \times n$ 数组显示为 $m$ 行 $n$ 个值,$m \times n \times p$ 数组显示为 $m$ 个大小为 $n \times p$ 的数组,并用空行分隔 $n \times p$ 数组。同一行上的值应由空格分隔,但不需要在列中对齐。
样例
输入 1
var = 1 2 3 var + 4 - / var iota 5 2 2 rho 1 2 3 4 2 3 rho 1 2 3 4 2 drop iota 4 1 2 * 3 4 ( ( a = 1 ) drop 1 2 3 ) – 5 a + ( a = 5 ) + a + ( a = 6 ) ( 2 2 rho 2 drop iota 6 ) + 100 1 2 3 + 4 5 6 2 3 rho 1 2 3 4 5 + 1 2 3 4 5 + / 2 3 4 rho iota 2 * 3 * 4 ( 2 4 5 rho iota 2 * 4 * 5 ) - 99 #
输出 1
Case 1: var = 1 2 3 1 2 3 Case 2: var + 4 5 6 7 Case 3: - / var 2 Case 4: iota 5 1 2 3 4 5 Case 5: 2 2 rho 1 2 3 4 1 2 3 4 Case 6: 2 3 rho 1 2 3 4 1 2 3 4 1 2 Case 7: 2 drop iota 4 3 4 Case 8: 1 2 * 3 4 3 8 Case 9: ( ( a = 1 ) drop 1 2 3 ) - 5 -3 -2 Case 10: a + ( a = 5 ) + a + ( a = 6 ) 22 Case 11: ( 2 2 rho 2 drop iota 6 ) + 100 103 104 105 106 Case 12: 1 2 3 + 4 5 6 5 7 9 Case 13: 2 3 rho 1 2 3 4 5 + 1 2 3 4 5 2 4 6 8 10 2 Case 14: + / 2 3 4 rho iota 2 * 3 * 4 10 26 42 58 74 90 Case 15: ( 2 4 5 rho iota 2 * 4 * 5 ) - 99 -98 -97 -96 -95 -94 -93 -92 -91 -90 -89 -88 -87 -86 -85 -84 -83 -82 -81 -80 -79 -78 -77 -76 -75 -74 -73 -72 -71 -70 -69 -68 -67 -66 -65 -64 -63 -62 -61 -60 -59