8

Anyone who is familiar with the problem of counting up/right going paths in a rectangle from bottom left corner to upper right corner knows that one way of doing this is doing it by recursion. I want to visualize this and therefore I need to make a lattice which has numbers on vertices of it. In the following matrix numbers are inside the squares but I want them on vertices or even better to have a gap in intersection of four lines and the number could be in that gap.

$\begin{array}{*{20}{c}}
\hline
  | & 1&| & 1&| & 1&| & 1&| & 1&| & 1&| & 1| &  \\ 
\hline
  | & 7&| & 6&| & 5&| & 4&| & 3&| & 2&| & 1| &  \\ 
\hline
  | & {28}&| & {21}&| & {15}&| & {10}&| & 6&| & 3&| & 1| &  \\ 
\hline
  | & {84}&| & {56}&| & {35}&| & {20}&| & {10}&| & 4&| & 1| & \\ 
\hline
\end{array}$

Something like this: enter image description here

Important Note: Image has been edited after the question has been answered by the image in correct answer.

  • I don't know why my tex code doesn't work! – Naji Apr 5 '13 at 23:18
  • Try adding a \\ before the last \hline. That will at least get your code to compile. – Peter Grill Apr 5 '13 at 23:23
  • Can you show us a picture how your output should look like? Also, I’d remove those \vline cells and use | in the column specification. – Qrrbrbirlbel Apr 5 '13 at 23:28
  • Didn't work again. – Naji Apr 5 '13 at 23:30
  • That sounds like a mission for TikZ... – jub0bs Apr 5 '13 at 23:43
6

Here is a way to do this:

enter image description here

Code:

\documentclass{article}
\usepackage{xstring}
\usepackage{tikz}
\usepackage{collcell}

