# Print a physical multiplication table

Rectangles have this nice property - an $$\n \times m\$$ rectangle consists of exactly $$\n \times m\$$ characters!

A.. more interesting property is that the rectangles can be aligned nicely in a multiplication table - for example, a $$\3 \times 3\$$ table:

# ## ###

# ## ###
# ## ###

# ## ###
# ## ###
# ## ###

Your challenge is to, given a number $$\n\$$ ($$\ n > 1\$$), output a formatted $$\n \times n\$$ multiplication table.

## Rules

• You can take the input one above or below $$\n\$$
• Default I/O rules apply
• You can choose any non-whitespace character to represent the blocks; every other character (though newlines are special) is considered whitespace. The chosen character can be different for different inputs, but must be the same throughout the input
• The result can have unneeded characters, as long as the table aligns up and there are no occurrences of the chosen character that aren't part of the required output
• The separators must be 1 character wide/tall, and the rectangles must be packed (i.e. no separators between their characters)
• The empty lines can be empty, padding isn't required
• The result can be a string, matrix, vector of lines, array of character arrays, or anything 2Dish
• You may alternatively output a matrix/vector-of-vectors/anything 2Dish of numbers, but the background & foreground must be 2 distinct numbers (which can vary input to input, but not throughout an output) and no other numbers can be present. Extra surrounding characters are allowed with this format too (though they must match the background number)
• This is , shortest answer in bytes, per-language, wins!

# Examples

For the input 2, a valid ascii-art output, with the character , is:

∙ ∙∙

Result: ∙ ∙∙.
∙ ∙∙

yes the period is there just to confuse you
Another valid answer as a number matrix, with 2 being the background number and 9 the foreground:

[[9,2,9,9,2,2],
[2,2,2,2,2,2],
[9,2,9,9,2,2],
[9,2,9,9,2,2]]

An invalid output example would be

#  # #

#  # #

#  # #

as the rectangles have separators in between them.

Example outputs for $$\4 \times 4\$$:

# ## ### ####

# ## ### ####
# ## ### ####

# ## ### ####
# ## ### ####
# ## ### ####

# ## ### ####
# ## ### ####
# ## ### ####
# ## ### ####

1 0 1 1 0 1 1 1 0 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0
1 0 1 1 0 1 1 1 0 1 1 1 1
1 0 1 1 0 1 1 1 0 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0
1 0 1 1 0 1 1 1 0 1 1 1 1
1 0 1 1 0 1 1 1 0 1 1 1 1
1 0 1 1 0 1 1 1 0 1 1 1 1
0 0 0 0 0 0 0 0 0 0 0 0 0
1 0 1 1 0 1 1 1 0 1 1 1 1
1 0 1 1 0 1 1 1 0 1 1 1 1
1 0 1 1 0 1 1 1 0 1 1 1 1
1 0 1 1 0 1 1 1 0 1 1 1 1
• Can we have extra row/columns of background characters in front, rather than at the end of the table? – Kirill L. Mar 16 '19 at 16:04
• @KirillL. sure, as long as the rows line up – dzaima Mar 16 '19 at 16:05
• Nitpick: ∙ (U+2219: BULLET OPERATOR) isn't present in the ASCII character set. Nor is • (U+2022: BULLET) or ⋅ (U+22C5: DOT OPERATOR) or · (U+00B7: MIDDLE DOT). :) – Andreas Rejbrand Mar 17 '19 at 12:55

f n=map=<<flip(map.max)$show.(10^)=<<[1..n] Try it online! A clever approach by Ørjan Johansen outputting with 0's and 1's, generating each 10...00 part as the string representation of a power of 10. 111111111 101001000 111111111 101001000 101001000 111111111 101001000 101001000 101001000 Haskell, 49 bytes f n=map=<<flip(map.max)$[0^i|x<-[1..n],i<-[0..x]]

Try it online!

