2

While trying to figure a complete answer to this post, I was wondering how I could get the total amount of lines in the algorithmic environment.

Of course this question can be relevant for other environments.

I already tried with the totcount package but when trying to use the final value of a counter with \totalvalue{<counter>} inside a \makeatketter ... \makeatother it fails.

I'm pretty sure I am missing some basic thing so would like to understand this issue better.

Other previous answers e.g. this one for instance address this issue for other environments but I could not figure how to adapt them to this case.

Here is the MWE adapted from the post I am trying to answer.

\documentclass[a4paper,10pt]{IEEEtran}
\usepackage{totcount}
\usepackage{algpseudocode}

\regtotcounter{ALG@line}

% Patch the line numbering to display the first and last line numbers
\makeatletter
\def\ALG@step%
   {%
   \addtocounter{ALG@line}{1}%
   \addtocounter{ALG@rem}{1}%
   % Beginning of patch
   % First line
   \ifthenelse{\equal{\arabic{ALG@line}}{1}}%
      {\alglinenumber{\arabic{ALG@line}}}%
      {}%
   % Last line  --> DOES NOT WORK
%   \ifthenelse{\equal{\arabic{ALG@line}}{\arabic{\total{ALG@line}}}}%
%      {\alglinenumber{\arabic{ALG@line}}}%
%      {}%
   % End of patch
   \ifthenelse{\equal{\arabic{ALG@rem}}{\ALG@numberfreq}}%
      {\setcounter{ALG@rem}{0}\alglinenumber{\arabic{ALG@line}}}%
      {}%
   }%
\makeatother


\begin{document}
See \figurename{~\ref{fig:myalgorithm}} below.

\begin{figure}[!ht]
 \noindent\rule{\linewidth}{0.8pt}
 \noindent \textbf{Algorithm} itsname
 \noindent\hrule
 \begin{algorithmic}[3]
  \Procedure {BellmanKalaba}{$G$, $u$, $l$, $p$}
  \ForAll {$v \in V(G)$}
  \State $l(v) \leftarrow \infty$
  \EndFor
  \State $l(u) \leftarrow 0$
  \Repeat
  \For {$i \leftarrow 1, n$}
  \State $min \leftarrow l(v_i)$
  \For {$j \leftarrow 1, n$}
  \If {$min > e(v_i, v_j) + l(v_j)$}
  \State $min \leftarrow e(v_i, v_j) + l(v_j)$
  \State $p(i) \leftarrow v_j$
  \EndIf
  \EndFor
  \State $l'(i) \leftarrow min$
  \EndFor
  \State $changed \leftarrow l \not= l'$
  \State $l \leftarrow l'$
  \Until{$\neg changed$}
  \EndProcedure
 \end{algorithmic}
 \noindent\rule{\linewidth}{0.8pt}
 \caption{This algorithm was copied from the algorithmicx's package documentation.}\label{fig:myalgorithm}
\end{figure}

Total amount of lines in the algorithm: \total{ALG@line}


\end{document}

enter image description here

5
  • I'd use a two run solution saving the highest counter number of the current environment. How else should the line number printing command know it's the last one. – Skillmon Sep 4 '18 at 12:19
  • One could do so by adding stuff to \endalgorithmic (e.g. with etoolbox and \AtEndEnvironment), but you'd have to take care that you get a separate marker for each algorithmic, e.g. by using another counter. – Skillmon Sep 4 '18 at 12:24
  • @Skillmon, I would also use a two step process, hence the totcount package. However, I can't figure how to provide the stored value to the definition of \ALG@step so it can be used for some logical test – BambOo Sep 4 '18 at 12:35
  • So the goal to fix your \ALG@step, not get the number of lines (\arabic{ALG@line}). – John Kormylo Sep 4 '18 at 13:22
  • @JohnKormylo. Well it's both. I know how to patch \ALG@step, but i don't know how to provide the total amount of lines in it. – BambOo Sep 4 '18 at 13:32
2

The following is a two-run approach solving your issue. I permit you to use it in order to answer the other question, but please give me credit :)

\documentclass[a4paper,10pt]{IEEEtran}
\usepackage{totcount}
\usepackage{algpseudocode}