\newcommand{\MakeBox}[1]{\makebox[2.0em][c]{#1}}%
\newcommand*{\MyBox}[1]{%
    \phantom{\MakeBox{#1}}%
    \IfStrEq{#1}{}{}{%
        \begin{tikzpicture}[overlay, draw=red, line width=1.0pt, text=blue]
            \node [draw=none, inner sep=2pt] (Node) {\MakeBox{#1}};
            \draw (Node.north) -- ([yshift=2.0ex]Node.north);
            \draw (Node.south) -- ([yshift=-2.0ex]Node.south);
            \draw (Node.west) -- ([xshift=-1.0em]Node.west);
            \draw (Node.east) -- ([xshift=1.0em]Node.east);
        \end{tikzpicture}%
    }%
}

\newcolumntype{C}{>{\collectcell\MyBox}c<{\endcollectcell}}

\begin{document}
$\begin{array}{*{20}{C}}
   & 1 &  1 &  1 &  1 &  1 &  1 &  1 &  \\[2.0ex]
   & 7 &  6 &  5 &  4 &  3 &  2 &  1 &  \\[2.0ex] 
   & 28 &  21 &  15 &  10 &  6 &  3 &  1 &  \\[2.0ex] 
   & 84 &  56 &  35 &  20 &  10 &  4 &  1 & \\ [2.0ex]
\end{array}$
\end{document}

If you want to suppress the outer lines, then you need to indicate the last row with a call to \ThisIsLastRow. The detection of the first column is handled by using the F column type.

enter image description here

Further Enhancements

  • Since I am using a \makebox[2.0em][c]{#1} to place the text to keep it centered, then the last column which only has single width characters looks wrong. One way to fix that would be to define two column types: one for double digits, and one for single digits. Alternatively, one could draw the lines through the text and then overlay the node text over it which will then remove the lines just around the numbers.

Code:

\documentclass{article}
\usepackage{xstring}
\usepackage{etoolbox}
\usepackage{tikz}
\usepackage{collcell}

\newtoggle{IsFirstColumn}\togglefalse{IsFirstColumn}%%
\newtoggle{IsLastRow}\togglefalse{IsLastRow}%
\newcommand{\ThisIsLastRow}{\global\toggletrue{IsLastRow}}%

\newcommand{\MakeBox}[1]{\makebox[2.0em][c]{#1}}%
\newcommand*{\MyBox}[1]{%
    \phantom{\MakeBox{#1}}%
    \IfStrEq{#1}{}{}{%
        \begin{tikzpicture}[overlay, draw=red, line width=1.0pt, text=blue]
            \node [draw=none, inner sep=2pt] (Node) {\MakeBox{#1}};
            \iftoggle{IsLastRow}{}{%
                \draw (Node.south) -- ([yshift=-2.0ex]Node.south);
            }%
            \iftoggle{IsFirstColumn}{}{%
                \draw (Node.west) -- ([xshift=-1.0em]Node.west);
            }%
        \end{tikzpicture}%
    }%
}

\newcommand*{\MyBoxFirstColumn}[1]{%
    \global\toggletrue{IsFirstColumn}%
    \MyBox{#1}%
    \global\togglefalse{IsFirstColumn}%
}%

\newcolumntype{C}{>{\collectcell\MyBox}c<{\endcollectcell}}
\newcolumntype{F}{>{\collectcell\MyBoxFirstColumn}c<{\endcollectcell}}

\begin{document}
$\begin{array}{F*{20}{C}}
    1 &   1 &   1 &   1 &   1 &  1 &  1 \\[2.0ex]
    7 &   6 &   5 &   4 &   3 &  2 &  1 \\[2.0ex] 
   28 &  21 &  15 &  10 &   6 &  3 &  1 \\[2.0ex] \ThisIsLastRow
   84 &  56 &  35 &  20 &  10 &  4 &  1 \\
\end{array}$
\end{document}
  • Can you guide me to get rid of the ones out of the main rectangle? I mean the ones which are above and the right of 1s! – Naji Apr 6 '13 at 0:01
  • @Naji: What about left and below? – Peter Grill Apr 6 '13 at 0:07
  • 1
    @Naji: Have updated solution as requested. – Peter Grill Apr 6 '13 at 0:27
3

Given the output you desire, I think I would use matrix of nodes

screenshot

Complete code

% arara: pdflatex
% !arara: indent: {overwrite: true}
\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{matrix}

\begin{document}
\begin{tikzpicture}[thick]
    \matrix (mylattice)[
        matrix of nodes,
        row sep=.5cm,
        column sep=.5cm,  
        nodes in empty cells,
        execute at empty cell={\node[draw=none]{\phantom{X}};},
    ]{
        &    &  &  &  &  &  &  &\\ 
        & 1 &  1 &  1 &  1 &  1 &  1 &  1  & \\
        & 7 &  6 &  5 &  4 &  3 &  2 &  1  & \\
        & 28 &  21 &  15 &  10 &  6 &  3 &  1 &  \\
        & 84 &  56 &  35 &  20 &  10 &  4 &  1 & \\ 
        &    &      &    &      &   &     &  & \\ 
    };
    \foreach \i [evaluate=\i as \y using int(\i+1)] in {1,...,5}
    {
        \foreach \j [evaluate=\j as \x using int(\j+1)]in {1,...,8}
        {
            \ifnum\j>1
            \draw[red] (mylattice-\i-\j)--(mylattice-\y-\j);
            \fi
            \ifnum\i>1
            \draw[blue] (mylattice-\i-\j)--(mylattice-\i-\x);
            \fi
        }
    }
\end{tikzpicture}
\end{document}

Following the comments, if you don't want the outside pieces then you can use the following slightly modified code.

screenshot

% arara: pdflatex
% !arara: indent: {overwrite: true}
\documentclass{standalone}

\usepackage{tikz}
\usetikzlibrary{matrix}

\begin{document}
\begin{tikzpicture}[thick]
    \matrix (mylattice)[
        matrix of nodes,
        row sep=.5cm,
        column sep=.5cm,  
        nodes in empty cells,
        execute at empty cell={\node[draw=none]{\phantom{X}};},
    ]{
         1 &  1 &  1 &  1 &  1 &  1 &  1   \\
         7 &  6 &  5 &  4 &  3 &  2 &  1   \\
         28 &  21 &  15 &  10 &  6 &  3 &  1   \\
         84 &  56 &  35 &  20 &  10 &  4 &  1  \\ 
    };
    \foreach \i [evaluate=\i as \y using int(\i+1)] in {1,...,4}
    {
        \foreach \j [evaluate=\j as \x using int(\j+1)]in {1,...,7}
        {
            \ifnum\i<4
            \draw[red] (mylattice-\i-\j)--(mylattice-\y-\j);
            \fi
            \ifnum\j<7
            \draw[blue] (mylattice-\i-\j)--(mylattice-\i-\x);
            \fi
        }
    }
\end{tikzpicture}
\end{document}
  • may I ask you to help me with the code without dashes in the outer area? – Naji Apr 6 '13 at 21:26
  • @Naji just remove the first and last row and column- or else mess around with the \ifnum bits :) – cmhughes Apr 6 '13 at 22:00
  • unfortunately removing them gives error!! where can I read about ifnums? – Naji Apr 7 '13 at 0:31
  • 1
    @Naji see the update – cmhughes Apr 7 '13 at 4:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.