7
\$\begingroup\$

Write a function or program which, given a number of lines and columns, generates a corresponding tabular environment for LaTeX with no data in it.

Table format and tabular Environment

Here is an example of a table with 2 rows and 4 columns:

enter image description here

As you can see, we do not count the first row nor do we count the first column: those are for the labels of the table.

The top left corner is also "missing", in that there is no border around it.

The corresponding LaTeX's code to generate this table is the following:

\begin{tabular}{|c|c|c|c|c|}
    \cline{2-5}
    \multicolumn{1}{c|}{} & & & & \\
    \hline
    & & & & \\
    \hline
    & & & & \\
    \hline
\end{tabular}
  • There are as many c in the first line as there are total columns (that is, 1 more than the number of columns given as input). These c are separated by | (and there are | on both the extreme left and extreme right too).
  • The first horizontal separator is generated by \cline{2-X} where X is the index of the last column (starting from 1).
  • The first element of the first row is always \multicolumn{1}{c|}{} (this removes the borders of the top left corner).
  • Each row has C &, C being the number of columns given as input. Each line ends with \\.
  • Each row is followed by a \hline.

Formatting details

  • You must indent everything between the begin{tabular}{...} and \end{tabular} tags with 4 spaces.
  • The &'s are separated with exactly one space on each row. The first one of the row does not have an extra space before it (since it already has 4 spaces before it). Note that this is not true for the first row, where the first & has a space before it because of the \multicolumn element.
  • \\ is separated from the last & by a space.
  • Each \hline and row description is on its own new line.

Input

Input is a couple of two integers representing the number of columns and the number of rows. Note that this is the number of columns and rows excluding the very first row and very first column.

You may assume that the row and column inputs will always be at least 1, and less than 1024.

Those two numbers can be taken whichever way is most appropriate in your language (two args, a list, etc.).

Output

The output is a string of the LaTeX code that generates a table with the appropriate number of rows and columns. This can be returned from a function or outputted to STDOUT.

A trailing new line is allowed after the \end{tabular}. Trailing spaces are not allowed at the end of any line.

Test cases

Input: (1,1)
Output:
\begin{tabular}{|c|c|}
    \cline{2-2}
    \multicolumn{1}{c|}{} & \\
    \hline
    & \\
    \hline
\end{tabular}


Input: 2 rows, 4 columns
Output:
\begin{tabular}{|c|c|c|c|c|}
    \cline{2-5}
    \multicolumn{1}{c|}{} & & & & \\
    \hline
    & & & & \\
    \hline
    & & & & \\
    \hline
\end{tabular}

Scoring

This is , so the shortest code in bytes \emph{wins}.

\$\endgroup\$

3 Answers 3

2
\$\begingroup\$

JavaScript (ES6), 172 170 bytes

a=>b=>`\\begin{tabular}{${'|c'[r='repeat'](++b)}|}
    \\cline{2-${b--}}
    \\multicolumn{1}{c|}{} ${('& '[r](b)+`\\\\
    \\hline
    `)[r](a+1).trim()}
\\end{tabular}`

Called as F(a)(b) (credit to Patrick Roberts for finding this method)

Would have been much messier if not for template strings. Originally came in at 200, when I had a separate repeat for the multicolumn &'s, but cut it down a good amount by combining them and using trim to get rid of the final unneeded indentation.

\$\endgroup\$
2
\$\begingroup\$

Python 2, 197 bytes

This solution uses string formatting to reduce repetition. Each string component is assembled, then placed within the template. It is tricky to use so many backslashes in Python strings. I used the raw string r'\\' and multi-line '''blah \n blah''' string techniques here.

def a(d,e):
 c='c|'*e;b='& '*e+r'\\';g=' '*4+b+'\n    \\hline\n';f=g*d;h='{tabular}'
 return r'''\begin%s{|c|%s}
    \cline{2-%s}
    \multicolumn{1}{c|}{} %s
    \hline
%s\end%s'''%(h,c,e+1,b,f,h)

Before the minifier, it looks like this:

def latextable(height, width):
    columns = 'c|' * width;
    linespec = '& ' * width + r'\\';
    line = ' '*4 + linespec + '\n    \\hline\n';
    block = line * height;
    mode = '{tabular}'
    return r'''\begin%s{|c|%s}
    \cline{2-%s}
    \multicolumn{1}{c|}{} %s
    \hline
%s\end%s''' % (mode, columns, width+1, linespec, block, mode)

print latextable(1, 1)
print latextable(2, 4)

The output tests:

\begin{tabular}{|c|c|}
    \cline{2-2}
    \multicolumn{1}{c|}{} & \\
    \hline
    & \\
    \hline
\end{tabular}
\begin{tabular}{|c|c|c|c|c|}
    \cline{2-5}
    \multicolumn{1}{c|}{} & & & & \\
    \hline
    & & & & \\
    \hline
    & & & & \\
    \hline
\end{tabular}

As a side note, I wrote a latex macro processor like this to format my thesis. I think I spent longer on developing that macro processor than on writing the words...

\$\endgroup\$
3
  • 1
    \$\begingroup\$ You forgot one space between the return and your raw string in your first code block. \$\endgroup\$
    – Denker
    Commented Feb 23, 2016 at 9:54
  • 1
    \$\begingroup\$ Also you can go with g=' '*4 instead of g=' ' to save one byte. \$\endgroup\$
    – Denker
    Commented Feb 23, 2016 at 9:56
  • \$\begingroup\$ @DenkerAffe, thanks for finding that error. My minifier has a bug! \$\endgroup\$ Commented Feb 23, 2016 at 10:01
1
\$\begingroup\$

C#, 248 byte

string t(int r,int c){string i="\r\n    ",d="",q="",m;for(int j=0;j++<c;){d+="c|";q+="& ";}q+=$"\\\\{i}\\hline";m=@"\begin{tabular}{|c|"+d+"}"+i+@"\cline{2-"+(c+1)+"}"+i+@"\multicolumn{1}{c|}{} "+q;for(;r-->0;)m+=i+q;return m+"\r\n\\end{tabular}";}

Tester:

using System;
class Table
{
    static int Main()
    {
        var x = new Table();
        Console.WriteLine(x.t(1,1));
        Console.WriteLine(x.t(2,4));
        Console.Read();
        return 0;
    }
    string t(int r,int c){string i="\r\n    ",d="",q="",m;for(int j=0;j++<c;){d+="c|";q+="& ";}q+=$"\\\\{i}\\hline";m=@"\begin{tabular}{|c|"+d+"}"+i+@"\cline{2-"+(c+1)+"}"+i+@"\multicolumn{1}{c|}{} "+q;for(;r-->0;)m+=i+q;return m+"\r\n\\end{tabular}";}

    string tab(int row, int col){
        string i="\r\n    ",sc="",sr="",msg;
        for(int j=0;j++<col;){sc+="c|";sr+="& ";}
        sr+=$"\\\\{i}\\hline";
        msg=@"\begin{tabular}{|c|"+sc+"}"+i+@"\cline{2-"+(col+1)+"}"+i+@"\multicolumn{1}{c|}{} "+sr;
        for(;row>0;)msg+=i+sr;
        return msg+"\r\n\\end{tabular}";
    }
}
\$\endgroup\$
1
  • \$\begingroup\$ I could save 4 bytes when I use "\n" instead of "\r\n" as linebreak. \$\endgroup\$
    – DW.com
    Commented Mar 2, 2016 at 12:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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