\usepackage{etoolbox}

\regtotcounter{ALG@line}

% Patch the line numbering to display the first and last line numbers
\makeatletter
% execute this code at \end{algorithmic} but before the group is closed
\AtEndEnvironment{algorithmic}{\@WriteAlgorithmicLastLine}
% execute this code at \begin{algorithmic} just after the group is opened
\AtBeginEnvironment{algorithmic}{\stepcounter{AlgorithmicEnvironmentCounter}}
\newcounter{AlgorithmicEnvironmentCounter}
\newcommand*\@WriteAlgorithmicLastLine
  {% this macro writes the definition to the aux file, you have to make sure
   % that only the right stuff is expanded (\write expands its argument as
   % much as it is able to)
    \immediate\write\@auxout
      {%
        % we don't want \expandafter to disappear
        \unexpanded{\expandafter\gdef}%
        % we don't want \csname to do its work just here
        \unexpanded{\csname @AlgorithmicLastLine@}%
        % the counter should be expanded
        \the\c@AlgorithmicEnvironmentCounter%
        % \endcsname isn't expandable (if you're unsure whether something is
        % expandable enclose it by \unexpanded or precede it with \noexpand)
        \endcsname%
        % this counter should as well be expanded
        {\arabic{ALG@line}}%
      }%
  }
\def\ALG@step%
  {%
    \addtocounter{ALG@line}{1}%
    \addtocounter{ALG@rem}{1}%
    % Beginning of patch
   \ifthenelse{\equal{\arabic{ALG@rem}}{\ALG@numberfreq}}%
      {\setcounter{ALG@rem}{0}\alglinenumber{\arabic{ALG@line}}}%
      {% if it is no line that already gets a number one of the other rules
       % might apply
        \ifthenelse{\equal{\arabic{ALG@line}}{1}}%
          {\alglinenumber{\arabic{ALG@line}}}%
          {% if not the first line, it may be the last
            % \ifcsdef is a wrapper around \ifcsname to check whether something
            % is defined or not
            \ifcsdef
              {@AlgorithmicLastLine@\arabic{AlgorithmicEnvironmentCounter}}%
              {% if it is defined execute this code
                % \ifnum is a TeX primitive comparing the following two numbers
                % and executing the true branch if the comparison is true,
                % possible comparisons are '=', '>' and '<'.
                \ifnum
                  % csuse is a wrapper around \csname building the
                  % control-sequence which's name is the argument of \csuse
                  % (argument is fully expanded)
                  \csuse
                    {%
                      @AlgorithmicLastLine@%
                      \arabic{AlgorithmicEnvironmentCounter}%
                    }%
                  =\c@ALG@line
                  \alglinenumber{\arabic{ALG@line}}%
                \fi
              }%
              {}% not defined
          }%
      }%
   }%
\makeatother


\begin{document}
See \figurename{~\ref{fig:myalgorithm}} below.

\begin{figure}[!ht]
 \noindent\rule{\linewidth}{0.8pt}
 \noindent \textbf{Algorithm} itsname
 \noindent\hrule
 \begin{algorithmic}[3]
  \Procedure {BellmanKalaba}{$G$, $u$, $l$, $p$}
  \ForAll {$v \in V(G)$}
  \State $l(v) \leftarrow \infty$
  \EndFor
  \State $l(u) \leftarrow 0$
  \Repeat
  \For {$i \leftarrow 1, n$}
  \State $min \leftarrow l(v_i)$
  \For {$j \leftarrow 1, n$}
  \If {$min > e(v_i, v_j) + l(v_j)$}
  \State $min \leftarrow e(v_i, v_j) + l(v_j)$
  \State $p(i) \leftarrow v_j$
  \EndIf
  \EndFor
  \State $l'(i) \leftarrow min$
  \EndFor
  \State $changed \leftarrow l \not= l'$
  \State $l \leftarrow l'$
  \Until{$\neg changed$}
  \EndProcedure
 \end{algorithmic}
 \noindent\rule{\linewidth}{0.8pt}
 \caption
  {%
    This algorithm was copied from the algorithmicx's package documentation.%
    \label{fig:myalgorithm}%
  }
