A pascal matrix is a two-dimensional square matrix holding numbers from   Pascal's triangle,   also known as   binomial coefficients   and which can be shown as   nCr.

Shown below are truncated   5-by-5   matrices   M[i, j]   for   i,j   in range   0..4. 


A Pascal upper-triangular matrix that is populated with   jCi:

[[1, 1, 1, 1, 1],
 [0, 1, 2, 3, 4],
 [0, 0, 1, 3, 6],
 [0, 0, 0, 1, 4],
 [0, 0, 0, 0, 1]]

A Pascal lower-triangular matrix that is populated with   iCj   (the transpose of the upper-triangular matrix):

[[1, 0, 0, 0, 0],
 [1, 1, 0, 0, 0],
 [1, 2, 1, 0, 0],
 [1, 3, 3, 1, 0],
 [1, 4, 6, 4, 1]]

A Pascal symmetric matrix that is populated with   i+jCi:

[[1, 1, 1, 1, 1],
 [1, 2, 3, 4, 5],
 [1, 3, 6, 10, 15],
 [1, 4, 10, 20, 35],
 [1, 5, 15, 35, 70]]



Task

Write functions capable of generating each of the three forms of   n-by-n   matrices.

Use those functions to display upper, lower, and symmetric Pascal   5-by-5   matrices on this page.

The output should distinguish between different matrices and the rows of each matrix   (no showing a list of 25 numbers assuming the reader should split it into rows).



Note
 
The   Cholesky decomposition   of a Pascal symmetric matrix is the Pascal lower-triangle matrix of the same size.




n := 5
MsgBox, 262144, ,% ""
. "Pascal upper-triangular :`n" show(Pascal_Upper(n))
. "`n`nPascal lower-triangular :`n" show(Pascal_Lower(n))
. "`n`nPascal symmetric:`n" show(Pascal_Symm(n))
return
 
show(obj){
	for i, o in obj{
		line := ""
		for j, v in o
			line .= v ", "
		res .= "[" Trim(line, ", ") "]`n,"
	}
	return "[" Trim(res, "`n,") "]"
}
 
Pascal_Upper(n){
	obj := fillObj(n)
	loop % n
		obj[1, A_Index] := 1
	loop % n-1
		obj[A_Index+1, 1] := 0
	for i, o in obj
		for j, v in o
			if !(i = 1 or j = 1)
				obj[i, j] := obj[i, j-1] + obj[i-1, j-1]
	return obj
}
 
Pascal_Lower(n){
	obj := fillObj(n)
	loop % n
		obj[A_Index, 1] := 1
	loop % n-1
		obj[1, A_Index+1] := 0
	for i, o in obj
		for j, v in o
			if !(i = 1 or j = 1)
				obj[i, j] := obj[i-1, j] + obj[i-1, j-1]
	return obj
}
 
Pascal_Symm(n){
	obj := fillObj(n)
	loop % n
		obj[A_Index, 1] := 1
	loop % n-1
		obj[1, A_Index+1] := 1
	for i, o in obj
		for j, v in o
			if !(i = 1 or j = 1)
				obj[i, j] := obj[i-1, j] + obj[i, j-1]
	return obj
}
 
fillObj(n){
	obj := []
	loop % n{
		i := A_Index
		loop % n
			obj[i, A_Index] := 0
	}
	return obj
}