This challenge is related to some of the MATL language's features, as part of the May 2018 Language of the Month event.
Introduction
In MATL, many two-input functions work element-wise with broadcast. This means the following:
Element-wise (or vectorized): the function takes as inputs two arrays with matching sizes. The operation defined by the function is applied to each pair of corresponding entries. For example, using post-fix notation:
[2 4 6] [10 20 30] +
gives the ouput
[12 24 36]
This also works with multi-dimensional arrays. The notation
[1 2 3; 4 5 6]
represents the2
×3
array (matrix)1 2 3 4 5 6
which has size
2
along the first dimension (vertical) and3
along the second (horizontal). So for example[2 4 6; 3 5 7] [10 20 30; 40 60 80] *
[20 80 180; 120 300 560]
Broadcasting or (singleton expansion): the two input arrays do not have matching sizes, but in each non-matching dimension one of the arrays has size
1
. This array is implicitly replicated along the other dimensions to make sizes match; and then the operation is applied element-wise as above. For example, consider two input arrays with sizes1
×2
and3
×1
:[10 20] [1; 2; 5] /
Thanks to broadcasting, this is equivalent to
[10 20; 10 20; 10 20] [1 1; 2 2; 5 5] /
and so it gives
[10 20; 5 10; 2 4]
Similarly, with sizes
3
×2
and3
×1
(broadcasting now acts along the second dimension only),[9 8; 7 6; 5 4] [10; 20; 30] +
[19 18; 27 26; 35 34]
The number of dimensions may even be different. For example, inputs with sizes 3×2 and 3×1×5 are compatible, and give a 3×2×5 result. In fact, size 3×2 is the same as 3×2×1 (there are arbitrarily many implicit trailing singleton dimensions).
On the other hand, a pair of
2
×2
and3
×1
arrays would give an error, because the sizes along the first dimension are2
and3
: they are not equal and none of them is1
.
Definition of modular broadcasting
Modular broadcasting is a generalization of broadcasting that works even if none of the non-matching sizes are 1
. Consider for example the following 2
×2
and 3
×1
arrays as inputs of the function +
:
[2 4; 6 8] [10; 20; 30] +
The rule is as follows: for each dimension, the array that is smaller along that dimension is replicated modularly (cyclically) to match the size of the other array. This would make the above equivalent to
[2 4; 6 8; 2 4] [10 10; 20 20; 30 30] +
with the result
[12 14; 26 28; 32 34]
As a second example,
[5 10; 15 20] [0 0 0 0; 1 2 3 4; 0 0 0 0; 5 6 7 8; 0 0 0 0] +
would produce
[5 10 5 10; 16 22 18 24; 5 10 5 10; 20 26 22 28; 5 10 5 10]
In general, inputs with sizes a
×b
and c
×d
give a result of size max(a,b)
×max(c,d)
.
The challenge
Implement addition for two-dimensional arrays with modular broadcasting as defined above.
The arrays will be rectangular (not ragged), will only contain non-negative integers, and will have size at least 1
in each dimension.
Aditional rules:
Input and output can be taken by any reasonable means. Their format is flexible as usual.
Programs or functions are allowed, in any programming language. Standard loopholes are forbidden.
Shortest code in bytes wins.
Test cases
The following uses ;
as row separator (as in the examples above). Each test case shows the two inputs and then the output.
[2 4; 6 8]
[10; 20; 30]
[12 14; 26 28; 32 34]
[5 10; 15 20]
[0 0 0 0; 1 2 3 4; 0 0 0 0; 5 6 7 8; 0 0 0 0]
[5 10 5 10; 16 22 18 24; 5 10 5 10; 20 26 22 28; 5 10 5 10]
[1]
[2]
[3]
[1; 2]
[10]
[11; 12]
[1 2 3 4 5]
[10 20 30]
[11 22 33 14 25]
[9 12 5; 5 4 2]
[4 2; 7 3; 15 6; 4 0; 3 3]
[13 14 9;12 7 9;24 18 20;9 4 6;12 15 8]
[9 12 5; 5 4 2]
[4 2 6 7; 7 3 7 3; 15 6 0 1; 4 0 1 16; 3 3 3 8]
[13 14 11 16; 12 7 9 8; 24 18 5 10; 9 4 3 21; 12 15 8 17]
[6 7 9]
[4 2 5]
[10 9 14]
1
×n
(such as[1 2 3]
) orn
×1
(such as[1; 2; 3]
) \$\endgroup\$