答案1
让我们使用 Ti钾Z 和一些用于此类事物的简单算法。
\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}[x=5ex,y=5ex]
\def\maxnum{11} % Change the size here
\foreach \i in {1,...,\maxnum} {
% Draw the numbers
\pgfmathsetmacro\auxnum{\maxnum-\i+1}
\foreach \j in {1,...,\auxnum}
\node (\i-\j) at (\i,\j) {\i};
% Draw the plus signs
\ifnum\i=\maxnum\relax\else
\pgfmathsetmacro\auxnum{\maxnum-\i}
\foreach \j in {1,...,\auxnum}
\node[anchor=base] at ([shift={(.5,0)}]\i-\j.base) {+};
\fi
}
\end{tikzpicture}
\end{document}
一个小福利:
\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}[x=5ex,y=5ex]
\def\maxnum{11}
\foreach \i in {1,...,\maxnum} {
% Draw the numbers
\pgfmathsetmacro\auxnum{\maxnum-\i+1}
\foreach \j in {1,...,\auxnum}
\node (\i-\j) at (\i,\j) {\i};
% Draw the plus signs
\ifnum\i=\maxnum\relax\else
\pgfmathsetmacro\auxnum{\maxnum-\i}
\foreach \j in {1,...,\auxnum}
\node[anchor=base] at ([shift={(.5,0)}]\i-\j.base) {+};
\fi
% The rest :)
\pgfmathsetmacro\sumoutput{int((\maxnum-\i+1)*(\maxnum-\i+2)/2)}
\node (output-\i) at (\maxnum+1,\i) {\sumoutput};
\node[anchor=base] at ([shift={(-.5,0)}]output-\i.base) {=};
}
\end{tikzpicture}
\end{document}
不确定您真正想要通过“向右”获得什么,但也许是这个?
\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}[x=5ex,y=5ex]
\def\maxnum{11}
\foreach \i in {1,...,\maxnum} {
% numbers - simpler than the above code
\foreach \j [count=\k] in {\i,...,1}
\node (\i-\j) at (\i,\j) {\k};
% plus signs - a bit simpler
\ifnum\i=\maxnum\relax\else
\foreach \j in {\i,...,1}
\node[anchor=base] at ([shift={(.5,0)}]\i-\j.base) {+};
\fi
% I keep the "bonus" part - it needs no improvements
\pgfmathsetmacro\sumoutput{int((\maxnum-\i+1)*(\maxnum-\i+2)/2)}
\node (output-\i) at (\maxnum+1,\i) {\sumoutput};
\node[anchor=base] at ([shift={(-.5,0)}]output-\i.base) {=};
}
\end{tikzpicture}
\end{document}
与其他答案的比较
其他答案都很好,但这个答案似乎与其他所有答案完全不同(它们在某种程度上有点相似)。这是这个答案与其他答案相比的优缺点。阅读它以考虑使用什么。
优点
数字和符号排列成一个完美的正方形。因此,您可以得到类似这样的结果
\documentclass[tikz]{standalone}
\usetikzlibrary{backgrounds,fit,calc}
\begin{document}
\begin{tikzpicture}[x=5ex,y=5ex]
\def\maxnum{11} % Change the size here
\foreach \i in {1,...,\maxnum} {
% numbers - simpler than the above code
\foreach \j [count=\k] in {\i,...,1}
\node[minimum size=.55cm] (\i-\j) at (\i,\j) {\k};
% plus signs - a bit simpler
\ifnum\i=\maxnum\relax\else
\foreach \j in {\i,...,1}
\node[anchor=base] at ([shift={(.5,0)}]\i-\j.base) {+};
\fi
% I keep the "bonus" part - it needs no improvements
\pgfmathsetmacro\sumoutput{int((\maxnum-\i+1)*(\maxnum-\i+2)/2)}
\node (output-\i) at (\maxnum+1,\i) {\sumoutput};
\node[anchor=base] at ([shift={(-.5,0)}]output-\i.base) {=};
}
\begin{scope}[on background layer]
\path[fill=red!10,draw=red,thick]
([shift={( .1,-.1)}]1-1.north west) --
([shift={( .1,-.1)}]11-11.north west)
arc (135:-45:{.55/sqrt(2)}) --
([shift={(-.1, .1)}]1-1.south east)
arc (315:135:{.55/sqrt(2)}); % Well, possibly this is not the best
% way to draw this, but this is only
% for illustration purpose.
\draw[red,thick,<-]
($([shift={( .1,-.1)}]1-1.north west)!.45!([shift={( .1,-.1)}]11-11.north west)$)
-- + (-2,1) node[pos=1.3] {Looks! All are number 1!};
\end{scope}
\end{tikzpicture}
\end{document}
\maxnum
在其他答案中,如果大于 9,则数字(比如 1)就不是完全对齐的,因此绘制这样的路径更加困难。
缺点
很明显:数字和加号之间的间距不一致。但是当我按照这种方法(单独插入加号)时,我不得不接受这种间距。
顺便说一句,等号后面的数字不是右对齐的。这是可以修复的,但修复会使代码变得更加复杂(如果我想自动确定“总和”节点的宽度)。不过我认为这不是一个大问题。
答案2
只是为了好玩:没有包裹。
\documentclass{article}
\newcounter{pft}
\newcounter{pfft}
\begin{document}
\setcounter{pft}{0}\loop%
\stepcounter{pft}%
\setcounter{pfft}{0}{\noindent$\loop%
\stepcounter{pfft}\number\value{pfft}%
\ifnum\number\value{pfft}<\number\value{pft}+\repeat$\par}%
\ifnum\number\value{pft}<11\repeat%
\end{document}
或者pgffor
使用\foreach
JouleV 的精彩回答,并由 Ti 加载钾Z。
\documentclass{article}
\usepackage{pgffor}
\begin{document}
\foreach \X in {1,...,11}%
{\noindent$\foreach \Y in {1,...,\X}%
{\ifnum\Y>1%
+%
\fi%
\Y
}$\par}
\end{document}
因为每个人都有奖金......
\documentclass{article}
\newcounter{pft}
\newcounter{pfft}
\newcounter{sum}
\begin{document}
\begin{flushright}
\setcounter{pft}{0}\loop%
\stepcounter{pft}%
\setcounter{pfft}{0}\setcounter{sum}{0}{\noindent$\loop%
\stepcounter{pfft}\number\value{pfft}\addtocounter{sum}{\value{pfft}}%
\ifnum\number\value{pfft}<\number\value{pft}+\repeat=\number\value{sum}%
\ifnum\value{sum}<10\relax\phantom{1}\fi$\par}%
\ifnum\number\value{pft}<11\repeat%
\end{flushright}
\end{document}
当然,您也可以align
使用递归来实现这一点(如果我没记错的话,这是我在聊天中从 David Carlisle 那里学到的,但我的实现更加优雅,因为zz
我使用了 ;-),而不是已弃用的pft
。
\documentclass{article}
\newcounter{pft}
\newcounter{pfft}
\newcounter{sum}
\usepackage{amsmath}
\def\Pft{\stepcounter{pft}\number\value{pft}\addtocounter{sum}{\number\value{pft}}\ifnum\number\value{pft}<\number\value{pfft}%
+\Pft\else%
&=\number\value{sum}\\
\fi}
\def\Pfft{\stepcounter{pfft}\setcounter{pft}{0}\setcounter{sum}{0}\Pft%
\ifnum\number\value{pft}<11\relax%
\Pfft%
\fi}
\begin{document}
\setcounter{pfft}{0}
\begin{align*}
\Pfft
\end{align*}
\end{document}
答案3
这是一个基于 LuaLaTeX 的解决方案。行数可以设置为 LaTeX 宏的参数\makearray
;该宏调用 Lua 函数make_array
,该函数完成大部分工作。
要使三角阵列右对齐而不是左对齐,请更改\begin{array}{@{}l@{}}
为\begin{array}{@{}r@{}}
。如果您希望在符号周围留出更多空间+
,请更改tex.sprint ( "{+}" )
为tex.sprint ( "+" )
。
% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{luacode} % for 'luacode' environment
%% Lua-side code: Define the Lua function 'make_array'
\begin{luacode}
function make_array ( n )
for i=1,n do
for j=1,i do
tex.sprint ( j )
if j<i then
tex.sprint ( "{+}" )
else
tex.sprint ( "\\\\" )
end
end
end
end
\end{luacode}
%% LaTeX-side code: Define the macro '\makearray'
\newcommand\makearray[1]{%
$\begin{array}{@{}l@{}}
\directlua{make_array(#1)}
\end{array}$
}
\begin{document}
\makearray{11}
\end{document}
附录:这是一个解决方案,它将每行的总和排版在(现在是矩形)数组的右侧边缘。与上面显示的解决方案相比,它还允许在符号周围留出更多空间。观察和+
的使用:这些指令是可选的,可以省略。\toprule
bottomrule
% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{luacode} % for '\luaexec' macro
\usepackage{booktabs} % for '\toprule' and '\bottomrule' macros
%% Lua-side code: Define the function 'make_array_with_rowsum'
\luaexec{%
function make_array_with_rowsum ( n )
for i=1,n do
for j=1,i do
tex.sprint ( j )
if j<i then
tex.sprint ( "+" )
else
tex.sprint ( "&{{}={}}&" .. i*(i+1)//2 .. "\\\\" )
end
end
end
end
}
%% LaTeX-side code: Define the macro '\makearray'
\newcommand\makearray[1]{%
\par\noindent
\begingroup
\centering
\setlength\arraycolsep{0pt}
$\begin{array}{lcr}
\toprule
\luadirect{make_array_with_rowsum(#1)}
\bottomrule
\end{array}$\par
\endgroup}
\begin{document}
\makearray{16}
\end{document}
答案4
强制双expl3
循环:
\documentclass{article}
\usepackage{xparse,array}
\ExplSyntaxOn
\NewDocumentCommand{\triangletab}{sm}
{% #1 = * for totals, #2 = end point
\IfBooleanTF { #1 }
{
\begin{tabular}{@{} l @{} c @{} r @{}}
\int_step_inline:nn { #2 } { \panda_row_total:n { ##1 } \\ }
\end{tabular}
}
{
\begin{tabular}{@{} l @{}}
\int_step_inline:nn { #2 } { \panda_row:n { ##1 } \\ }
\end{tabular}
}
}
\cs_new_protected:Nn \panda_row:n
{
$1 \int_step_inline:nnn { 2 } { #1 } { + ##1 }$
}
\cs_new_protected:Nn \panda_row_total:n
{
\panda_row:n { #1 } & ${}={}$ & $\int_eval:n { (#1)*(#1+1)/2 }$
}
\ExplSyntaxOff
\begin{document}
\[
\triangletab{1} \qquad \triangletab{3} \qquad \triangletab{11}
\]
\[
\triangletab*{1} \qquad \triangletab*{3} \qquad \triangletab*{11}
\]
\end{document}