# Pascal's triangle in tikz

I would like to typeset the top part of Pascal's triangle. To get the triangle with the names of the binomial coefficients, i.e., {n \choose k}, I used the following code

\begin{tikzpicture}
\foreach \n in {0,...,4} {
\foreach \k in {0,...,\n} {
\node at (\k-\n/2,-\n) {${\n \choose \k}$};
}
}
\end{tikzpicture}


The result is this

Now I want to be equally lazy and do something like this for the values of the binomial coefficients, i.e., replace {\n \choose \k} in the node label with \CalculateBinomialCoefficient{\n}{\k} where \CalculateBinomialCoefficient is a hypothetical macro that calculates the binomial coefficient. Has anyone done something like that?

The result should look like this:

• The code in Triangle de Pascal could give you some ideas; note the use of the \FPpascal macro implemented in fp-pas.sty (part of the fp package). May 6 '11 at 0:49
• For a better result I suggest to use the command \binom{a}{b} from the amsmath package instead of {a \choose b} for binomial coefficients May 6 '11 at 8:44

Here is a solution using TeX integer arithmetic. I am reusing counters defined by PGF in order to avoid having to declare new ones.

\documentclass{article}
\usepackage{tikz}

\makeatletter
\newcommand\binomialCoefficient[2]{%
% Store values
\c@pgf@counta=#1% n
\c@pgf@countb=#2% k
%
% Take advantage of symmetry if k > n - k
\c@pgf@countc=\c@pgf@counta%
\ifnum\c@pgf@countb>\c@pgf@countc%
\c@pgf@countb=\c@pgf@countc%
\fi%
%
% Recursively compute the coefficients
\c@pgf@countc=1% will hold the result
\c@pgf@countd=0% counter
\pgfmathloop% c -> c*(n-i)/(i+1) for i=0,...,k-1
\ifnum\c@pgf@countd<\c@pgf@countb%
\multiply\c@pgf@countc by\c@pgf@counta%
\divide\c@pgf@countc by\c@pgf@countd%
\repeatpgfmathloop%
\the\c@pgf@countc%
}
\makeatother

\begin{document}
\begin{tikzpicture}
\foreach \n in {0,...,15} {
\foreach \k in {0,...,\n} {
\node at (\k-\n/2,-\n) {$\binomialCoefficient{\n}{\k}$};
}
}
\end{tikzpicture}

\end{document}


If you want, you can wrap \pgfmathdeclarefunction around that to have the function available in pgfmath (see Section 65 “Customizing the Mathematical Engine” in the manual (v2.10)).

• Nice solution! It works up to the first 30 rows! May 6 '11 at 2:42
• Is it easy to change this triangle to this one here with a slight change to the addiction $N=2R+L$?
– hhh
Feb 5 '15 at 2:45

From texample.net. The author is Paul Gaborit.

Triangle de Pascal

• Such a pity this can't do more than the 16 rows shown here. Someone needs to write an arbitrary integer type for TikZ ;) Sep 22 '13 at 14:00
• Is it easy to change this triangle to this one here with a slight change to the addiction $N=2R+L$?
– hhh
Feb 5 '15 at 2:49
• Any idea how to draw parallel arrows but in reverse orientation? I'd like 2 arrows instead of one connecting the nodes. Apr 14 '16 at 12:39
• @Sigur I don't have enough time to study the code but you can ask the question to Paul Apr 14 '16 at 13:16

The earlier answer used a macro computing individual binomial coefficients.

I now address the matter building row by row of the Pascal Triangle, as in the other answers.

For this as an exercise of translation I have taken an exact copy of the metapost code of @fpast's answer, and translated it into TeX. Up the the 34th row we can use TeX arithmetic. For simplicity I used \numexpr. Starting with the 34th row (actually there only the middle three coefficients exceeds 2^31-1) I use big integer arithmetic.

