J, 12 bytes - 3 = 9
(,~*/,)&($~) This defines a dyadic (meaning binary) verb, used as follows:
4 (,~*/,)&($~) 3 12 12 12 12 9 9 9 12 12 12 12 9 9 9 12 12 12 12 9 9 9 16 16 16 16 12 12 12 16 16 16 16 12 12 12 16 16 16 16 12 12 12 16 16 16 16 12 12 12 I also claim the 3-byte bonus, since an input of 0 produces sub-matrices of size zero:
4 (,~*/,)&($~) 0 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 16 0 (,~*/,)&($~) 3 9 9 9 9 9 9 9 9 9 Explanation
J has a definite edge in this challenge. In addition to eating array manipulation problems for breakfast, it prints 2D matrices in the correct format by default.
$~ For integer n, give array with n copies of n &( ) Apply it to each input (,~ ,) Concatenate these arrays in both ways */ Compute the multiplication table of the concatenations Appendix
There's also a 10-byte version (score of 7 with the bonus), which is basically a translation of this APL answer:
(|.*/])@#~ It takes a list of integers and returns a 2D array. Explanation:
#~ Produce n copies of each list element n ( )@ Pipe to the function in parentheses */ Compute multiplication table of |. ] the reversed and unmodified lists