LaTeX3 - 整数循环

LaTeX3 - 整数循环

下面的代码尝试实现埃拉托斯特尼筛法,但布尔测试失败:在下面的 M(not)WE 中,最大整数为 4,因此大于 4 的整数应被忽略。我遗漏了什么?

在此处输入图片描述

\documentclass{article}

\ExplSyntaxOn

\int_new:N \l_row_int
\int_new:N \l_col_int

\NewDocumentCommand\eratosthenes{ O{#2}m }{   
    \seq_new:N \l_notprime_seq
    
    \int_new:N  \l_tested_int
    \int_set:Nn \l_tested_int { 1 }
    
    \int_new:N  \l_striked_int

    \int_new:N  \l_max_int
    \int_set:Nn \l_max_int { #2*#2 }
    
    \int_do_while:nn {
%        \l_tested_int <= #2
        % The following inefficient test shows one of my problem.
        \l_tested_int <= \l_max_int 
    } {
        \int_compare:nNnTF \l_tested_int = 1 {
            STRIKE ~ ME: ~ 1
            \seq_put_left:Nn \l_notprime_seq 1
        } {
            \seq_if_in:NnF \l_notprime_seq \l_tested_int {
                \int_set:Nn \l_striked_int { 2*\l_tested_int }
                
                \int_do_while:nn {
                    \l_striked_int <= \l_max_int
                } {
%                    \seq_if_in:NnF \l_notprime_seq \l_striked_int {
                        \\ STRIKE ~ ME: ~ \int_use:N \l_striked_int
                        \seq_put_left:Nn \l_notprime_seq {\l_striked_int}
%                    }
    
                    \int_set:Nn \l_striked_int { \l_striked_int + \l_tested_int }         
                }
            }
        }
        
        \int_incr:N \l_tested_int
        
%        \int_show:N \l_tested_int
%        \int_show:N \l_max_int
        
%        \seq_show:N \l_notprime_seq
    }
}

\ExplSyntaxOff


\begin{document}

\eratosthenes{2}

\end{document}

答案1

这是循环的基本解决方案。\int_while_do必须使用 而不是\int_do_while。即使这给出了正确的“视觉”算法,仍然需要提高整数序列的使用效率,但这在这里不起作用。请参阅下面的解决方案。

\documentclass{article}

\ExplSyntaxOn

\int_new:N \l_row_int
\int_new:N \l_col_int

\NewDocumentCommand\eratosthenes{ O{#2}m }{   
    \seq_new:N \l_notprime_seq
    
    \int_new:N  \l_tested_int
    \int_set:Nn \l_tested_int { 1 }
    
    \int_new:N  \l_striked_int

    \int_new:N  \l_max_int
    \int_set:Nn \l_max_int { #2*#2 }
   
    \int_while_do:nn {
%        \l_tested_int <= #2
%        The following inefficient test shows one of my problem.
        \l_tested_int <= \l_max_int 
    } {
        \int_compare:nNnTF \l_tested_int = 1 {
            \\ \quad STRIKE ~ THIS: ~ 1
            \seq_put_left:Nn \l_notprime_seq 1
        } {
            \seq_if_in:NnTF \l_notprime_seq \l_tested_int {
                \\ PRIME: ~ \int_use:N \l_tested_int
            } {
                \int_set:Nn \l_striked_int { 2*\l_tested_int }
                
                \int_while_do:nn {
                    \l_striked_int <= \l_max_int
                } {
%                    \seq_if_in:NnF \l_notprime_seq \l_striked_int {
                        \\ \quad STRIKE ~ ME: ~ \int_use:N \l_striked_int
                        \seq_put_left:Nn \l_notprime_seq {\l_striked_int}
%                    }
    
                    \int_set:Nn \l_striked_int { \l_striked_int + \l_tested_int }         
                }
            }
        }
        
        \int_incr:N \l_tested_int
    }
}

\ExplSyntaxOff


\begin{document}

\noindent \eratosthenes{3}

\end{document}

该代码可正确打印。

STRIKE THIS: 1
STRIKE ME: 4 
STRIKE ME: 6 
STRIKE ME: 8 
STRIKE ME: 6 
STRIKE ME: 9 
STRIKE ME: 8

最终版本仅敲击一次数字

这是我正在寻找的代码。这是一个有趣的LaTeX3练习。

在此处输入图片描述

\documentclass{article}

\usepackage{nicematrix}
\usepackage{tikz}

\NewDocumentCommand\drawstrike{ mm } {  
    \begin{tikzpicture}[
        remember picture, 
        overlay
    ]
        \draw[
            very thick, 
            red, 
            opacity = 0.3
        ] 
        ([xshift=-3pt]this-#1-#2.north west)
        --
        ([xshift=3pt]this-#1-#2.south east);
    \end{tikzpicture}
}

\ExplSyntaxOn

\int_new:N \l_row_int
\int_new:N \l_col_int

\NewDocumentCommand\strikeme{ mm } {
    \int_set:Nn \l_row_int { \int_div_truncate:nn {#2}{#1} }
    \int_set:Nn \l_col_int { \int_mod:nn {#2} {#1}}
    
    \int_compare:nNnTF \l_col_int = 0 {
        \int_set:Nn \l_col_int { #1 }
    } {
        \int_set:Nn \l_row_int { \l_row_int + 1}
    }

    \drawstrike{\int_use:N \l_row_int}{\int_use:N \l_col_int}
}

\NewDocumentCommand\eratosthenes{ O{#2}m }{   
    $\AutoNiceMatrix[
        hvlines, 
        columns - width = auto,
        name            = this
    ]{
        #2-#2
    }{
        \cellval{#2}{\arabic{iRow}}{\arabic{jCol}}
    }$

    \seq_new:N \l_notprime_seq
    
    \int_new:N  \l_tested_int
    \int_set:Nn \l_tested_int { 1 }
    
    \int_new:N  \l_striked_int

    \int_new:N  \l_max_int
    \int_set:Nn \l_max_int { #2*#2 }
    
    \int_while_do:nn {
         \l_tested_int <= #2
    } {
        \int_compare:nNnTF \l_tested_int = 1 {
            \strikeme{#2}{1}
            \seq_put_left:Nn \l_notprime_seq 1
        } {
            \seq_if_in:NxF \l_notprime_seq {\int_use:N \l_tested_int} {
                \int_set:Nn \l_striked_int { 2*\l_tested_int }
                
                \int_while_do:nn {
                    \l_striked_int <= \l_max_int
                } {
                    \seq_if_in:NxF \l_notprime_seq {\int_use:N \l_striked_int} {
                        \strikeme{#2}{\int_use:N \l_striked_int}
                        \seq_put_left:Nx \l_notprime_seq {\int_use:N \l_striked_int}
                    }
    
                    \int_set:Nn \l_striked_int { \l_striked_int + \l_tested_int }         
                }
            }
        }
        
        \int_incr:N \l_tested_int
    }
}

\NewDocumentCommand\cellval{ mmm }{    
    \int_eval:n{#3 + #1*(#2 - 1)}
}

\ExplSyntaxOff


\begin{document}

\eratosthenes{10}

\end{document}

相关内容