我想使用条形和星号方法列出方程的非负解的数量x + y + z = 4
。我尝试过
\documentclass{article}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{fourier}
\begin{document}
\begin{tabular}{|c|c|}
\hline
$(0, 0, 4)$ & $\big|\big|\star \star \star\star $ \\
\hline
$(0, 1, 3)$ & $\big|\star\big| \star \star\star $ \\
\hline
$(0, 2, 2)$ & $\big|\star\star \big| \star\star $ \\
\hline
$(0, 3, 1)$ & $\big|\star\star \star \big| \star $ \\
\hline
$(0, 4, 0)$ & $\big|\star\star \star \star\big| $ \\
\hline
$(1, 0, 3)$ & $\star\big|\big|\star \star \star $ \\
\hline
$(1, 1, 2)$ & $\star\big|\star \big|\star \star $ \\
\hline
$(1, 2, 1)$ & $\star\big|\star \star\big| \star $ \\
\hline
$(1, 3, 0)$ & $\star\big|\star \star \star \big| $ \\
\hline
$(2, 0, 2)$ & $\star \star\big|\big|\star \star $ \\
\hline
$(2, 1, 1)$ & $\star \star\big|\star\big| \star $ \\
\hline
$(2, 2, 0)$ & $\star \star\big|\star \star\big| $ \\
\hline
$(3, 0, 1)$ & $\star \star\star \big|\big| \star $ \\
\hline
$(3, 1, 0)$ & $\star \star\star \big| \star \big| $ \\
\hline
$(4, 0, 0)$ & $\star \star\star \star\big| \big| $ \\
\hline
\end{tabular}
\end{document}
我知道,该解的非负解的数量x + y + z = 4
是C_(4+3-1)^4=15
。有没有什么方法可以更快地表示条形和星形?
答案1
强制expl3
解决方案:两个嵌套循环来构建表体。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\starsandbars}{m}
{
\minthao_starsandbars:n { #1 }
}
\tl_new:N \l__minthao_table_body_tl
\cs_new_protected:Npn \minthao_starsandbars:n #1
{
\tl_clear:N \l__minthao_table_body_tl
\int_step_inline:nnnn { 0 } { 1 } { #1 } % ##1 is x
{
\int_step_inline:nnnn { 0 } { 1 } { #1 - ##1 } % ####1 is y
{
\tl_put_right:Nx \l__minthao_table_body_tl
{
$(\int_to_arabic:n { ##1 },
\int_to_arabic:n { ####1 },
\int_to_arabic:n { #1 - ##1 - ####1 })$ &
}
\tl_put_right:Nx \l__minthao_table_body_tl
{
\prg_replicate:nn { ##1 } { $\star$ }
\exp_not:n { \,\vline\, }
\prg_replicate:nn { ####1 } { $\star$ }
\exp_not:n { \,\vline\, }
\prg_replicate:nn { #1 - ##1 - ####1 } { $\star$ }
}
\tl_put_right:Nn \l__minthao_table_body_tl { \\ \hline }
}
}
\begin{tabular}{|c|c|}
\hline
\l__minthao_table_body_tl
\end{tabular}
}
\ExplSyntaxOff
\begin{document}
\starsandbars{4}
\end{document}
具有键值接口的扩展版本;键是
longtable
(布尔值);如果表达,则longtable
产生apreamble
,用于指定longtable
前导码\endhead
等,或者在表的开头设置一些内容(参见第二个示例)
图片仅显示前两页。
\documentclass{article}
\usepackage{xparse,longtable}
\ExplSyntaxOn
\NewDocumentCommand{\starsandbars}{O{}m}
{
\group_begin:
\keys_set:nn { minthao/starsandbars } { #1 }
\minthao_starsandbars:n { #2 }
\__minthao_starsandbars_print_table:
\group_end:
}
\keys_define:nn { minthao/starsandbars }
{
longtable .bool_set:N = \l__minthao_starsandbars_longtable_bool,
longtable .default:n = { true },
longtable .initial:n = { false },
preamble .tl_set:N = \l__minthao_starsandbars_preamble_tl,
preamble .initial:n = \hline,
}
\tl_new:N \l__minthao_table_body_tl
\cs_new_protected:Npn \minthao_starsandbars:n #1
{
\tl_clear:N \l__minthao_table_body_tl
\int_step_inline:nnnn { 0 } { 1 } { #1 } % ##1 is x
{
\int_step_inline:nnnn { 0 } { 1 } { #1 - ##1 } % ####1 is y
{
\tl_put_right:Nx \l__minthao_table_body_tl
{
$(\int_to_arabic:n { ##1 },
\int_to_arabic:n { ####1 },
\int_to_arabic:n { #1 - ##1 - ####1 })$ &
}
\tl_put_right:Nx \l__minthao_table_body_tl
{
\prg_replicate:nn { ##1 } { $\star$ }
\exp_not:n { \,\vline\, }
\prg_replicate:nn { ####1 } { $\star$ }
\exp_not:n { \,\vline\, }
\prg_replicate:nn { #1 - ##1 - ####1 } { $\star$ }
}
\tl_put_right:Nn \l__minthao_table_body_tl { \\ \hline }
}
}
}
\cs_new_protected:Npn \__minthao_starsandbars_print_table:
{
\bool_if:NTF \l__minthao_starsandbars_longtable_bool
{ \begin{longtable} }
{ \begin{tabular} }
{|c|c|}
\l__minthao_starsandbars_preamble_tl
\l__minthao_table_body_tl
\bool_if:NTF \l__minthao_starsandbars_longtable_bool
{ \end{longtable} }
{ \end{tabular} }
}
\ExplSyntaxOff
\begin{document}
\starsandbars{3}
\bigskip
\starsandbars[
preamble=\hline\multicolumn{2}{|c|}{$x+y+z=4$}\\\hline
]{4}
\starsandbars[
longtable,
preamble={
\caption{$x+y+z=12$}\\
\hline
\endfirsthead
\caption*{$x+y+z=12$ (continued)}\\
\hline
\endhead
}
]{12}
\end{document}
答案2
不确定是否要求在括号中显示数字和画星号和横线。这个\starsandbars
宏只画星号和横线:
\documentclass[varwidth,border=5]{standalone}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{fourier}
\usepackage{pgffor}
\def\starsandbars#1{{\ensuremath{%
\edef\starlist{#1}%
\foreach \i [count=\a] in \starlist{%
\ifnum\a>1\big|\fi%
\ifnum\i>0\foreach \j in {1,...,\i}{\star}\fi%
}}}}%
\begin{document}
\foreach \i in {{0,1,2},{1,2,1},{0,0,5}, {1,3,0}, {4,3,2,6}}{\leavevmode
\hbox to .75in{(\i)\hfil} \starsandbars{\i} \par
}
\end{document}
答案3
问题已被标记,但如果您想按照原始表述tikz-pgf
来做,那么这是一项理想的工作。tabular
\xintFor
\documentclass{article}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{fourier}
\usepackage{xinttools}
% we need _ as private letter because we will employ \xint_dothis
% and \xint_orthat
\catcode`_ 11
\newcommand\barsandstars [1]{% solving x+y+z=#1 in non-negative integers
\edef\tmp_N {\numexpr\the\numexpr #1\relax\relax}%
\def\tmp_a {0}%
\def\tmp_b {0}%
\edef\tmp_c {\the\tmp_N }%
\begin{tabular}{|c|c|}
\hline
\xintFor ##1 in {\xintegers [0+1]}\do
{% ##1 = insertion location of first bar
\xintFor ##2 in {\xintegers [{\numexpr##1+1\relax}+1]}\do
{% ##2 = insertion location of second bar
% (first bar insertion has shifted by one all things to its right)
$(\tmp_a,\tmp_b,\tmp_c)$
&
$\xintFor ##3 in {\xintegers [0+1]}\do
{%
\ifnum ##3<##1\xint_dothis{\star}\fi
\ifnum ##3=##1\xint_dothis{\big|}\fi
\ifnum ##3<##2\xint_dothis{\star}\fi
\ifnum ##3=##2\xint_dothis{\big|}\fi
\xint_orthat {\star}%
\ifnum ##3>\tmp_N \expandafter\xintBreakFor\fi
}$
% The trick is to always decide if we need to continue BEFORE inserting \\
% and we must do non-expandable things before the \\
\xdef\tmp_b {\the\numexpr\tmp_b+1}%
\xdef\tmp_c {\the\numexpr\tmp_c-1}%
\ifnum ##2>\tmp_N \expandafter\xintBreakFor\fi
\\\hline
}%
\xdef\tmp_a {\the\numexpr\tmp_a+1\relax }%
\gdef\tmp_b {0}%
\xdef\tmp_c {\the\numexpr \tmp_N-\tmp_a\relax}%
\ifnum ##1=\tmp_N \expandafter\xintBreakFor\fi
\\\hline
}%
\\\hline
\end{tabular}
}
\catcode`_8
\begin{document}
\barsandstars {7}
\end{document}
答案4
如果“更快”意味着更短的代码不仅适用于 4,那么这里有一个 TikZ 解决方案:
\documentclass[tikz,border=7mm]{standalone}
\begin{document}
\begin{tikzpicture}[scale=.7]
\def\total{4} % i+j+k = total
\xdef\y{0}
\foreach \i in {0,...,\total}{
\pgfmathsetmacro{\maxj}{int(\total-\i)}
\foreach \j in {0,...,\maxj}{
\pgfmathparse{int(\y+1)}\xdef\y{\pgfmathresult}
\pgfmathsetmacro{\k}{int(\total-\i-\j)}
\foreach \i in {1,...,\total}
\node at (\i,\y){$\star$};
\node at (.45+\j+\i,\y) {$\big|$};
\node at (.55+\i,\y) {$\big|$};
\node[left] at (-1,\y){(\i,\j,\k)};
}
}
\end{tikzpicture}
\end{document}
如果你设置,\def\total{2}
你会得到:
我不会公布 7 的结果;)