To organize the loops I use \xintFor from package xinttools. This package also defines \odef which does a definition + expansion and \oodef which does a definition + double expansion. They are used in the code together with various mixes of \numexpr, \dimexpr, \@namedef, @nameuse etc... pure TeX/LaTeX joys with its subtleties at times about where spaces are allowed or not (most spaces do not matter much as we are in a TikZ picture).

The code for the first 80 lines compile not too slowly (about 9 seconds on my laptop).

I only display the largest numbers of the triangle.

Notice that we are close to the TeX limits for the maximal dimension as each number is separated horizontally by 6cm from its neighbour.

The original metapost code of fpast is shown alongside its translation into TeX.

edit the code tested the line number to use only \numexpr for the first 33 lines (as only integers <2^31 are then evaluated) but actually doing all the computations with xint and not checking for the line number to decide to use \numexpr or xint is faster! (about 2% faster when computing 80 lines of the triangle). I thus comment out the conditionals.

\documentclass[12pt, tikz, border=5mm]{standalone}
\usepackage{tikz}
\usepackage{xint}
\usepackage{xinttools}
\makeatletter
\newdimen\X
\newdimen\Y
\def\PascalTriangle #1#2#3{% #1=n (integer) #2=u (dimension) #3=v (dimension)
%    save b, mid; numeric b[][], mid; clearxy;
%    b[0][0] = b[1][0] = b[1][1] = 1;
%    label("1", origin); label("1", (-.5u, -v)); label("1", (.5u, -v));
\edef\U {\the\numexpr\dimexpr #2\relax }% convert to sp units
\edef\V {\the\numexpr\dimexpr #3\relax }%
\@namedef{dali@0@0}{1}%
\@namedef{dali@1@0}{1}%
\@namedef{dali@0@1}{1}%
\node at (0,0) {$1$};%
\node at (-.5*#2,-#3) {$1$};
\node at (.5*#2,-#3)  {$1$};
% for i = 2 upto n:
\xintFor ##1 in {\xintegers[2+1]}\do {%
\ifnum #1<##1\expandafter\xintBreakFor\fi
%        mid := i div 2;
\odef\Mid  {\the\numexpr (##1+1)/2 -1\relax }%
%       x := -u*i/2;
\X = \dimexpr\the\numexpr (-##1*\U)/2\relax sp
%       y := -i*v ;
\Y = \dimexpr\the\numexpr -##1*\V\relax sp
%       b[i][0] = 1; label("1", z); label("1", (-x, y));
\@namedef{dali@\the##1@0}{1}%
\node at (\X,\Y)  {$1$};
\node at (-\X,\Y) {$1$};
%       for k = 1 upto mid:
\xintFor ##2 in {\xintegers[1+1]}\do {%
\ifnum\Mid<##2\expandafter\xintBreakFor\fi
%           x := x + u;
\let\next\@secondoftwo
%           if (k < mid) or (odd i):
\ifnum \Mid>##2\let\next\@firstoftwo\fi
\ifodd      ##1\let\next\@firstoftwo\fi
\next
{%
%               b[i][k] = b[i-1][k-1] + b[i-1][k];
%          \ifnum ##1<34 % binomial coefficients are < 2^31
%          % EDIT DROPS THIS CONDITIONAL
%             \expandafter\odef\csname dali@\the##1@\the##2\endcsname
%             {\the\numexpr\@nameuse{dali@\the\numexpr##1-1@\the\numexpr##2-1}
%                         +\@nameuse{dali@\the\numexpr##1-1@\the##2}\relax }%
%          \else % 34 choose 17 is 2333606220 > 2^31-1 = 2147483647
\expandafter\oodef\csname dali@\the##1@\the##2\endcsname
{\@nameuse{dali@\the\numexpr##1-1@\the##2}}}%
%          \fi
%               label(decimal b[i][k], z); label(decimal b[i][k], (-x, y));
\node at (\X,\Y)  {$\@nameuse{dali@\the##1@\the##2}$};
\node at (-\X,\Y) {$\@nameuse{dali@\the##1@\the##2}$};
}%
%           else:
{%
%               b[i][k] = 2b[i-1][k-1];
%          \ifnum ##1<34   % EDIT DROPS THIS CONDITIONAL
%             \expandafter\odef\csname dali@\the##1@\the##2\endcsname
%             {\the\numexpr2*\@nameuse{dali@\the\numexpr##1-1@\the\numexpr##2-1}\relax}%
%          \else
\expandafter\oodef\csname dali@\the##1@\the##2\endcsname
{\xintDouble{\@nameuse{dali@\the\numexpr##1-1@\the\numexpr##2-1}}}%
%          \fi
%               label(decimal b[i][k], z);
\node at (\X,\Y) {$\@nameuse{dali@\the##1@\the##2}$};
}%
%           fi
%       endfor
}%
% endfor
}%
}
\makeatother

\begin{document}
\begin{tikzpicture}
\PascalTriangle{80}{6cm}{1cm}
\end{tikzpicture}
\end{document}


(computes individual binomial coefficients)

You can do this

\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{tikz}

% \binomialb macro from https://tex.stackexchange.com/a/161863/4686
% expandably computes binomial coefficients with \numexpr

% START OF CODE
\catcode_ 11

\def\binomialb #1#2{\romannumeral0\expandafter
\binomialb_a\the\numexpr #1\expandafter.\the\numexpr #2.}

\def\binomialb_a #1.#2.{\expandafter\binomialb_b\the\numexpr #1-#2.#2.}

\def\binomialb_b #1.#2.{\ifnum #1<#2 \expandafter\binomialb_ca
\else   \expandafter\binomialb_cb
\fi {#1}{#2}}

\def\binomialb_ca #1{\ifnum#1=0 \expandafter \binomialb_one\else
\expandafter \binomialb_d\fi {#1}}

\def\binomialb_cb #1#2{\ifnum #2=0 \expandafter\binomialb_one\else
\expandafter\binomialb_d\fi {#2}{#1}}

\def\binomialb_one #1#2{ 1}

\def\binomialb_d #1#2{\expandafter\binomialb_e \the\numexpr #2+1.#1!}

% n-k+1.k! -> u=n-k+2.v=2.w=n-k+1.k!
\def\binomialb_e #1.{\expandafter\binomialb_f \the\numexpr #1+1.2.#1.}

% u.v.w.k!
\def\binomialb_f #1.#2.#3.#4!%
{\ifnum #2>#4 \binomialb_end\fi
\expandafter\binomialb_f
\the\numexpr #1+1\expandafter.%
\the\numexpr #2+1\expandafter.%
\the\numexpr #1*#3/#2.#4!}

\def\binomialb_end #1*#2/#3!{\fi\space #2}
\catcode_ 8
% END OR \binomialb code

\begin{document}\thispagestyle{empty}

\begin{tikzpicture}
\foreach \n in {0,...,4} {
\foreach \k in {0,...,\n} {
\node at (2*\k-\n,-\n) {${\n \choose \k} = \binomialb\n\k$};
}
}
\end{tikzpicture}

\bigskip\bigskip

\begin{tikzpicture}
\foreach \n in {21,...,24} {
\foreach \k in {10,...,\the\numexpr\n-11\relax} {
\node at (3*\k-1.5*\n,-\n) {${\n \choose \k} = \binomialb\n\k$};
}
}
\end{tikzpicture}

%\bigskip\bigskip

% arithmetic overflow, use xint and \binomialB !
% \begin{tikzpicture}
% \foreach \n in {30,...,34} {
%   \foreach \k in {15,...,\the\numexpr\n-15\relax} {
%     \node at (4*\k-2*\n,-\n) {${\n \choose \k} = \binomialb\n\k$};
%   }
% }
% \end{tikzpicture}

\end{document}


• Wow! I am dazzled by your skills in TeX programming. All this seems most complicated to me, even more so knowing that it is translated from my own MetaPost program. And I never imagined that TeX could handle such big numbers. Mar 16 '15 at 12:16
• Package xint does expandable arithmetic with "arbitrarily big" integers. An earlier package was bigintcalc. Expandability allows among other things intuitive "composition of macros" rather than the style of \pgfmathparse or \FPadd to cite other mathematical engines. Expandability is implemented in the strongest sense by xint. Starting with numbers having hundreds of digits this makes the macro slower. If one were to drop expandability, it would be possible to implement much faster routines.
– user4686
Mar 16 '15 at 16:10
• @fpast Package xintfrac extends xint to handle exactly fractions A/B or decimal numbers. Packages with non expandable arbitrary precision fixed point arithmetic exist, but this does not mean that they are faster than the expandable xintfrac for numbers with less than one hundred digits. To the contrary in the case of xintfrac \xintXTrunc which admittedly is completely expandable, but not in the strongest sense as for the other xint macros.
– user4686
Mar 16 '15 at 16:13

Done with MetaPost, several years too late.

The Pascal_triangle macro defined below takes three arguments, the number of rows n (starting from 0), the horizontal space between consecutive coefficients in the same row and the vertical space between two consecutive rows. It uses the well-known recursive relation between binomial coefficients, in an iterative way and a straightforward manner (it doesn't take any symmetry into account), yet it is more efficient than I expected: it works up to the first 56 rows.

\documentclass[12pt, border=5mm]{standalone}
\usepackage{luatex85,luamplib}
\mplibnumbersystem{double}
\mplibtextextlabel{enable}
\begin{document}
\begin{mplibcode}
vardef Pascal_triangle(expr n, u, v) =
save b; numeric b[][]; clearxy;
b[0][0] = 1; b[0][1] = 0; label("1", origin);
for i = 1 upto n:
x := -u*i/2; y := -i*v;
b[i][0] = 1; label("1", z);
for k = 1 upto i:
x := x + u;
b[i][k] = b[i-1][k-1] + b[i-1][k]; label(decimal(b[i][k]), z);
endfor b[i][i+1]=0;
endfor
enddef;

beginfig(1);
Pascal_triangle(19, 1.4cm, 1cm);
endfig;
\end{mplibcode}
\end{document}


To be executed with LuaLaTeX. This example shows the first 20 rows of the triangle (n=19):

Edit Here is a version which makes use of the symmetry of Pascal's triangle, with the same output as before, of course. It was quite a bit more difficult for me to sort that one out (probably because I have not found the most clever way of doing it ;-)), and I have not noticed any difference in speed nor in efficiency with the previous version.

\documentclass[12pt, border=5mm]{standalone}
\usepackage{luatex85,luamplib}
\mplibnumbersystem{double}
\mplibtextextlabel{enable}
\begin{document}
\begin{mplibcode}
vardef Pascal_triangle(expr n, u, v) =
save b, mid; numeric b[][], mid; clearxy;
b[0][0] = b[1][0] = b[1][1] = 1;
label("1", origin); label("1", (-.5u, -v)); label("1", (.5u, -v));
for i = 2 upto n:
mid := i div 2;
x := -u*i/2; y := -i*v;
b[i][0] = 1; label("1", z); label("1", (-x, y));
for k = 1 upto mid:
x := x + u;
if (k < mid) or (odd i):
b[i][k] = b[i-1][k-1] + b[i-1][k];
label(decimal b[i][k], z); label(decimal b[i][k], (-x, y));
else:
b[i][k] = 2b[i-1][k-1];
label(decimal b[i][k], z);
fi
endfor
endfor
enddef;

beginfig(1);
Pascal_triangle(19, 1.4cm, 1cm);
endfig;
\end{mplibcode}
\end{document}


Edit I've added the loading of the luatex85 package, since LuaLaTeX is not compatible with the standalone class anymore without this package.

\documentclass[a4paper,12pt]{article}%
\usepackage[dvipsnames]{xcolor}
\usepackage{tikz}
\usepackage{pdfpages}
\makeatletter
\newcommand\binomialCoefficient[2]{%
% Store values
\c@pgf@counta=#1% n
\c@pgf@countb=#2% k
%
% Take advantage of symmetry if k > n - k
\c@pgf@countc=\c@pgf@counta%
\ifnum\c@pgf@countb>\c@pgf@countc%
\c@pgf@countb=\c@pgf@countc%
\fi%
%
% Recursively compute the coefficients
\c@pgf@countc=1% will hold the result
\c@pgf@countd=0% counter
\pgfmathloop% c -> c*(n-i)/(i+1) for i=0,...,k-1
\ifnum\c@pgf@countd<\c@pgf@countb%
\multiply\c@pgf@countc by\c@pgf@counta%
\divide\c@pgf@countc by\c@pgf@countd%
\repeatpgfmathloop%
\the\c@pgf@countc%
}
\makeatother
\begin{document}
\begin{center}
\newdimen\R
\R=.4cm
\newcommand\mycolor{gray}
\begin{tikzpicture}[line width=.8pt]
\foreach \k in {0,...,12}{
\begin{scope}[shift={(-60:{sqrt(3)*\R*\k})}]
\pgfmathtruncatemacro\ystart{12-\k}
\foreach \n in {0,...,\ystart}{
\pgfmathtruncatemacro\newn{\n+\k}
\ifthenelse{\k=0}{\def\mycolor{pink}}{}
\ifthenelse{\k=1}{\def\mycolor{yellow}}{}
\ifthenelse{\k=2}{\def\mycolor{blue}}{}
\ifthenelse{\k=3}{\def\mycolor{green}}{}
\ifthenelse{\k=8 \AND \n < 4}{\def\mycolor{purple}}{}
\ifthenelse{\k=9 \AND \n = 3}{\def\mycolor{purple}}{}
\begin{scope}[shift={(-120:{sqrt(3)*\R*\n})}]
\draw[top color=\mycolor!20,bottom color=\mycolor!60]
(30:\R) \foreach \x in {90,150,...,330} {
-- (\x:\R)}
--cycle (90:0) node {\tiny $\mathbf{\binomialCoefficient{\newn}{\k}}$};
\end{scope}
}
\end{scope}
}
\end{tikzpicture}
\end{center}
\end{document}


• I love this hexagonal Pascal triangle, but I couldn't make it work. I copied the code verbatim, but it gives me plenty of errors. The first error is "Missing number, treated as zero" on line 69. What's the problem? Thank you very much in advance. Jan 1 '18 at 22:21
• I'd recommend changing \newdimen\R to \newlength\R and \R=.4cm to \setlength\R{.4cm}. A handful of math documents have the definition \newcommand{\R}{\mathbb{R}} and when the \newdimen\R definition comes through, it doesn't check to see whether \R is defined already. If an author continues through their document using \R as if it denotes the reals, they'll end up getting a ! Missing number... error.
– user45054
Dec 19 '18 at 14:21

Why not? This should work to construct up to the first 100 lines of the triangle. It will work for higher values (subject to capacity etc.), but the alignment would need adjusting in that case.

\documentclass[border=10pt]{standalone}
\usepackage{forest}
\begin{document}
\newlength\pwidth
\settowidth\pwidth{$99 \choose 99$}
\forestset{
declare count={pk}{0},
my phantom/.style={, no edge, inner sep=0pt, calign with current, my node},
my node/.style={},
pascal triangle/.style={
if={>n_>{#1}{9}}{%
my node/.style={text width=\pwidth},
}{},
before computing xy={
for tree={
l'=\baselineskip,
},
},
before typesetting nodes={
for tree={
content/.process={OOw2}{level}{pk}{##1 \choose ##2},
math content,
s sep'=0pt,
inner sep=0pt,
my node,
no edge,
if n children=1{
prepend={[, my phantom]},
}{},
},
for nodewalk={fake=r,F}{insert after={[, my phantom]}},
},
delay={
for root={
append={[]},
append={[, pk'=1]},
},
repeat={>n{#1-1}}{
delay={
do dynamics,
for leaves={
append={[, pk/.option=!u.pk, pk'+=1]},
},
for first leaf={
prepend={[]},
},
},
},
}
},
}
\begin{forest}
pascal triangle=2,
[]
\end{forest}
\begin{forest}
pascal triangle=3,
[]
\end{forest}
\begin{forest}
pascal triangle=4,
[]
\end{forest}
\begin{forest}
pascal triangle=5,
[]
\end{forest}
\begin{forest}
pascal triangle=6,
[]
\end{forest}
\begin{forest}
pascal triangle=7,
[]
\end{forest}
\begin{forest}
pascal triangle=8,
[]
\end{forest}
\begin{forest}
pascal triangle=9,
[]
\end{forest}
\begin{forest}
pascal triangle=10,
[]
\end{forest}
\end{document}


\documentclass[border=5pt,tikz]{standalone}
\begin{document}
\begin{tikzpicture}[rotate=-90]
\foreach \x in {0,1,...,5}
{
\foreach \y in {0,...,\x}
{
\pgfmathsetmacro\binom{factorial(\x)/(factorial(\y)*factorial(\x-\y))}
\pgfmathsetmacro\shift{\x/2}
\node[xshift=-\shift cm] at (\x,\y) {\pgfmathprintnumber\binom};
}
}
\end{tikzpicture}
\end{document}


Output:

• Elegant solution, but falls apart for n >= 8. Dec 29 '18 at 11:20

Here is a fully expandable solution (two expansions of \BinomialCoefficient{From}{By} are enough; From and By may be arithmetic expressions).

\documentclass{article} % binomial(N,K) from N by K as N/1*(N-1)/2*(N-3)/3...  Here the denominator is denoted as k
% Works for all cases (but 0 for N<0) when N, K, and the answer fit into 32-bit signed integers

\def\binomialCoefficient#1#2{%  #1 >= 0 (otherwise 0); (K=#2 out of N=#1); expandable (needs 2 expansion); leaves no \else/\fi junk
\the\numexpr 1\expandafter\bKN\expandafter{\the\numexpr #2\relax}{#1}\relax}
\def\bKN#1#2{% #1 not an expression, expanded at most twice per call;
\ifnum #1<0 *0% may leave at most 5 dangling \else or \fi
\else    \ifnum 0<\numexpr 2*#1-(#2)\relax \expandafter\bKN\expandafter{\the\numexpr #2-(#1)\relax}{#2}%
\else  \bkNK 1{#2}{#1}\fi\fi}
\def\bkNK#1#2#3{% 1,3 not expressions
\ifnum #1>#3 % end: falls through to \relax
\else  *(#2)/#1\expandafter\bNkKfi\expandafter{\the\numexpr#2-1\relax}{#1+1}{#3}%
\fi}      % Inserting \fi then exchanging it is needed for the pre-else branch
\def\bNkKfi#1#2#3#4{%  4 is \fi, 3 may not be an expression; avoids unexpanded \fi's at end
#4\expandafter\bkNK\expandafter{\the\numexpr#2\relax}{#1}{#3}}

\usepackage{pgffor} % For testing only
\begin{document}

\def\LAST{33}   % 33 is the max which does not overflow
\edef\L{\the\numexpr\LAST+3\relax}

\foreach \I in {0,...,\LAST} { (\the\numexpr 1\bKN {\I}{\LAST-3+3})}

\foreach \I in {1,...,\L} { (\binomialCoefficient {\L-3}{\I-2})}

\foreach \I in {2,...,7} { (\binomialCoefficient {190}{190-\I+2})}

\expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter\A\expandafter\expandafter\expandafter
{\binomialCoefficient {200-10}{190-5}}  % ->1956800538.
%  {\binomialCoefficient {33}{16}}  % ->1166803110.
\show\A

\end{document}