%%% % Pyramide de calculs %%% \def\filedatePyraCalc{2024/08/04}% \def\fileversionPyraCalc{0.1}% \message{-- \filedatePyraCalc\space v\fileversionPyraCalc}% % \newcommand\DessinePyramideNombreMul[1]{% \ifluatex \mplibforcehmode \begin{mplibcode} pair A[],B[],O; cote:=\useKV[ClesPyramide]{Cote}; boolean Aide,Produit,Solution,Vide; Aide:=\useKV[ClesPyramide]{Aide}; Vide:=\useKV[ClesPyramide]{Vide}; Produit:=\useKV[ClesPyramide]{Produit}; Solution:=\useKV[ClesPyramide]{Solution}; A1=u*(1,1); A2-A1=cote*(1,0); A3=rotation(A2,A1,60); A4=A1; B1=iso(A1,A2); B2=iso(A2,A3); B3=iso(A3,A1); O=iso(A1,A2,A3); path BoiteRec; BoiteRec=((-0.4,-0.5)--(0.4,-0.5){dir0}..{dir90}(0.5,-0.4)--(0.5,0.4){dir90}..{dir180}(0.4,0.5)--(-0.4,0.5){dir180}..{dir-90}(-0.5,0.4)--(-0.5,-0.4){dir-90}..cycle) scaled 1u; % On trace et on affiche...éventuellement :) trace polygone(A1,A2,A3); for k=1 upto 3: trace segment(O,B[k]) dashed withdots scaled 0.25; draw BoiteRec shifted (1.75[O,B[k]]-center BoiteRec) dashed evenly scaled 0.5; endfor; if Vide: else: % On récupère les valeurs pour déterminer les produits k=0; for p_=#1: k:=k+1; Facteur[k]=p_; endfor; Produit[1]=Facteur[1] * Facteur[2]; Produit[2]=Facteur[2] * Facteur[3]; Produit[3]=Facteur[3] * Facteur[1]; for k=1 upto 3: if Produit or Solution: label(TEX("\num{"&decimal(Produit[k])&"}"),(1.75[O,B[k]]-center BoiteRec)); fi; if Produit: else: label(TEX("\num{"&decimal(Facteur[k])&"}"),(0.5[O,A[k]]-center BoiteRec)); fi; endfor; fi; if Aide: for k=1 upto 3: drawarrow (0.5[O,A[k]]--1.75[O,B[k]]) cutbefore segment(A[k],A[k+1]) cutafter BoiteRec shifted (1.75[O,B[k]]-center BoiteRec) dashed evenly scaled 0.5; drawarrow (0.5[O,A[k+1]]--1.75[O,B[k]]) cutbefore segment(A[k],A[k+1]) cutafter BoiteRec shifted (1.75[O,B[k]]-center BoiteRec) dashed evenly scaled 0.5; endfor; fi; \end{mplibcode} \else \begin{mpost}[mpsettings={cote:=\useKV[ClesPyramide]{Cote}; boolean Aide,Produit,Solution,Vide; Aide:=\useKV[ClesPyramide]{Aide}; Vide:=\useKV[ClesPyramide]{Vide}; Produit:=\useKV[ClesPyramide]{Produit}; Solution:=\useKV[ClesPyramide]{Solution};}] pair A[],B[],O; A1=u*(1,1); A2-A1=cote*(1,0); A3=rotation(A2,A1,60); A4=A1; B1=iso(A1,A2); B2=iso(A2,A3); B3=iso(A3,A1); O=iso(A1,A2,A3); path BoiteRec; BoiteRec=((-0.4,-0.5)--(0.4,-0.5){dir0}..{dir90}(0.5,-0.4)--(0.5,0.4){dir90}..{dir180}(0.4,0.5)--(-0.4,0.5){dir180}..{dir-90}(-0.5,0.4)--(-0.5,-0.4){dir-90}..cycle) scaled 1u; % On trace et on affiche...éventuellement :) trace polygone(A1,A2,A3); for k=1 upto 3: trace segment(O,B[k]) dashed withdots scaled 0.25; draw BoiteRec shifted (1.75[O,B[k]]-center BoiteRec) dashed evenly scaled 0.5; endfor; if Vide: else: % On récupère les valeurs pour déterminer les produits k=0; for p_=#1: k:=k+1; Facteur[k]=p_; endfor; Produit[1]=Facteur[1] * Facteur[2]; Produit[2]=Facteur[2] * Facteur[3]; Produit[3]=Facteur[3] * Facteur[1]; for k=1 upto 3: if Produit or Solution: label(LATEX("\num{"&decimal(Produit[k])&"}"),(1.75[O,B[k]]-center BoiteRec)); fi; if Produit: else: label(LATEX("\num{"&decimal(Facteur[k])&"}"),(0.5[O,A[k]]-center BoiteRec)); fi; endfor; fi; if Aide: for k=1 upto 3: drawarrow (0.5[O,A[k]]--1.75[O,B[k]]) cutbefore segment(A[k],A[k+1]) cutafter BoiteRec shifted (1.75[O,B[k]]-center BoiteRec) dashed evenly scaled 0.5; drawarrow (0.5[O,A[k+1]]--1.75[O,B[k]]) cutbefore segment(A[k],A[k+1]) cutafter BoiteRec shifted (1.75[O,B[k]]-center BoiteRec) dashed evenly scaled 0.5; endfor; fi; \end{mpost} \fi } \newcommand\DessinePyramideNombre[1]{% \ifluatex \mplibforcehmode \begin{mplibcode} pair A[][],B[]; path Case[]; color CaseCouleur; nbetages:=\useKV[ClesPyramide]{Etages}; largeur:=\useKV[ClesPyramide]{Largeur}; hauteur:=\useKV[ClesPyramide]{Hauteur}; CaseCouleur:=\useKV[ClesPyramide]{Couleur}; boolean Double; Double=\useKV[ClesPyramide]{Double}; Nbeb:=0;%Pour associer les textes avec les points. Plus facile :) if Double: for k=nbetages downto 1: for l=0 upto (k-1): Nbeb:=Nbeb+1; A[k][l]=(0,0)+(nbetages-k)*(largeur/2,0)+(l*largeur,(nbetages-k)*hauteur); B[Nbeb]=A[k][l]; Case[Nbeb]=((unitsquare xscaled largeur) yscaled hauteur) shifted (A[k][l]-0.5*(largeur,hauteur)); trace Case[Nbeb]; endfor; endfor; for k=nbetages-1 downto 1: for l=0 upto (k-1): Nbeb:=Nbeb+1; A[-k][l]=(0,0)+(nbetages-k)*(largeur/2,0)+(l*largeur,-(nbetages-k)*hauteur); B[Nbeb]=A[-k][l]; Case[Nbeb]=((unitsquare xscaled largeur) yscaled hauteur) shifted (A[-k][l]-0.5*(largeur,hauteur)); trace Case[Nbeb]; endfor; endfor; else: if \useKV[ClesPyramide]{Inverse}: change:=-1; else: change=1; fi; for k=nbetages downto 1: for l=0 upto (k-1): Nbeb:=Nbeb+1; A[k][l]=(0,0)+(nbetages-k)*(largeur/2,0)+(l*largeur,change*(nbetages-k)*hauteur); B[Nbeb]=A[k][l]; Case[Nbeb]=((unitsquare xscaled largeur) yscaled hauteur) shifted (A[k][l]-0.5*(largeur,hauteur)); trace Case[Nbeb]; endfor; endfor; fi; if \useKV[ClesPyramide]{Vide}: else: Nbeb:=0; for p_=#1: Nbeb:=Nbeb+1; if (substring(0,1) of p_)="*": fill Case[Nbeb] withcolor CaseCouleur; trace Case[Nbeb]; label(TEX(substring(1,length p_) of p_),B[Nbeb]); elseif (substring(0,1) of p_)="!": drawoptions(withcolor \useKV[ClesPyramide]{CouleurNombre}); label(TEX(substring(1,length p_) of p_),B[Nbeb]); drawoptions(); else: label(TEX(p_),B[Nbeb]); fi; endfor; fi; \end{mplibcode} \else \begin{mpost}[mpsettings={nbetages:=\useKV[ClesPyramide]{Etages};largeur:=\useKV[ClesPyramide]{Largeur};hauteur:=\useKV[ClesPyramide]{Hauteur};boolean Vide,Inverse,Double;Vide=\useKV[ClesPyramide]{Vide};Inverse=\useKV[ClesPyramide]{Inverse};Double=\useKV[ClesPyramide]{Double};color CaseCouleur;CouleurNombre; CaseCouleur:=\useKV[ClesPyramide]{Couleur};CouleurNombre=\useKV[ClesPyramide]{CouleurNombre};}] pair A[][],B[]; path Case[]; Nbeb:=0; if Double: for k=nbetages downto 1: for l=0 upto (k-1): Nbeb:=Nbeb+1; A[k][l]=(0,0)+(nbetages-k)*(largeur/2,0)+(l*largeur,(nbetages-k)*hauteur); B[Nbeb]=A[k][l]; Case[Nbeb]=((unitsquare xscaled largeur) yscaled hauteur) shifted (A[k][l]-0.5*(largeur,hauteur)); trace Case[Nbeb]; endfor; endfor; for k=nbetages-1 downto 1: for l=0 upto (k-1): Nbeb:=Nbeb+1; A[-k][l]=(0,0)+(nbetages-k)*(largeur/2,0)+(l*largeur,-(nbetages-k)*hauteur); B[Nbeb]=A[-k][l]; Case[Nbeb]=((unitsquare xscaled largeur) yscaled hauteur) shifted (A[-k][l]-0.5*(largeur,hauteur)); trace Case[Nbeb]; endfor; endfor; else: if Inverse: change:=-1; else: change=1; fi; for k=nbetages downto 1: for l=0 upto (k-1): Nbeb:=Nbeb+1; A[k][l]=(0,0)+(nbetages-k)*(largeur/2,0)+(l*largeur,change*(nbetages-k)*hauteur); B[Nbeb]=A[k][l]; Case[Nbeb]=((unitsquare xscaled largeur) yscaled hauteur) shifted (A[k][l]-0.5*(largeur,hauteur)); trace Case[Nbeb]; endfor; endfor; fi; if Vide: else: Nbeb:=0; for p_=#1: Nbeb:=Nbeb+1; if (substring(0,1) of p_)="*": fill Case[Nbeb] withcolor CaseCouleur; trace Case[Nbeb]; label(LATEX(substring(1,length p_) of p_),B[Nbeb]); elseif (substring(0,1) of p_)="!": drawoptions(withcolor CouleurNombre); label(LATEX(substring(1,length p_) of p_),B[Nbeb]); drawoptions(); else: label(LATEX(p_),B[Nbeb]); fi; endfor; fi; \end{mpost} \fi }% \setKVdefault[ClesPyramide]{ToutesOperations=false,Etages=5,Largeur=2cm,Hauteur=1cm,Vide=false,Inverse=false,Double=false,Couleur=Crimson,Multiplication=false,CouleurNombre=blue,Produit=false,Solution=false,Aide=false,Cote=4cm}% \newtoks\toklistecaseP% \def\UpdatetoksPyramide#1\nil{\addtotok\toklistecaseP{"#1",}}% \def\UpdatetoksPyramideMul#1\nil{\addtotok\toklistecaseP{#1,}}% \NewDocumentCommand\PyramideNombre{o m}{% \useKVdefault[ClesPyramide]% \setKV[ClesPyramide]{#1}% \ifboolKV[ClesPyramide]{ToutesOperations}{% \PyramideOp[#1]{#2}% }{% \ifboolKV[ClesPyramide]{Multiplication}{% \ifx\bla#2\bla% \setKV[ClesPyramide]{Vide=true}% \DessinePyramideNombreMul{\the\toklistecaseP}% \else \setsepchar{,}% \readlist*\ListePyramide{#2}% \DessinePyramideNombreMul{\ListePyramide[1],\ListePyramide[2],\ListePyramide[3]}% \fi }{% \ifx\bla#2\bla% \setKV[ClesPyramide]{Vide=true}% \DessinePyramideNombre{\the\toklistecaseP}% \else% \setsepchar{,}% \readlist*\ListePyramide{#2}% \ifboolKV[ClesPyramide]{Double}{% \def\CalculNombreComposants{\fpeval{\useKV[ClesPyramide]{Etages}*\useKV[ClesPyramide]{Etages}}}% }{% \def\CalculNombreComposants{\fpeval{\useKV[ClesPyramide]{Etages}*(\useKV[ClesPyramide]{Etages}+1)/2}}% }% \xintifboolexpr{\ListePyramidelen==\CalculNombreComposants}{% \toklistecaseP{}% \foreachitem\compteur\in\ListePyramide{\expandafter\UpdatetoksPyramide\compteur\nil}% \DessinePyramideNombre{\the\toklistecaseP}% }{Le nombre d'éléments dans la liste des propositions n'est pas compatible avec le nombre d'étages choisi.}% \fi% }% }% }% \setKVdefault[PyramideOp]{Rayon=5mm,Graines=false,Etages=5,Solution=false,Relatifs=false,Case=-1} \defKV[PyramideOp]{Graine=\setKV[PyramideOp]{Graines}} \defKV[PyramideOp]{CouleurSolution=\setKV[PyramideOp]{Solution}} \NewDocumentCommand\PyramideOp{om}{% \useKVdefault[PyramideOp]% \setKV[PyramideOp]{#1}% \ifboolKV[PyramideOp]{Relatifs}{% \BuildPyramideOpRelatifs{#2}% }{% \BuildPyramideOp{#2}% }% }% \NewDocumentCommand\BuildPyramideOp{m}{% \ifluatex \mplibforcehmode \mplibnumbersystem{double} \begin{mplibcode} Etages=\useKV[PyramideOp]{Etages}; Rayon=\useKV[PyramideOp]{Rayon}; Case=\useKV[PyramideOp]{Case}; boolean Graines,Solution,Allume[][]; Graines=\useKV[PyramideOp]{Graines}; if Graines: randomseed:=\useKV[PyramideOp]{Graine}; fi; Solution=\useKV[PyramideOp]{Solution}; if Solution: color CouleurSolution; CouleurSolution=\useKV[PyramideOp]{CouleurSolution}; fi; vardef ChoixOperation(expr Nba,Nbb)= if (Nba200: ChoixOp:=ceiling(uniformdeviate(1)); else: ChoixOp:=ceiling(uniformdeviate(2)); fi; else: if (Nba mod Nbb)<>0: if Nba*Nbb>200: ChoixAlea:=uniformdeviate(1); if ChoixAlea<0.5: ChoixOp:=1; else: ChoixOp:=3; fi; else: ChoixOp:=ceiling(uniformdeviate(3)); fi; else: if Nba*Nbb>200: ChoixAlea:=uniformdeviate(1); if ChoixAlea<0.5: ChoixOp:=1; else: ChoixOp:=ceiling(2+uniformdeviate(2)); fi; else: ChoixOp:=ceiling(uniformdeviate(4)); fi; fi; fi; enddef; numeric Nb[][],ChoixOp[][]; pair M[][],N[][]; for k=0 upto Etages-1: for l=0 upto Etages-1-k: M[k][l]=Rayon*(1,1)+2*Rayon*(l,k)+k*2*Rayon*(0.5,-1+cosd(30)); Allume[k][l]=false; endfor; endfor; for k=0 upto Etages-2: for l=0 upto Etages-2-k: N[k][l]=Rayon*(1,1)+(Rayon,0)+2*Rayon*(l,k)+k*2*Rayon*(0.5,-1+cosd(30)); endfor; endfor; n:=0; for p_=#1: Nb[0][n]=p_; if n=Case: if n200: ChoixOp:=ceiling(uniformdeviate(1)); else: ChoixOp:=ceiling(uniformdeviate(2)); fi; elseif (Nba+Nbb=0): if abs(Nba*Nbb)>200: ChoixOp:=3; else: ChoixAlea:=uniformdeviate(1); if ChoixAlea<0.5: ChoixOp:=2; else: ChoixOp:=3; fi; fi; else: if (abs(Nba) mod abs(Nbb))<>0: if abs(Nba*Nbb)>200: ChoixAlea:=uniformdeviate(1); if ChoixAlea<0.5: ChoixOp:=1; else: ChoixOp:=3; fi; else: ChoixOp:=ceiling(uniformdeviate(3)); fi; else: if abs(Nba*Nbb)>200: ChoixAlea:=uniformdeviate(1); if ChoixAlea<0.5: ChoixOp:=1; else: ChoixOp:=ceiling(2+uniformdeviate(2)); fi; else: ChoixOp:=ceiling(uniformdeviate(4)); fi; fi; fi; enddef; %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% numeric Nb[][],ChoixOp[][]; pair M[][],N[][]; for k=0 upto Etages-1: for l=0 upto Etages-1-k: M[k][l]=Rayon*(1,1)+2*Rayon*(l,k)+k*2*Rayon*(0.5,-1+cosd(30)); Allume[k][l]=false; endfor; endfor; for k=0 upto Etages-2: for l=0 upto Etages-2-k: N[k][l]=Rayon*(1,1)+(Rayon,0)+2*Rayon*(l,k)+k*2*Rayon*(0.5,-1+cosd(30)); endfor; endfor; n:=0; for p_=#1: Nb[0][n]=p_; if n=Case: if n