\end{figure}

Total amount of lines in the algorithm: \total{ALG@line}

\begin{figure}[!ht]
 \noindent\rule{\linewidth}{0.8pt}
 \noindent \textbf{Algorithm} itsname
 \noindent\hrule
 \begin{algorithmic}[3]
  \Procedure {BellmanKalaba}{$G$, $u$, $l$, $p$}
  \ForAll {$v \in V(G)$}
  \State $l(v) \leftarrow \infty$
  \EndFor
  \State $l(u) \leftarrow 0$
  \Repeat
  \For {$i \leftarrow 1, n$}
  \State $min \leftarrow l(v_i)$
  \For {$j \leftarrow 1, n$}
  \If {$min > e(v_i, v_j) + l(v_j)$}
  \State $min \leftarrow e(v_i, v_j) + l(v_j)$
  \State $p(i) \leftarrow v_j$
  \EndIf
  \EndFor
  \State $l'(i) \leftarrow min$
  \EndFor
  \Until{$\neg changed$}
  \EndProcedure
 \end{algorithmic}
 \noindent\rule{\linewidth}{0.8pt}
 \caption
  {%
    This algorithm was copied from the algorithmicx's package documentation.%
    \label{fig:myalgorithm2}%
  }
\end{figure}

\end{document}

EDIT: I've added some comments in the above code hopefully describing everything.

EDIT 2: Solving the bugs of multiple line numberings.

4
  • Well thanks Skillmon ! I checked etoolbox too but I just don't know enough of such commands to make a solution on my own. If you could just add a few comments, to fully understand what you propose it would be perfect ! I will of course credit you in the initial post ;) – BambOo Sep 4 '18 at 15:14
  • @BambOo see my edits, I hope the comments are enough, if anything remains unclear just ask. – Skillmon Sep 4 '18 at 15:30
  • Thanks. There is still a small glitch, but let me try to find myself so I can take a bit of credit ^^. FYI, the last line may be print twice due to the redundancy bteween your patch and \ALG@numberfreq – BambOo Sep 4 '18 at 15:34
  • @BambOo you're right, but that is easy enough to fix :) – Skillmon Sep 4 '18 at 15:37
1

Since counters are saved globally, all you need is \arabic{ALG@line}. If you want to access it before it is computed, you can fake a \label.

\documentclass[a4paper,10pt]{IEEEtran}
\usepackage{totcount}
\usepackage{algpseudocode}

\begin{document}
See \figurename{~\ref{fig:myalgorithm}} below (\ref{ALGlines} lines).

\begin{figure}[!ht]
 \noindent\rule{\linewidth}{0.8pt}
 \noindent \textbf{Algorithm} itsname
 \noindent\hrule
 \begin{algorithmic}[3]
  \Procedure {BellmanKalaba}{$G$, $u$, $l$, $p$}
  \ForAll {$v \in V(G)$}
  \State $l(v) \leftarrow \infty$
  \EndFor
  \State $l(u) \leftarrow 0$
  \Repeat
  \For {$i \leftarrow 1, n$}
  \State $min \leftarrow l(v_i)$
  \For {$j \leftarrow 1, n$}
  \If {$min > e(v_i, v_j) + l(v_j)$}
  \State $min \leftarrow e(v_i, v_j) + l(v_j)$
  \State $p(i) \leftarrow v_j$
  \EndIf
  \EndFor
  \State $l'(i) \leftarrow min$
  \EndFor
  \State $changed \leftarrow l \not= l'$
  \State $l \leftarrow l'$
  \Until{$\neg changed$}
  \EndProcedure
 \end{algorithmic}
 \noindent\rule{\linewidth}{0.8pt}
 \caption{This algorithm was copied from the algorithmicx's package documentation.}\label{fig:myalgorithm}
 \addtocounter{ALG@line}{-1}\refstepcounter{ALG@line}\label{ALGlines}%
\end{figure}

Total amount of lines in the algorithm: \arabic{ALG@line}

\end{document}
1
  • I guess I wasn't clear enough. The last sentence is there just for example. The issue is in the patch for algorithmicx that I am trying to provide. – BambOo Sep 4 '18 at 13:17

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.