%%% % Mulart %%% \setKVdefault[TabMul]{Multiple=2,Cibles=false,Largeur=20pt,Couleurs=false,Graines=false,Operations=false,Enonce=false,SchemaEnonce=false} \defKV[TabMul]{Couleur=\setKV[TabMul]{Couleurs}} \defKV[TabMul]{Graine=\setKV[TabMul]{Graines}\PfCGraineAlea{#1}} \defKV[TabMul]{Cible=\setKV[TabMul]{Cibles}}% \newtoks\tokstabmul \newtoks\tokstabmulpdts \newtoks\tokstabmulnonpdts \newtoks\tokstabmulpdtscible \def\UpdatetoksTabMul#1\nil{\addtotok\tokstabmul{"#1",}}% \def\UpdatetoksTabMulPdts#1\nil{\addtotok\tokstabmulpdts{"#1",}}% \def\UpdatetoksTabMulNonPdts#1\nil{\addtotok\tokstabmulnonpdts{"#1",}}% \def\UpdatetoksTabMulPdtsCible#1\nil{\addtotok\tokstabmulpdtscible{"#1",}}% \NewDocumentCommand\TableauMultiplicatif{om}{% \useKVdefault[TabMul]% \setKV[TabMul]{#1}% \setsepchar{,}\ignoreemptyitems% \readlist*\PfCListeTabMul{#2}% \reademptyitems% \StrLen{\PfCListeTabMul[1]}[\TailleTabMul]% \tokstabmul{}% \foreachitem\compteur\in\PfCListeTabMul{\expandafter\UpdatetoksTabMul\compteur\nil}% \savecomparemode% \comparestrict% \ifboolKV[TabMul]{Cibles}{% \tokstabmulpdtscible{}% \xdef\PfCCompteurX{0}% \xdef\PfCCompteurO{0}% \xintFor* ##1 in {\xintSeq{1}{\PfCListeTabMullen}}\do{% \xintFor* ##2 in {\xintSeq{1}{\TailleTabMul}}\do{% \StrChar{\PfCListeTabMul[##1]}{##2}[\PfCLettre]% \IfStrEq{\PfCLettre}{x}{% \xdef\PfCCompteurX{\fpeval{\PfCCompteurX+1}}% }{\IfStrEq{\PfCLettre}{o}{% \xdef\PfCCompteurO{\fpeval{\PfCCompteurO+1}}% }{}% }% }% }% \xdef\PfCFooRetiensCible{\useKV[TabMul]{Cible}}% \readlist*\PfCListeDesNombresCibles{\PfCFooRetiensCible}% \xintFor* ##2 in{\xintSeq{1}{\PfCListeDesNombresCibleslen}}\do{% \PfCListeDiviseursInfDix{\PfCListeDesNombresCibles[##2]}% \setsepchar{,}\ignoreemptyitems% \readlist*\PfCTabMulDiviseursCible{\PfCListeDiviseursInfDixRetour}% \xdef\PfCFooListePdtCible{$1\times\num{\PfCListeDesNombresCibles[##2]}$,$\num{\PfCListeDesNombresCibles[##2]}\times1$}% \xintFor* ##1 in {\xintSeq{1}{\PfCNbDiviseurs}}\do{% \xdef\PfCFooListePdtCible{\PfCFooListePdtCible,$\num{\PfCTabMulDiviseursCible[##1]}\times\num{\fpeval{\PfCListeDesNombresCibles[##2]/\PfCTabMulDiviseursCible[##1]}}$,$\num{\fpeval{\PfCListeDesNombresCibles[##2]/\PfCTabMulDiviseursCible[##1]}}\times\num{\PfCTabMulDiviseursCible[##1]}$}% }% }% \ignoreemptyitems% \readlist*\PfCListeProduitsCible{\PfCFooListePdtCible}% \foreachitem\compteur\in\PfCListeProduitsCible{\expandafter\UpdatetoksTabMulPdtsCible\compteur\nil}% \BuildTabMulCible{\the\tokstabmul}{\the\tokstabmulpdtscible}{\PfCFooRetiensCible}% }{% \ifboolKV[TabMul]{Operations}{% \xdef\PfCTabMulListePdts{4,6,8,9,10,12,14,15,16,18,20,21,24,25,27,28,30,32,35,36,40,42,45,48,49,50,54,56,60,63,64,70,72,80,81,90,100}%37 \xdef\PfCTabMulListeNonPdts{2,3,5,7,11,13,17,19,22,23,26,29,31,33,34,37,38,39,41,43,44,46,47,51,52,53,55,57,58,59,61,62,65,66,67,68,69,71,73,74,75,76,77,78,79,82,83,84,85,86,87,88,89,91,92,93,94,95,96,97,98,99}%62 \xdef\PfCCompteurX{0} \xdef\PfCCompteurO{0} \xintFor* ##1 in {\xintSeq{1}{\PfCListeTabMullen}}\do{% \xintFor* ##2 in {\xintSeq{1}{\TailleTabMul}}\do{% \StrChar{\PfCListeTabMul[##1]}{##2}[\PfCLettre]% \IfStrEq{\PfCLettre}{x}{% \xdef\PfCCompteurX{\fpeval{\PfCCompteurX+1}}% }{\IfStrEq{\PfCLettre}{o}{% \xdef\PfCCompteurO{\fpeval{\PfCCompteurO+1}}% }{}% }% }% }% \xdef\NombreRepetX{\fpeval{ceil(\PfCCompteurX/37)}}% \xdef\NombreRepetO{\fpeval{ceil(\PfCCompteurO/62)}}% \xdef\PfCTabMulListeFinalePdts{} \xdef\PfCTabMulListeFinaleNonPdts{} \xintFor* ##1 in {\xintSeq{1}{\NombreRepetX}}\do{% \xdef\PfCTabMulListeFinalePdts{\PfCTabMulListeFinalePdts,\PfCTabMulListePdts} }% \xintFor* ##1 in {\xintSeq{1}{\NombreRepetO}}\do{% \xdef\PfCTabMulListeFinaleNonPdts{\PfCTabMulListeFinaleNonPdts,\PfCTabMulListeNonPdts} }% \MelangeListe{\PfCTabMulListeFinalePdts}{\PfCCompteurX} \ignoreemptyitems \readlist*\PfCListeProduits{\faa} \MelangeListe{\PfCTabMulListeFinaleNonPdts}{\PfCCompteurO} \ignoreemptyitems \readlist*\PfCListeNonProduits{\faa} \ifboolKV[TabMul]{Enonce}{% \begin{enumerate} \xintFor* ##1 in {\xintSeq{1}{\PfCCompteurX}}\do{% \PfCListeDiviseursInfDix{\PfCListeProduits[##1]}% \ifnum\PfCNbDiviseurs>1\relax \MelangeListe{\PfCListeDiviseursInfDixRetour}{1}% \else \xdef\faa{\PfCListeDiviseursInfDixRetour} \fi \ignoreemptyitems \readlist*\PfCListeDiviseurChoisi{\faa}% \item $\PfCListeDiviseurChoisi[1]\times\fpeval{\PfCListeProduits[##1]/\PfCListeDiviseurChoisi[1]}=$ } \end{enumerate} }{} \ifboolKV[TabMul]{SchemaEnonce}{% \tokstabmulpdts{} \tokstabmulnonpdts{} \xdef\PfCFoo{\PfCListeProduits[1]} \xintFor* ##3 in {\xintSeq{2}{\PfCCompteurX}}\do{% \xdef\PfCFoo{\PfCFoo,\PfCListeProduits[##3]}% }% \MelangeListe{\PfCFoo}{\PfCCompteurX}% \ignoreemptyitems \readlist*\PfCListeProduits{\faa}% \foreachitem\compteur\in\PfCListeProduits{\expandafter\UpdatetoksTabMulPdts\compteur\nil}% \foreachitem\compteur\in\PfCListeNonProduits{\expandafter\UpdatetoksTabMulNonPdts\compteur\nil}% \BuildTabMulEnonce{\the\tokstabmul}{\the\tokstabmulpdts}{\the\tokstabmulnonpdts} }{}%% }{% \BuildTabMul{\the\tokstabmul}% } } \restorecomparemode% \reademptyitems% }% \NewDocumentCommand\PfCListeDiviseursInfDix{m}{% \ifnum#1<10\relax \xdef\PfCLimiteDiv{#1} \else \xdef\PfCLimiteDiv{10} \fi \xdef\PfCListeDiviseursInfDixRetour{} \xdef\PfCNbDiviseurs{} \xintFor* ##2 in {\xintSeq{2}{\PfCLimiteDiv}}\do{% \modulo{#1}{##2}\relax \ifnum\remainder=0\relax \xdef\PfCListeDiviseursInfDixRetour{\PfCListeDiviseursInfDixRetour ##2,}% \xdef\PfCNbDiviseurs{\fpeval{\PfCNbDiviseurs+1}}% \fi }% }% \def\TabMulCibleCode{% NbCasesLarg=\TailleTabMul; Largeur=\useKV[TabMul]{Largeur}; color CoulFond; boolean Colore,Stop,Graines; Colore=\useKV[TabMul]{Couleurs}; if Colore: CoulFond=\useKV[TabMul]{Couleur}; fi; Graines=\useKV[TabMul]{Graines}; if Graines: randomseed:=\useKV[TabMul]{Graine}; fi; vardef NombresCibles(text t)= nbc=0; for p_=t: nbc:=nbc+1; Cible[nbc]=p_; endfor; enddef; % vardef LectureDesProduits(text t)= string Sproduits[]; nbp=0; for p_=t: nbp:=nbp+1; Sproduits[nbp]=p_; endfor; enddef; % vardef Remplissage(text t)= pair M[][]; n=0; for p_=t: for k=0 upto NbCasesLarg-1: l:=n mod NbCasesLarg; h:=n div NbCasesLarg; M[l][h]=Largeur*(l,-h); if (substring(k,k+1) of p_)="x": if Colore: fill ((unitsquare scaled Largeur) shifted M[l][h]) withcolor CoulFond; fi; label(TEX(Sproduits[ceiling(uniformdeviate(nbp))]),M[l][h] shifted (Largeur*(0.5,0.5))); elseif (substring(k,k+1) of p_)="X": fill ((unitsquare scaled Largeur) shifted M[l][h]); else: Stop:=false; forever: basea:=ceiling(1+uniformdeviate(9)); baseb:=ceiling(1+uniformdeviate(9)); basec:=0; for r=1 upto nbc: if (basea*baseb)<>Cible[r]: basec:=basec+1; fi; endfor; if basec=nbc: Stop:=true; fi; exitif Stop; endfor; label(TEX("$\num{"&decimal(basea)&"}\times\num{"&decimal(baseb)&"}$"),M[l][h] shifted (Largeur*(0.5,0.5))); fi; trace (unitsquare scaled Largeur) shifted M[l][h]; n:=n+1; endfor; endfor; enddef; % vardef RemplissagePDF(text t)= pair M[][]; n=0; for p_=t: for k=0 upto NbCasesLarg-1: l:=n mod NbCasesLarg; h:=n div NbCasesLarg; M[l][h]=Largeur*(l,-h); if (substring(k,k+1) of p_)="x": if Colore: fill ((unitsquare scaled Largeur) shifted M[l][h]) withcolor CoulFond; fi; label(LATEX(Sproduits[ceiling(uniformdeviate(nbp))]),M[l][h] shifted (Largeur*(0.5,0.5))); elseif (substring(k,k+1) of p_)="X": fill ((unitsquare scaled Largeur) shifted M[l][h]); else: Stop:=false; forever: basea:=ceiling(1+uniformdeviate(9)); baseb:=ceiling(1+uniformdeviate(9)); basec:=0; for r=1 upto nbc: if (basea*baseb)<>Cible[r]: basec:=basec+1; fi; endfor; if basec=nbc: Stop:=true; fi; exitif Stop; endfor; label(LATEX("$\num{"&decimal(basea)&"}\times\num{"&decimal(baseb)&"}$"),M[l][h] shifted (Largeur*(0.5,0.5))); fi; trace (unitsquare scaled Largeur) shifted M[l][h]; n:=n+1; endfor; endfor; enddef; }% \NewDocumentCommand\BuildTabMulCible{mmm}{% \ifluatex \mplibforcehmode \mplibnumbersystem{double} \begin{mplibcode} \TabMulCibleCode NombresCibles(#3); LectureDesProduits(#2); Remplissage(#1); \end{mplibcode} \mplibnumbersystem{scaled} \else \begin{mpost}[mpsettings={\TabMulCibleCode}] NombresCibles(#3); LectureDesProduits(#2); RemplissagePDF(#1); \end{mpost} \fi } \def\TabMulCode{% NbCasesLarg=\TailleTabMul; Multiple=\useKV[TabMul]{Multiple}; Largeur=\useKV[TabMul]{Largeur}; color CoulFond; boolean Colore,Stop,Graines; Colore=\useKV[TabMul]{Couleurs}; if Colore: CoulFond=\useKV[TabMul]{Couleur}; fi; Graines=\useKV[TabMul]{Graines}; if Graines: randomseed:=\useKV[TabMul]{Graine}; fi; vardef Remplissage(text t)= pair M[][]; n=0; for p_=t: for k=0 upto NbCasesLarg-1: l:=n mod NbCasesLarg; h:=n div NbCasesLarg; M[l][h]=Largeur*(l,-h); if (substring(k,k+1) of p_)="x": if Colore: fill ((unitsquare scaled Largeur) shifted M[l][h]) withcolor CoulFond; fi; label(TEX(decimal(Multiple*ceiling(uniformdeviate(9)+1))),M[l][h] shifted (Largeur*(0.5,0.5))); elseif (substring(k,k+1) of p_)="X": fill ((unitsquare scaled Largeur) shifted M[l][h]); else: Stop:=false; forever: base:=ceiling((1+uniformdeviate(9))*(1+uniformdeviate(9))); if (base mod Multiple)>0: Stop:=true; fi; exitif Stop; endfor; label(TEX(decimal(base)),M[l][h] shifted (Largeur*(0.5,0.5))); fi; trace (unitsquare scaled Largeur) shifted M[l][h]; n:=n+1; endfor; endfor; enddef; % vardef RemplissagePDF(text t)= pair M[][]; n=0; for p_=t: for k=0 upto NbCasesLarg-1: l:=n mod NbCasesLarg; h:=n div NbCasesLarg; M[l][h]=Largeur*(l,-h); if (substring(k,k+1) of p_)="x": if Colore: fill ((unitsquare scaled Largeur) shifted M[l][h]) withcolor CoulFond; fi; label(LATEX(decimal(Multiple*ceiling(uniformdeviate(9)+1))),M[l][h] shifted (Largeur*(0.5,0.5))); elseif (substring(k,k+1) of p_)="X": fill ((unitsquare scaled Largeur) shifted M[l][h]); else: Stop:=false; forever: base:=ceiling((1+uniformdeviate(9))*(1+uniformdeviate(9))); if (base mod Multiple)>0: Stop:=true; fi; exitif Stop; endfor; label(LATEX(decimal(base)),M[l][h] shifted (Largeur*(0.5,0.5))); fi; trace (unitsquare scaled Largeur) shifted M[l][h]; n:=n+1; endfor; endfor; enddef; } \NewDocumentCommand\BuildTabMul{m}{% \ifluatex \mplibforcehmode \mplibnumbersystem{double} \begin{mplibcode} \TabMulCode Remplissage(#1); \end{mplibcode} \mplibnumbersystem{scaled} \else \begin{mpost}[mpsettings={\TabMulCode}] Remplissage(#1); \end{mpost} \fi } \def\TabMulEnonceCode{ NbCasesLarg=\TailleTabMul; Multiple=\useKV[TabMul]{Multiple}; Largeur=\useKV[TabMul]{Largeur}; color CoulFond; boolean Colore,Stop;%,Graines; Colore=\useKV[TabMul]{Couleurs}; if Colore: CoulFond=\useKV[TabMul]{Couleur}; fi; vardef Remplissage(text t)(text listepdt)(text listenonpdt)= string pdt[],nonpdt[]; n:=0; for p_=listepdt: pdt[n]=p_; n:=n+1; endfor; n:=0; for p_=listenonpdt: nonpdt[n]=p_; n:=n+1; endfor; pair M[][]; n:=0; nx=0; no=0; for p_=t: for k=0 upto NbCasesLarg-1: l:=n mod NbCasesLarg; h:=n div NbCasesLarg; M[l][h]=Largeur*(l,-h); if (substring(k,k+1) of p_)="x": if Colore: fill ((unitsquare scaled Largeur) shifted M[l][h]) withcolor CoulFond; fi; label(TEX(pdt[nx]),M[l][h] shifted (Largeur*(0.5,0.5))); nx:=nx+1; elseif (substring(k,k+1) of p_)="X": fill ((unitsquare scaled Largeur) shifted M[l][h]); else: label(TEX(nonpdt[no]),M[l][h] shifted (Largeur*(0.5,0.5))); no:=no+1; fi; trace (unitsquare scaled Largeur) shifted M[l][h]; n:=n+1; endfor; endfor; enddef; vardef RemplissagePDF(text t)(text listepdt)(text listenonpdt)= string pdt[],nonpdt[]; n:=0; for p_=listepdt: pdt[n]=p_; n:=n+1; endfor; n:=0; for p_=listenonpdt: nonpdt[n]=p_; n:=n+1; endfor; pair M[][]; n:=0; nx=0; no=0; for p_=t: for k=0 upto NbCasesLarg-1: l:=n mod NbCasesLarg; h:=n div NbCasesLarg; M[l][h]=Largeur*(l,-h); if (substring(k,k+1) of p_)="x": if Colore: fill ((unitsquare scaled Largeur) shifted M[l][h]) withcolor CoulFond; fi; label(TEX(pdt[nx]),M[l][h] shifted (Largeur*(0.5,0.5))); nx:=nx+1; elseif (substring(k,k+1) of p_)="X": fill ((unitsquare scaled Largeur) shifted M[l][h]); else: label(TEX(nonpdt[no]),M[l][h] shifted (Largeur*(0.5,0.5))); no:=no+1; fi; trace (unitsquare scaled Largeur) shifted M[l][h]; n:=n+1; endfor; endfor; enddef; } \NewDocumentCommand\BuildTabMulEnonce{mmm}{% \ifluatex \mplibforcehmode \mplibnumbersystem{double} \begin{mplibcode} \TabMulEnonceCode Remplissage(#1)(#2)(#3); \end{mplibcode} \mplibnumbersystem{scaled} \else \begin{mpost}[mpsettings={\TabMulEnonceCode}] RemplissagePDF(#1)(#2)(#3); \end{mpost} \fi }