%%%
% Rullo
%%%
\def\filedateRullo{2025/11/19}%
\def\fileversionRullo{0.1b}%
\message{-- \filedateRullo\space v\fileversionRullo}%
%
\setKVdefault[Rullo]{ValeurMin=2,ValeurMax=9,Taille=5,Solution=false,Hauteur=20pt,Graine={},CouleurSolution={}}%
%
\NewDocumentCommand\Rullo{o}{%
  \useKVdefault[Rullo]%
  \setKV[Rullo]{#1}%
  \ifemptyKV[Rullo]{Graine}{}{\PfCGraineAlea{\useKV[Rullo]{Graine}}}%
  \ifemptyKV[Rullo]{CouleurSolution}{}{\setKV[Rullo]{Solution}\colorlet{PfCRulloCoulSol}{\useKV[Rullo]{CouleurSolution}}}%
  \edef\RulloTaille{\useKV[Rullo]{Taille}}%
  \PfCChoixAleaMultiMixRep{\fpeval{\RulloTaille*\RulloTaille}}{\useKV[Rullo]{ValeurMin}}{\useKV[Rullo]{ValeurMax}}{0,1}{\ListeAav}%
  \setsepchar{,}\ignoreemptyitems%
  \readlist*\ListeFacteurA{\ListeAav}%
  \ifnum\fpeval{\RulloTaille}=3\relax%
    \ChoixAlea{1}{\fpeval{\RulloTaille}}{\LaFa}%
    \PfCChoixAleaMultiMix{1}{1}{\fpeval{\RulloTaille}}{\LaFa}{\LaFb}%
    \PfCChoixAleaMultiMix{1}{1}{\fpeval{\RulloTaille}}{\LaFa,\LaFb}{\LaFc}%
    \edef\PfMFooRullo{\LaFa,\LaFb,\LaFc}%
    \setsepchar{,}\ignoreemptyitems%
    \readlist*\ListeTrouee{\PfMFooRullo}%
    \edef\PfMFooProduitsH{}%
    \xintFor* ##1 in {\xintSeq{1}{\RulloTaille}}\do{%
      \edef\PfMFooFacteurs{1}%
      \xintFor* ##2 in {\xintSeq{1}{\RulloTaille}}\do{%
        \itemtomacro\ListeTrouee[##1]\PfMTiti%
        \xintifboolexpr{##2==\PfMTiti}{}{\edef\PfMFooFacteurs{\fpeval{\PfMFooFacteurs*\ListeFacteurA[\fpeval{\RulloTaille*(##1-1)+##2}]}}%
        }%
      }%
      \edef\PfMFooProduitsH{\PfMFooProduitsH,\PfMFooFacteurs}%
    }%
    \setsepchar{,}\ignoreemptyitems%
    \readlist*\ListeFacteursH{\PfMFooProduitsH}%
    \reademptyitems%
    \edef\PfMFooProduitsV{}%
    \xintFor* ##1 in {\xintSeq{1}{\RulloTaille}}\do{%
      \edef\PfMFooFacteurs{1}%
      \xintFor* ##2 in {\xintSeq{1}{\RulloTaille}}\do{%
        \edef\PfMFooFacteurs{\fpeval{\PfMFooFacteurs*\ListeFacteurA[\fpeval{##1+\RulloTaille*(##2-1)}]}}%
      }%
      \foreachitem\compteur\in\ListeTrouee{%
        \itemtomacro\ListeTrouee[\compteurcnt]\PfMTiti%
        \xintifboolexpr{##1==\PfMTiti}{\edef\PfMFooFacteurs{\fpeval{\PfMFooFacteurs/\ListeFacteurA[\fpeval{##1+\RulloTaille*(\compteurcnt-1)}]}}}{}%
      }%
      \edef\PfMFooProduitsV{\PfMFooProduitsV,\PfMFooFacteurs}%
    }%
    \setsepchar{,}\ignoreemptyitems%
    \readlist*\ListeFacteursV{\PfMFooProduitsV}%
    \PfCChoixAleaMultiMix{\RulloTaille}{1}{\RulloTaille}{0}{\ListeChgtAv}%
    \setsepchar{,}\ignoreemptyitems%
    \readlist*\ListeChgt{\ListeChgtAv}%
    \begin{tabular}{|*{\fpeval{\RulloTaille+1}}{c|}}%
      \hhline{~---}%
      \multicolumn{1}{c|}{}\xintFor* ##1 in{\xintSeq{1}{\RulloTaille}}\do{%
      &\cellcolor{gray!15}\num{\ListeFacteursV[##1]}}\\
      \hhline{----}%
      \xintFor*##2 in{\xintSeq{1}{\fpeval{\RulloTaille}}}\do{%
      \cellcolor{gray!15}\num{\ListeFacteursH[##2]}\xintFor* ##1 in{\xintSeq{1}{\RulloTaille}}\do{%
      &\xintifboolexpr{##1==\ListeTrouee[##2]}{\ifboolKV[Rullo]{Solution}{\cellcolor{PfCRulloCoulSol}}{}}{}\num{\ListeFacteurA[\fpeval{\RulloTaille*(##2-1)+##1}]}%
        }\\
      \hhline{----}%
      }%
    \end{tabular}
  \else%
    \edef\PfMFooRullo{}%
    \edef\PfCRetiensSomme{0}%
    \xintFor* ##1 in {\xintSeq{2}{\RulloTaille}}\do{%
      \edef\PfCRetiensSomme{\PfCRetiensSomme,0}%
    }%
    \setsepchar{,}\ignoreemptyitems%
    \readlist*\ListeSomme{\PfCRetiensSomme}%
    % L1
    \ChoixAlea{1}{\fpeval{\RulloTaille}}{\LaFaun}%
    \edef\PfCRetiensSomme{}%
    \foreachitem\compteur\in\ListeSomme{%
      \ifnum\fpeval{\compteurcnt}=\fpeval{\LaFaun}\relax%
        \edef\PfCRetiensSomme{\PfCRetiensSomme,\fpeval{\compteur+1}}%
      \else%
        \edef\PfCRetiensSomme{\PfCRetiensSomme,\compteur}%
      \fi%
    }%
    \setsepchar{,}\ignoreemptyitems%
    \readlist*\ListeSomme{\PfCRetiensSomme}%
    \PfCChoixAleaMultiMix{1}{1}{\fpeval{\RulloTaille}}{\LaFaun}{\LaFaDeux}%
    \setsepchar{,}\ignoreemptyitems%
    \readlist*\ListeNombreTester{\LaFaDeux}%
    \edef\PfCRetiensSomme{}%
    \foreachitem\compteur\in\ListeSomme{%
      \ifnum\fpeval{\compteurcnt}=\fpeval{\ListeNombreTester[1]}\relax%
        \edef\PfCRetiensSomme{\PfCRetiensSomme,\fpeval{\compteur+1}}%
      \else%
        \edef\PfCRetiensSomme{\PfCRetiensSomme,\compteur}%
      \fi%
    }%
    \edef\PfMFooRullo{\LaFaun,\LaFaDeux}%
    \setsepchar{,}\ignoreemptyitems%
    \readlist*\ListeSomme{\PfCRetiensSomme}%
    % L2
    \ChoixAlea{1}{\fpeval{\RulloTaille}}{\LaFaun}%
    \edef\PfCRetiensSomme{}%
    \foreachitem\compteur\in\ListeSomme{%
      \ifnum\fpeval{\compteurcnt}=\fpeval{\LaFaun}\relax%
        \edef\PfCRetiensSomme{\PfCRetiensSomme,\fpeval{\compteur+1}}%
      \else%
        \edef\PfCRetiensSomme{\PfCRetiensSomme,\compteur}%
      \fi%
    }%
    \setsepchar{,}\ignoreemptyitems%
    \readlist*\ListeSomme{\PfCRetiensSomme}%
    \reademptyitems%
    \PfCChoixAleaMultiMix{1}{1}{\fpeval{\RulloTaille}}{\LaFaun}{\LaFaDeux}%
    \edef\PfCRetiensSomme{}%
    \readlist*\ListeNombreTester{\LaFaDeux}%
    \edef\PfCRetiensSomme{}%
    \foreachitem\compteur\in\ListeSomme{%
      \ifnum\fpeval{\compteurcnt}=\fpeval{\ListeNombreTester[1]}\relax%
        \edef\PfCRetiensSomme{\PfCRetiensSomme,\fpeval{\compteur+1}}%
      \else%
        \edef\PfCRetiensSomme{\PfCRetiensSomme,\compteur}%
      \fi%
    }%
    \edef\PfMFooRullo{\PfMFooRullo,\LaFaun,\LaFaDeux}%
    \setsepchar{,}\ignoreemptyitems%
    \readlist*\ListeSomme{\PfCRetiensSomme}%
    % Lignes suivantes
    \xintFor* ##1 in{\xintSeq{3}{\fpeval{\RulloTaille-1}}}\do{%
      \edef\PfMColonnesExclues{0}%
      \foreachitem\compteur\in\ListeSomme{%
        \ifnum\fpeval{\compteur}=2\relax%
          \edef\PfMColonnesExclues{\PfMColonnesExclues,\compteurcnt}%
        \fi%
      }%
      \PfCChoixAleaMultiMix{1}{1}{\fpeval{\RulloTaille}}{\PfMColonnesExclues}{\LaFaun}%
      \edef\PfCRetiensSomme{}%
      \setsepchar{,}\ignoreemptyitems
      \readlist*\ListeNombreTester{\LaFaun}%
      \foreachitem\compteur\in\ListeSomme{%
        \ifnum\fpeval{\compteurcnt}=\fpeval{\ListeNombreTester[1]}\relax%
          \edef\PfCRetiensSomme{\PfCRetiensSomme,\fpeval{\compteur+1}}%
        \else%
          \edef\PfCRetiensSomme{\PfCRetiensSomme,\compteur}%
        \fi%
      }%
      \setsepchar{,}\ignoreemptyitems%
      \readlist*\ListeSomme{\PfCRetiensSomme}%
      % 
      \PfCChoixAleaMultiMix{1}{1}{\fpeval{\RulloTaille}}{\PfMColonnesExclues,\LaFaun}{\LaFaDeux}%
      \edef\PfCRetiensSomme{}%
      \readlist*\ListeNombreTester{\LaFaDeux}%
      \edef\PfCRetiensSomme{}%
      \foreachitem\compteur\in\ListeSomme{%
        \ifnum\fpeval{\compteurcnt}=\fpeval{\ListeNombreTester[1]}\relax%
          \edef\PfCRetiensSomme{\PfCRetiensSomme,\fpeval{\compteur+1}}%
        \else%
          \edef\PfCRetiensSomme{\PfCRetiensSomme,\compteur}%
        \fi%
      }%
      \edef\PfMFooRullo{\PfMFooRullo,\LaFaun,\LaFaDeux}%
      \setsepchar{,}\ignoreemptyitems%
      \readlist*\ListeSomme{\PfCRetiensSomme}%
    }%
    %    % 
    \edef\PfMColonnesExclues{0}%
    \foreachitem\compteur\in\ListeSomme{%
      \ifnum\fpeval{\compteur}=2\relax%
        \edef\PfMColonnesExclues{\PfMColonnesExclues,\compteurcnt}%
      \fi%
    }%
    \PfCChoixAleaMultiMix{1}{1}{\fpeval{\RulloTaille}}{\PfMColonnesExclues}{\LaFaun}%
    \edef\PfCRetiensSomme{}%
    \readlist*\ListeNombreTester{\LaFaun}%
    \foreachitem\compteur\in\ListeSomme{%
      \ifnum\fpeval{\compteurcnt}=\fpeval{\ListeNombreTester[1]}\relax%
        \edef\PfCRetiensSomme{\PfCRetiensSomme,\fpeval{\compteur+1}}%
      \else%
        \edef\PfCRetiensSomme{\PfCRetiensSomme,\compteur}%
      \fi%
    }%
    \edef\PfMFooRullo{\PfMFooRullo,\LaFaun}%
    \setsepchar{,}\ignoreemptyitems%
    \readlist*\ListeSomme{\PfCRetiensSomme}%
    \setsepchar{,}\ignoreemptyitems%
    \readlist*\ListeTrouee{\PfMFooRullo}%
    \edef\PfMFooProduitsH{}%
    \xintFor* ##1 in {\xintSeq{1}{\RulloTaille}}\do{%
      \edef\PfMFooFacteurs{1}%
      \xintFor* ##2 in {\xintSeq{1}{\RulloTaille}}\do{%
        \edef\PfMFooFacteurs{\fpeval{\PfMFooFacteurs*\ListeFacteurA[\fpeval{\RulloTaille*(##1-1)+##2}]}}%
      }%
      \itemtomacro\ListeTrouee[\fpeval{2*##1-1}]\PfMTiti%
      \xintFor* ##2 in {\xintSeq{1}{\RulloTaille}}\do{%
        \xintifboolexpr{##2==\PfMTiti}{%
          \edef\PfMFooFacteurs{\fpeval{\PfMFooFacteurs/\ListeFacteurA[\fpeval{\RulloTaille*(##1-1)+##2}]}}%
        }{}%
      }%
      \ifnum##1<\RulloTaille\relax%
        \xintFor* ##2 in {\xintSeq{1}{\RulloTaille}}\do{%
          \itemtomacro\ListeTrouee[\fpeval{2*##1}]\PfMTiti%
          \xintifboolexpr{##2==\PfMTiti}{%
            \edef\PfMFooFacteurs{\fpeval{\PfMFooFacteurs/\ListeFacteurA[\fpeval{\RulloTaille*(##1-1)+##2}]}}%
          }{}%
        }%
      \fi%
      \edef\PfMFooProduitsH{\PfMFooProduitsH,\PfMFooFacteurs}%
    }%
    \setsepchar{,}\ignoreemptyitems%
    \readlist*\ListeFacteursH{\PfMFooProduitsH}%
    % Les verticaux
    \edef\PfMFooProduitsV{}%
    \xintFor* ##1 in {\xintSeq{1}{\RulloTaille}}\do{%
      \edef\PfMFooFacteurs{1}%
      \xintFor* ##2 in {\xintSeq{1}{\RulloTaille}}\do{%
        \edef\PfMFooFacteurs{\fpeval{\PfMFooFacteurs*\ListeFacteurA[\fpeval{##1+\RulloTaille*(##2-1)}]}}%
      }%
      \foreachitem\compteur\in\ListeTrouee{%
        \itemtomacro\ListeTrouee[\compteurcnt]\PfMTiti%
        \xintifboolexpr{##1==\PfMTiti}{%
          \quotient{\fpeval{\compteurcnt-1}}{2}%
          \edef\PfMFooFacteurs{\fpeval{\PfMFooFacteurs/\ListeFacteurA[\fpeval{##1+\RulloTaille*\the\intquotient}]}}%
        }{}%
      }%
      \edef\PfMFooProduitsV{\PfMFooProduitsV,\PfMFooFacteurs}%
    }%
    \setsepchar{,}\ignoreemptyitems%
    \readlist*\ListeFacteursV{\PfMFooProduitsV}%
    \reademptyitems%
    % 
    \PfCChoixAleaMultiMix{\RulloTaille}{1}{\RulloTaille}{0}{\ListeChgtAv}%
    \setsepchar{,}\ignoreemptyitems%
    \readlist*\ListeChgt{\ListeChgtAv}%
    \begin{tabular}{|*{\fpeval{\RulloTaille+1}}{c|}}%
      \hhline{~*{\RulloTaille}{-}}
      \multicolumn{1}{c|}{}\xintFor* ##1 in{\xintSeq{1}{\RulloTaille}}\do{%
      &\cellcolor{gray!15}\num{\ListeFacteursV[##1]}
        }\\
      \hhline{*{\fpeval{\RulloTaille+1}}{-}}
      \xintFor*##2 in{\xintSeq{1}{\fpeval{\RulloTaille}}}\do{%
      \itemtomacro\ListeChgt[##2]\Toto
      \ifnum\fpeval{\Toto}=\fpeval{\RulloTaille}\relax
      \cellcolor{gray!15}\num{\ListeFacteursH[\RulloTaille]}\xintFor* ##1 in{\xintSeq{1}{\RulloTaille}}\do{%
      \uppercase{&}\xintifboolexpr{##1==\ListeTrouee[\fpeval{2*\RulloTaille-1}]}{\ifboolKV[Rullo]{Solution}{\cellcolor{PfCRulloCoulSol}}{}}{}
                   \num{\ListeFacteurA[\fpeval{\RulloTaille*(\RulloTaille-1)+##1}]}
                   }
                   \else
                   \cellcolor{gray!15}\num{\ListeFacteursH[\Toto]}\xintFor* ##1 in{\xintSeq{1}{\RulloTaille}}\do{%
                   \uppercase{&}\itemtomacro\ListeChgt[##2]\Toto%
                                \xintifboolexpr{##1==\ListeTrouee[\fpeval{2*\Toto-1}] || ##1==\ListeTrouee[\fpeval{2*\Toto}]}{\ifboolKV[Rullo]{Solution}{\cellcolor{PfCRulloCoulSol}}{}}{}\num{\ListeFacteurA[\fpeval{\RulloTaille*(\Toto-1)+##1}]}
                                }
                                \fi
      \\
      \hhline{*{\fpeval{\RulloTaille+1}}{-}}
      }
    \end{tabular}%
  \fi%
  \reademptyitems%
}%