Generates a pattern like [1,0,1,0,0,1,0,0,0,...], then makes a 2D by taking the min of pairs. The pointfree weirdness saves 2 bytes over the more readable:

+g(s):'')(p='')

Try it online!

# JavaScript (ES7),  87 83  82 bytes

Saved 3 bytes thanks to @dzaima

Returns a binary matrix, which is built cell by cell.

n=>[...Array(n*(n+3)/2)].map((_,y,a)=>a.map(h=(z,x)=>(17+8*x)**.5%1&&(z||h(1,y))))

Try it online!

### How?

The width $$\w\$$ of the matrix is given by:

$$w=T_n+n-1={n+1\choose 2}+n-1=\frac{n(n + 3)}{2}-1$$

(NB: As allowed by the challenge rules, we output a matrix of width $$\w+1\$$ instead.)

Similarly, the cell located at $$\(X,Y)\$$ is empty if the following quadratic admits an integer root for either $$\k=X\$$ or $$\k=Y\$$:

$$\frac{x(x+3)}{2}-1-k=0\\ x^2+3x-2-2k=0$$

whose determinant is:

$$\Delta=9-4(-2-2k)=17+8k$$

• Not sure if it can save bytes, but the solution of that quadratic would be $\frac{-3\pm\sqrt{17+8k}}2$, so there would be an integer root if $\sqrt\Delta$ is odd, that is, $\Delta$ is an odd perfect square. – Erik the Outgolfer Mar 16 '19 at 19:18

# MATL, 14 10 bytes

:"@:Fv]g&*

This answer uses 1 for the blocks and 0 for the background

Try it at MATL Online

Explanation

% Implicitly grab the input as an integer, N
%   STACK: { 3 }
:    % Create an array from 1...N
%   STACK: { [1, 2, 3] }
"    % For each element M in this array
@: % Create an array from 1...M
%   STACK (for 1st iteration): { [1] }
%   STACK (for 2nd iteration): { [1; 0], [1, 2] }
%   STACK (for 3rd iteration): { [1; 0; 1; 2; 0], [1, 2, 3] }
F  % Push a zero to the stack
%   STACK (for 1st iteration): { [1], 0 }
%   STACK (for 2nd iteration): { [1; 0], [1, 2], 0 }
%   STACK (for 3rd iteration): { [1; 0; 1; 2; 0], [1, 2, 3], 0 }
v  % Vertically concatenate everything on the stack
%   STACK (for 1st iteration): { [1; 0] }
%   STACK (for 2nd iteration): { [1; 0; 1; 2; 0] }
%   STACK (for 3rd iteration): { [1; 0; 1; 2; 0; 1; 2; 3; 0] }
]
g    % Convert everything to be boolean (turns all non-zeros to 1)
%   STACK: { [1; 0; 1; 1; 0; 1; 1; 1; 0] }
&*   % Perform element-wise multiplication to expand this array out into the 2D grid
% Implicitly display the result

1ẋⱮj0ȧþ

Try it online!

# APL (Dyalog Unicode), 1210 12 bytesSBCS

∘.×⍨∊,\0,⎕⍴1

Try it online!

Edit: -2 bytes from ngn. +2 bytes because the previous answers were invalid (with idea thanks to ngn and dzaima).

## Explanation

∘.×⍨∊,\0,⎕⍴1

⎕    Take input.
⍴1  An array of 1s of length our input. Example: 1 1 1
0,      Prepend a 0. Example: 0 1 1 1
,\        Take all the prefixes and concatenate them. Example: 0  0 1  0 1 1  0 1 1 1
∊          Flatten the list. Example: 0 0 1 0 1 1 0 1 1 1
∘.×⍨           Turn the above list into a multiplication table of 0s and 1s
by multiplying the list with itself.

The output should look like:

