# How to do recursive program with latex

I am trying to make a schedule for two groups of people who will watch the same experimental lectures at the same laboratory in different dates. I need to skip the holidays. I intend to get something like this:

I tried, with no success, this code:

\documentclass{article}

%... Set the first practice date
\ThisDay{7}\ThisMonth{2}\ThisYear{2019}     %... quinta-feira

%... the number of days between lectures

\newcommand{\holidaylist}{%
{March 03, 2019}, % ter Carnaval
{April 18, 2019}, % qui Atividade complementar
{April 19, 2019}, % sex Santa
{April 21, 2019}, % dom Tiradentes/Páscoa
{May 01, 2019},   % qua Trabalhador
{June 19, 2019}   % qua Aniv. Rib. Preto
}

%... the next-practice command
\newif\ifholiday
\def\groupA{}
\def\groupB{}
\newcommand{\nextprac}{%
\holidayfalse
\foreach \D in \holidaylist{%
\ifx \today \D
\holidaytrue
\breakforeach
\fi
\ifholiday
\nexprac
\else
\ifx \groupA \empty
\def\groupA{\today}
\nextprac
\else
\ifx \groupB \empty
\def\groupB{\today}
\section*{\groupA\ $\parallel$ \groupB}
\vspace{-5mm}
\def\groupA{}
\def\groupB{}
\fi
\fi
\fi
}
}

\begin{document}

\nextprac
Practice one

\nextprac
Practice two

\nextprac
Practice three

\nextprac
Practice four

\nextprac
Practice five

\nextprac
Practice six

\nextprac
Practice seven

\nextprac
Practice eight

\nextprac
Practice nine

\nextprac
Practice ten

\end{document}


I also tried this code, but didn't work too:

\documentclass{article}

%... Set the first practice date
\ThisDay{7}\ThisMonth{2}\ThisYear{2019}     %... quinta-feira

%... the number of days between lectures

\newcommand{\holidaylist}{%
{March 3, 2019}, % ter Carnaval
{April 18, 2019}, % qui Atividade complementar
{April 19, 2019}, % sex Santa
{April 21, 2019}, % dom Tiradentes/Páscoa
{May 1, 2019},   % qua Trabalhador
{June 19, 2019}   % qua Aniv. Rib. Preto
}

%... the next-practice command
\newif\ifalldone
\newif\ifholiday
\def\groupA{}
\def\groupB{}
\newcommand{\nextprac}{%
\holidayfalse
\foreach \D in \holidaylist{%
% <1
\ifx \today \D
\holidaytrue
\breakforeach
\fi
% 1>
% <1
\ifholiday
\else
% <2
\ifx \groupA \empty
\SaveDate[\dayA]
\def\groupA{\dayA}
\else
% <3
\ifx \groupB \empty
\SaveDate[\dayB]
\def\groupB{\dayB}
\alldonetrue
% 3>
\fi
% 2>
\fi
% 1>
\fi
}
\ifalldone
\section*{\groupA\ $\parallel$ \groupB}
\vspace{-5mm}
\def\groupA{}
\def\groupB{}
\alldonefalse
\else
\nextprac
\fi
}

\begin{document}

\nextprac
Practice one

\nextprac
Practice two

\nextprac
Practice three

\nextprac
Practice four

\nextprac
Practice five

\nextprac
Practice six

\nextprac
Practice seven

\nextprac
Practice eight

\nextprac
Practice nine

\nextprac
Practice ten

\end{document}


I believe that latex is not understanding the recursion I am trying asking it to do. Observe that I need an answer with the \if internal package and the \advdate (because I am afraid any other new package could conflict with the other ones I am already loading, which is not shown here for simplicity).

Can any one tell me what I am doing wrong or (better) provide a working solution, please? Thank you!

• One issue here is that the \if statements are recursively nested and TeX only allows 256 level, if I remember correctly. This can sometimes fixed by expanding (i.e. removing in this case) the else part: \expandafter\nextprac\else or better \expandafter\expandafter\expandafter\nextprac\else .... \fi \fi which will close the open if-statement and then process \nextprac outside of it. – Martin Scharrer Jan 30 at 11:58
• However, calling \foreach \D ... again from inside it will overwrite the \D variable, so when the inner call will end the outer loop will continue with a wrong value. You might want to unroll your recursion or use a different for-loop construction. I can't tell you which one will work, unfortunately. – Martin Scharrer Jan 30 at 12:01

Your primary issue is that \foreach forms a group. That means that the manipulation done by \AdvanceDate never leaves the the loop. I'd therefore avoid that loop structure and do things manually.

You also need to watch that \today is a command which prints the date, not the date itself. I'd therefore avoid a text-based comparison, and check day/month/year explicitly. I'd also avoid try to store the output of \today, and instead store the \day/\month/\year that are right for group A. That leads to something like

\documentclass{article}

% Set the first practice date
\ThisDay{7}
\ThisMonth{2}
\ThisYear{2019}

%... the number of days between lectures
\newcommand*{\lecturegap}{7}

\makeatletter
\newcounter{holiday}
\stepcounter{holiday}%
\@namedef{holiday\arabic{holiday}}{%
\def\holidayDay{#1}%
\def\holidayMonth{#2}%
\def\holidayYear{#3}%
}%
}
\makeatother
\newcommand*{\holidayDay}{0}
\newcommand*{\holidayMonth}{0}
\newcommand*{\holidayYear}{0}
\addholiday{19}{6}{2019} % qua Aniv. Rib. Preto

\newif\ifholiday
\newcommand*{\groupA}{}
\makeatletter
\newcommand*{\nextprac}{%
\holidayfalse
\count0=1 %
\loop
\ifnum\count0>\value{holiday}\else
\@nameuse{holiday\number\count0 }%
\ifnum 0%
\ifnum\holidayDay=\day1\else0\fi
\ifnum\holidayMonth=\month1\else0\fi
\ifnum\holidayYear=\year1\else0\fi
=111 %
\holidaytrue
\count0=\value{holiday}%
\else
\fi
\repeat
\ifholiday
\expandafter\nextprac
\else
\ifx\groupA\empty
\edef\groupA{%
{\day=\the\day\month=\the\month\year=\the\year\relax\noexpand\today}}%
\expandafter\expandafter\expandafter\nextprac
\else
\section*{\groupA\space$\parallel$ \today}%
\def\groupA{}%
\fi
\fi
}

\begin{document}

\nextprac
Practice one

\nextprac
Practice two

\nextprac
Practice three

\nextprac
Practice four

\nextprac
Practice five

\nextprac
Practice six

\nextprac
Practice seven

\nextprac
Practice eight

\nextprac
Practice nine

\nextprac
Practice ten

\end{document}

• Just a last question: how can I change the date format to display dd/mm? Thank you in advance! – Brasil Jan 30 at 14:15
• @Brasil That's a separate question: it's nothing to do with the programming, rather to do with altering the definition of \today. Please post it sepaarately. – Joseph Wright Jan 30 at 15:01
• Hi, @JosephWright, how are you? I just realized that your solution brings a problem to page numbering. Check that the very code above leads to pages numbers = 7. How can we fix it? – Brasil Mar 6 at 22:00