0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 1 0 1 1 0 1 1 1
0 0 0 0 0 0 0 0 0 0
0 0 1 0 1 1 0 1 1 1
0 0 1 0 1 1 0 1 1 1
0 0 0 0 0 0 0 0 0 0
0 0 1 0 1 1 0 1 1 1
0 0 1 0 1 1 0 1 1 1
0 0 1 0 1 1 0 1 1 1
• you could take input as to avoid the { } – ngn Mar 16 '19 at 17:31

# Jelly, 7 bytes

‘RÄṬ|þ

Try it online!

Outputs a digit matrix, using $$\0\$$ for the rectangles and $$\1\$$ for the padding between them. The TIO link contains a footer which formats a digit matrix in a human-readable way by lining up the rows and columns.

## Explanation

‘RÄṬ|þ
R       Take a range from 1 to
‘          {the input} plus 1
Ä      Cumulative sum; produces the first {input}+1 triangular numbers
Ṭ     Produce an array with 1s at those indexes, 0s at other indexes
þ   Create a table of {the array}
with itself
|      using bitwise OR

The number at cell $$\(x,y)\$$ of the resulting table will be $$\1\$$ if either $$\x\$$ or $$\y\$$ is a triangular number, or $$\0\$$ otherwise (because bitwise OR works like logical OR on 0 and 1). (We use R, range from 1, because Jelly uses 1-based indexing, so we don't have to worry about column 0 being incorrectly full of 0s; we have to add 1 to the input because the array produced by stops at the largest element given in the input, so we need to draw a line on the right-hand side and the bottom.) The gaps between triangular numbers are the consecutive integers, so the rectangular blocks formed by the gaps between the lines end up as the sizes requested by the question; and the use of an OR operation (in this case, bitwise) allows the lines to cross each other correctly.

• Why is this a community wiki?! If you want to waive rep you could just give it to Erik the Outgolfer – Jonathan Allan Mar 16 '19 at 22:09
• I CW all my answers (unless I think they might get a bounty, in which case I use a temporary account for them). Aiming for a high reputation normally means aiming to make the site worse (I once repcapped every day for a week to prove that it was possible; it wasn't particularly difficult, and yet it involved a lot of shallow questions/answers that didn't really contribute to the site much). Additionally, gaining reputation is mostly a negative on the account because it makes the site nag you into doing moderation work; and gaining privileges increases the risk of accidentally gaining badges. – ais523 Mar 16 '19 at 22:19
• Also, I mostly disagree with the concept of ownership of posts on SE (although mostly with questions rather than answers, but you can't CW a question without moderator help). A CW marker very clearly says "if something is wrong here, feel free to edit it"; so I'd be applying a CW marker to everything even if it didn't waive reputation. SE is meant to be part wiki, after all, but people don't always use it as that. – ais523 Mar 16 '19 at 22:21
• RE "aiming for a high reputation" if you don't want that then just post when you think it is meaningful and avoid what you term "shallow" q&a. Either you feel this answer does add something to the site, in which case post it without CW, or you think it is "shallow", in which case just don't post it. RE "I mostly disagree with the concept of ownership of posts on SE" - well you're simply on the wrong site then. – Jonathan Allan Mar 16 '19 at 22:35
• I think the answer adds something to the site, but if it's not CW, I feel compelled to post in a way that would gain me reputation rather than posting what I think would be interesting; back when I was a 20k user, I ended up really hating the site and almost got turned away from code golf in general because of it, so I deleted my account as a result. When I returned, I used to delete my account with every answer I posted (creating a new one for the next answer), but someone else pointed out that CWing every answer would have a similar effect, so nowadays I do that instead. – ais523 Mar 16 '19 at 22:39

# 05AB1E, 9 bytes

Defines a program $$\f\texttt{: }\color{purple}{\texttt{Nat}} →\color{purple}{\texttt{List}}\texttt{[}\color{purple}{\texttt{List}}\texttt{[}\color{purple}{\texttt{Nat}}\texttt{]]}\$$.

$L×0ýSDδ* Uses the 05AB1E-encoding. Try it online! or use the pretty-printed version. ### Explanation:$              # Push the number 1 and the input n
L             # Create the list [1, 2, 3, ..., n]
×            # Vectorized string multiplication: 1 × [1, 2, 3, ..., n]
This would result in ["1", "11", "111", ..., "1" × n]
0ý          # Join the resulting list with '0', resulting in "10110111011110111110..."
S         # Split into single digits: [1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, ...]
Dδ*      # Multiplication table with itself

# C# (Visual C# Interactive Compiler), 96 95 bytes

-1 byte thanks to Embodiment of Ignorance

n=>{var l="";for(;n>0;)l=new string('#',n--)+' '+l;for(;n<l.Length;)WriteLine(l[n++]>32?l:"");}

Try it online!

# Python 2, 67 bytes

s='';n=input()
while n:s='#'*n+' '+s;n-=1
for c in s:print(c>' ')*s

Try it online!

Prints blank lines for empty lines, which the challenge allows.

Same length (with input one above n):

r=range(input())
for n in r:print(' '.join(i*'#'for i in r)+'\n')*n

Try it online!

# Wolfram Language (Mathematica), 41 bytes

a#&/@(a=Flatten@Array[{0,1~Table~#}&,#])&

Try it online!

# Charcoal, 18 bytes

≔⪫ＥＮ×#⊕ι θＥθ⭆θ⌊⟦ιλ

Try it online! Link is to verbose version of code. Explanation:

Ｎ                Input number
Ｅ                 Map over implicit range
ι            Current value
⊕             Incremented
×               Repetitions of
#              Literal #
⪫                  Join with spaces
≔        θ          Assign to variable
θ        Retrieve variable
Ｅ         Map over characters
θ      Retrieve variable
⭆      Replace characters with
⌊     Minimum of
⟦    List of
ι   Row character
λ  Column character
Implicitly print each row on its own line

# Mouse-2002, 79 bytes

Abusing Mouse's macros to repeat functionality.

?1+n:#P,n,j,k,b#P,j,y,k,#P,n,i,' ,#P,i,x,35;;;;$P0 2%:(1%.2%.-^4%3%!'2%.1+2%:)@ Try it online! # C# (.NET Core), 208 155 bytes class M{static void Main(string[]a){int i=int.Parse(a[0]);var l="";for(;i>0;)l=new string('#',i--)+' '+l;for(;;)System.Console.WriteLine(l[i++]>32?l:"");}} Try it online! A much revised version thanks to various helpful people (see the comments). • 202? – ASCII-only Mar 18 '19 at 1:18 • 166, indexing fixed – ASCII-only Mar 18 '19 at 1:32 • @EmbodimentofIgnorance invalid, does not work for n >= 10... – ASCII-only Mar 18 '19 at 3:17 • @ASCII-only this works: tio.run/… – Gymhgy Mar 18 '19 at 3:22 • @Stackstuck Yes. A program is allowed to terminate by crashing – ASCII-only Mar 18 '19 at 3:23 # PowerShell, 42 40 bytes -2 bytes thanks to mazzy. ($r=1.."$args")|%{"$($r|%{'#'*$_})
"Xx$_+1)>>.say}o^* Try it online! Anonymous Callable that takes a number and prints the multiplication table with *s with a trailing newline. ### Explanation: { }o^* # Change the input to the range 0..n-1 (\*Xx$_+1)    # Cross string multiply '*' by all of range 1..n
# This creates the string "* ** *** ****" etc.
~"\n"                 # Append a newline
Xx$_+1 # Cross string multiply again ( )>>.say # And print all the lines ## Haskell, 69 68 bytes (a#b)0=[] (a#b)n=(a#b)(n-1)++b:(a<$[1..n])
f n=((1#0)n#(0<$(1#0)n))n Returns a matrix of numbers. Try it online! Variants of f with the same byte count: f n=((#)<*>(0<$)$(1#0)n)n f n|l<-(1#0)n=(l#(0<$l))n
• Do the 0 row and column help? – dfeuer Mar 16 '19 at 21:16
• @dfeuer: yes, they save a byte. See the first version of my answer. – nimi Mar 16 '19 at 22:18

# Stax, 7 bytes

é╫▐§╘←╘

Run and debug it

The chosen character is backtick. (How do you code format that in markdown?)

That means a and b are considered extraneous whitespace.

# MathGolf, 20 bytes

╒ÉÄ10;]h\■mÆε*╣¡§y╠n

Try it online!

MathGolf really needs to get some more functionality for splitting lists and creating 2D lists.

## Explanation

╒                      range(1,n+1)
É                     start block of length 3
Ä                    start block of length 1
1                   push 1
0                  push 0
]                end array / wrap stack in array
the stack now contains the list [1, 0, 1, 1, 0, 1, 1, 1, 0, 1, ...]
h               length of array/string without popping (used for splitting string)
\              swap top elements
■             cartesian product with itself for lists, next collatz item for numbers
m            explicit map
Æ           start block of length 5
ε*         reduce list by multiplication (logical AND)
╣¡       push the string " #"
§      get character at index 0 or 1 based on logical AND value
block ends here, stack is now ['#',' ','#','#',' ','#',...]
y     join array without separator to string
╠    pop a, b, push b/a (divides the string using the length of a single line)
n   join array of strings with newlines

# Ink, 151152 151 bytes

VAR k=0
=t(n)
~k=n
-(u)
~n--
{n+1:->s(k-n)->u}->->
=r(c)
->g(c)->
{k-c:<>->r(c+1)}->->
=g(n)
{n>1:@<>->g(n-1)}@->->
=s(n)
{n:
->r(1)->
->s(n-1)
}
.->->

Try it online!

Good thing the rules allow excess characters.

Edit: +1: Fixed spacing. Also, display using @ (which doesn't need escaping) instead of # (which does)

Edit: -1: Apparently that fix also meant I no longer needed a trailing period to force a newline on the non-empty lines. Neat.

• Ohh, I actually didn't even notice those spaces. I'll see if I can do something about them... – Sara J Mar 19 '19 at 15:24

## C++, 170 156 bytes

Thanks to dzaima

#include<string>
using v=std::string;v f(int a){v s;for(int i=1;i<=a;++i,s+='\n')for(int k=0;k<i;++k,s+='\n')for(int j=1;j<=a;++j)s+=v(j,'#')+' ';return s;}

# SmileBASIC, 83 77 bytes

Graphical output. Input is N-1

INPUT N
FOR J=0TO N
X=0FOR I=0TO N
GFILL X,Y,X+I,Y+J
X=X+I+2NEXT
Y=Y+J+2NEXT

# Python 3, 88 83 bytes

-5 bytes from Jo King

n,l=range(int(input())),''
for i in n:l+='#'*-~i+' '
for j in n:print((l+'\n')*-~j)

Try it online!

• You can save bytes by declaring l outside the loop. Try it online! – Jo King Mar 17 '19 at 11:52
• @JonathanFrech There's an extra space in the newline string – Jo King Mar 18 '19 at 2:31

## Perl 6, 63 bytes

{(1..$_).map(((1..$_).map("#"x*).join(" ")~"\n")x*).join("\n")}
• .join(' ') does nothing, '#' can be \* instead, the newline strings can use literal newlines, both l.map(str x*) can be (str Xx l) instead. 38 bytes – Jo King Mar 19 '19 at 5:38

# C (gcc), 108 104 bytes

-4 bytes thanks to ceilingcat

f(n,j){char*s,u[n*n],*t=s=u,i=0;for(;i++<n;*s++=32)for(j=i;j--;)*s++=35;for(s=t;*t;)puts(*t++>32?s:"");}

Try it online!