Simplificando raíces cuadradas

Simplificando raíces cuadradas

Quiero crear un comando que, para un número entero dado n, escriba una raíz cuadrada simplificada de n. Por ejemplo, la salida de

\rsqrt{4}
\rsqrt{8}
\rsqrt{18}
\rsqrt{7}

sería el mismo que el de

2
2\sqrt{2}
3\sqrt{2}
\sqrt{7}

¿Dónde \rsqrt{}está el comando en cuestión?

Sé que el algoritmo se parecería a esto

i = square root of n rounded down 

while i > 0:
    if n is divisible by i²:
        simplification is i\sqrt{n/i²}
        break loop
    i = i - 1

%the simpification will always be found
%since every n is divisible by 1

donde nes el número entero dado, ies el número anterior \sqrty n/i²es el argumento de \sqrt{...}.

¿Pero no tengo idea de cómo implementar esto en látex?

EDITAR: Se aclaró que el número de entrada siempre será un número entero.

Respuesta1

El algoritmo de la pregunta es muy ineficiente: excepto, por supuesto, si el número entero original es un cuadrado perfecto.

Esta respuesta (en orden cronológico):

  1. un enfoque con macros que imita el algoritmo de factorización más simple,

  2. un enfoque ampliable utilizando el algoritmo como en OP.actualizarMuy vergonzosamente, el autor no había entendido el algoritmo del OP y después de haber encontrado una simplificación Icomo I^2dividida N, fue recursivamente sin N<-N/I^2entender que el algoritmo podía detenerse allí. (como excusa, había implementado primero el método "de abajo hacia arriba", que necesita recursividad, al contrario del método "de arriba hacia abajo" (menos eficiente)). La respuesta se actualiza así, disculpas a todos los generosos y confiados primeros votantes.

    Estoy actualizando nuevamente (lo siento) porque ahora leí más xintexpr.stydocumentación de y cambié por eficiencia de i=sqrt(N)..1a i=-sqrt(N)++(no hay ninguna --disponible, de ahí un truco con signo menos). El primero genera de antemano la lista completa de floor(\sqrt{N})números ( sqrtsignifica raíz cuadrada truncada \xintiiexpr), el segundo es un iterador que no genera cosas de antemano. Además, la sintaxis anterior solo puede generar 5000valores aproximados ( sqrt(N)..[-1]..1no tendría tal limitación, pero aún así generaría todo de antemano).

  3. una implementación ampliable de un algoritmo más rápido (tipo de factorización de escuela secundaria) como en el enfoque 1.

Para ser honesto, 2., 3. e incluso 1. probablemente estarían mejor escritos en su totalidad usando \numexprcomo pretensión de manejar números más grandes que 2^31lo que es un poco exagerado, se necesita tiempo con un número primo de 10 dígitos para hacer decenas de miles de divisiones para concluir que no tenía cuadrados... La implementación 2. tiene un límite intrínseco porque 2^62la raíz cuadrada debe ser un número TeX (debido a alguna construcción interna).

En 2. y 3., llevamos un poco más allá de lo razonable las posibilidades de \xintexprsintaxis con secuencias recursivas. La notación es un poco engorrosa. Además xintexpr.sty 1.2ges necesario porque cambió la sintaxis relevante.

  1. finalmente (2017) también agrego el enfoque expandible sin paquete numexpr.

Primer enfoque (cambiamos el algoritmo)

No quiere decir que éste sea un problema fácil. Un poco de búsqueda en Google revela que aparentemente los matemáticos creen actualmente que encontrar el radical libre cuadrado de un número entero puede ser tan difícil como una factorización completa:https://math.stackexchange.com/questions/171568/finding-the-radical-of-an-integeryhttps://math.stackexchange.com/questions/14667/square-free-integers-factorization.

Aquí hay un enfoque (usando macros) que imita la forma más simple de algoritmo de factorización.

El paquete xintexprse utiliza sólo para permitir entradas como 1e7o incluso expresiones. También carga xinttoolscuál se utiliza en la sintaxis.

Aparte de eso, todas las operaciones se realizan con macros disponibles en xint. Como en el ejemplo tratamos casi solo con números, <2^31podríamos emplear una variante en la que todas las operaciones se realizarían utilizando de forma única \numexpr, naturalmente, eso sería bastante más rápido.

El código utiliza \xintiiDivisionel cual calcula simultáneamente el cociente y el resto. Por eso \xintAssignse utiliza para almacenarlos en dos macros \Ay \B. El código examina si \Bdesaparece para detectar la divisibilidad por a Q=P^2.

\documentclass[a4paper]{article}

\usepackage{geometry}

\usepackage{xintexpr}

\makeatletter
\def\Rsqrt@ {%
    \let\Nrad\N
    \def\Nroot {1}% 
% we will always have original N = \Nrad times \Nroot^2
% first we check powers of 2
    \def\P{2}%
    \def\Q{4}% \Q is always square of \P
    \xintloop
% try to divide \Nrad by 4. If possible, multiply \Nroot by 2
        \xintAssign\xintiiDivision{\Nrad}{\Q}\to \A\B
        \xintiiifZero{\B}
           {\let\Nrad\A
            \edef\Nroot{\xintiiMul{\Nroot}{\P}}% 
            \iftrue}
           {\iffalse}%
    \repeat
% try to divide \Nrad by 9=3^2, then by 25=5^2, etc...
% unfortunately we divide by all odd integers, but only odd prime
% integers would be really needed
    \def\P{3}%
    \xintloop
      \edef\Q{\xintiiSqr{\P}}%
      \xintiiifGt{\Q}{\Nrad}
         {\iffalse}%
         {\xintloop
             \xintAssign\xintiiDivision{\Nrad}{\Q}\to \A\B
             \xintiiifZero{\B}
                {\let\Nrad\A
                 \edef\Nroot{\xintiiMul{\P}{\Nroot}}% 
                 \iftrue}
                {\iffalse}%
          \repeat 
          \edef\P{\xintiiAdd{2}{\P}}%
          \iftrue
         }%
    \repeat
% at this stage \N = \Nrad times \Nroot^2
% and \Nrad is square-free.
    \xintiiifOne{\Nroot}{}{\Nroot}%
    \xintiiifOne{\Nrad} {}{\sqrt{\Nrad}}%
}%

\newcommand* \Rsqrt[1]{%
   \begingroup
     \edef\N{\xinttheiexpr #1\relax}%
     \xintiiifSgn \N
        {\pm\edef\N{\xintiiAbs{\N}}\xintiiifOne\N{}{\Rsqrt@}i}
        {0}
        {\xintiiifOne \N{1}{\Rsqrt@}}
   \endgroup
}

\makeatother
\usepackage{multicol}

\begin{document}

\parindent0pt\def\columnseprule{.4pt}%

% testing
% \begin{multicols}{4}
% \xintFor* #1 in {\xintSeq {10000}{10100}}\do
%        {$\sqrt{#1}=\Rsqrt{#1}$\par}
% \end{multicols}

% $\Rsqrt{-10}, \Rsqrt{-1}, \Rsqrt{-16}$

$\Rsqrt {1e6}, \Rsqrt {1e7}, \Rsqrt{1e21}$

\pdfsetrandomseed 123456789

\begin{multicols}{3}
\xintiloop [1+1]
    \edef\Z {\xinttheiiexpr 
             (\pdfuniformdeviate 1000)^2
             *\pdfuniformdeviate 1000\relax }%
    $\sqrt{\Z}=\Rsqrt{\Z}$\par
\ifnum\xintiloopindex<50
\repeat
\end{multicols}
    
\end{document}

ingrese la descripción de la imagen aquí


Segundo enfoque (mismo algoritmo que en OP, implementación ampliable)

Con el algoritmo original. Aquí definimos \ExtractRadicalcuál regresa expandiblemente A,Bcon N=A^2 B. Un envoltorio no expandible se recicla \Rsqrtdesde el enfoque más rápido anterior para producir A\sqrt{B}, distinguiendo casos de negativo No N=0, 1.

He agregado comentarios de código para explicar la implementación. Una versión anterior era muy aburrida (ver la parte superior de la respuesta) y además requería xintexpr 1.2glo que ya no es el caso.

\documentclass[a4paper]{article}

\usepackage{geometry}

\usepackage{xintexpr}

% Aim: given N find largest I such as I^2 divides N.
% Then compute J=N/I^2 and print I\sqrt{J}.

% Algorithm: compute first truncated square root Imax of N.
% With I = Imax try to divide N by I^2, if it does not work
% repeat with I replaced by I-1 and so on. 
% As soon as it works the seeked-for I has been found.

% **** Notice: embarrassingly the author of this answer initially continued
% **** the algorithm recursively with N<-N/I^2, which was very stupid, but
% **** explainable from the fact that he had implemented first another (much
% **** faster) algorithm which divided not from the top down, but from the
% **** bottom up.

% The code is far simpler now. And it does not require xintexpr 1.2g anymore,
% earlier versions of xintexpr.sty work, too.

% The iteration over i used Imax..1 syntax which requires Imax 
% to be <2^31. Else we could use Imax..[-1]..1, but we don't
% really consider realistic to iterate over 2^31 or more values !

% After an update we use (-Imax)++ syntax; this also requires Imax<2^31.

\def\ExtractRadical #1{%
  \xinttheiiexpr 
  subs(
  % we return I, #1//I^2 where I is biggest integer such as I^2 divides #1.
     (I, #1//I^2), 
  % The I is computed via the "seq" here. Theoretically this "seq" 
  % evaluates as many values as the last list indicates.
  % But here we omit all i's such that i^2 does not divide #1
  % and as soon as we have found one, we stop here and now by 
  % "break". We work topdown, at the worst I=1.
% The i=A..B syntax pre-generates all values, which is wasteful
% and limited to about at most 5000 values.
%       I=seq((#1/:i^2)?{omit}{break(i)}, i=sqrt(#1)..1)
% On the contrary the N++ syntax does not pre-generate anything.
       I=seq((#1/:i^2)?{omit}{break(-i)}, i=-sqrt(#1)++)
% There is currently no "n--" only "n++", thus we tricked with a minus sign.
      )
  \relax
}

\makeatletter

\def\Rsqrt@ {\expandafter\Rsqrt@@\romannumeral-`0\ExtractRadical\N,}

% The #2#3 trick is to get rid of a space after the comma
% because \ExtractRadical does \xinttheiiexpr which in case
% of comma separated values on output always inserts such a space.
% Naturally as the typesetting is in math mode the space is
% not a real problem (it is not a problem either in \xintiiifOne 
% as here its argument is already expanded anyhow).
\def\Rsqrt@@ #1,#2#3,{\xintiiifOne{#1}{}{#1}\xintiiifOne{#2#3}{}{\sqrt{#2#3}}}

\newcommand* \Rsqrt[1]{%
   \begingroup
     \edef\N{\xinttheiexpr #1\relax}%
     \xintiiifSgn \N
        {\pm\edef\N{\xintiiAbs{\N}}\xintiiifOne\N{}{\Rsqrt@}i}
        {0}
        {\xintiiifOne \N{1}{\Rsqrt@}}
   \endgroup
 }

\makeatother
\usepackage{multicol}

\begin{document}

\parindent0pt\def\columnseprule{.4pt}%

% testing

\begin{multicols}{4}
\xintFor* #1 in {\xintSeq {10000}{10099}}\do
       {$\sqrt{#1}=\Rsqrt{#1}$\par}
\end{multicols}

% $\Rsqrt{-10}, \Rsqrt{-1}, \Rsqrt{-16}$

$\Rsqrt {1e6}, \Rsqrt {1e7}$%, 

% this one does not work because 10^10.5 > 2^31 causes an arithmetic
% overflow in the "sqrt(J)..1" part. 
% It would not overflow with "sqrt(J)..[-1]..1"
% but then we can wait long time ... 
% from 31622776601 downto
%      10000000000 that's a lot of iterations !
%$\Rsqrt{1e21}$
% The update uses n++ syntax, but this also requires abs(n) to be <2^31
% hence the same remark applies: a "Number too big" error is generated.
% Better actually than to wait the completion of 21622776601 iterations ;-)


% \stop

\pdfsetrandomseed 123456789

% we try with smaller numbers... 1000 replaced by 100...
\begin{multicols}{3}
\xintiloop [1+1]
    \edef\Z {\xinttheiiexpr 
             (\pdfuniformdeviate 100)^2
             *\pdfuniformdeviate 100\relax }%
    $\sqrt{\Z}=\Rsqrt{\Z}$\par
\ifnum\xintiloopindex<51
\repeat
\end{multicols}

\end{document}

ingrese la descripción de la imagen aquí


Tercer enfoque: nuevamente el algoritmo más rápido, pero expandible.

Sería más razonable codificar esto à la \numexprpero bien. Detalles en el comentario del código. El ejemplo ahora tiene 51 ejemplos aleatorios y, curiosamente, el que faltaba (desde el primer enfoque) resultó ser un cuadrado aleatorio (con la semilla aleatoria del generador de números aleatorios pdftex configurada en 123456789).

\documentclass[a4paper]{article}

\usepackage{geometry}

\usepackage{xintexpr}[2016/03/19]%
% needs xintexpr 1.2g due to 
%  - changed meaning of iter
%  - shift by 1 in [L][n] syntax


% syntax \ExtractRadical {N or <integer expression>} expands to "A, B" with
% N=A^2 B, B square-free
% Algorithm:
% main variable a triple (P, I, J) where
%  - always N = I^2 J
%  - J's prime factors < P have multiplicity one.
% START: (2, 1, N)
% ITER:  (P, I, J)
         % Q=P^2
         % is Q > J ?
         %   - yes: STOP(I, J)
         %   - no:
         %         does Q divide J ?
         %         - yes: I<-I*P, J<-J/Q and repeat until Q does not divide J
         %         - no; continue with (P+2, I, J). Except if P=2 then we go
         %                      on with P=3.
% Also works with N=0 (produces 1, 0) and with N=1 (produces 1, 1)
%

\newcommand*\ExtractRadical [1]{%
  \xinttheiiexpr 
  iter (2, 1, #1; % starting triple P=2, I=1, J=N
  subs(subs(subs(subs(
  % apart from Q=P^2, these substitutions are mainly because [@][n] syntax
  % is cumbersome; and inefficient as it allows n to be itself a complicated
  % expression, hence does some rather unneeded parsing here of n= 0, 1, 2.
  % We really need some better syntax like iter(P=2, I=1, J=#1;...) and then
  % work with P, I, J standing for the last values.
  % Or at least something like subs(..., (Q, P, I, J)=(...)).
  % (not yet with xintexpr 1.2g). 
  (Q>J)?
      {break(I, J)}
      {(J/:Q)?
          {(n)?{P+2}{3}, I, J}
      % must use parentheses here: ([@][1]). Else ]/: will confuse parser.
      % I could have used again subs, but well. 
          {iter(P*I,J//Q;(([@][1])/:Q)?{break((n)?{P+2}{3},@)}
                                       {(P*[@][0],([@][1])//Q)},e=1++)
          }
      }
  , Q=P^2), P=[@][0]), I=[@][1]), J=[@][2]), n=0++)
    \relax
}             
                  
\makeatletter
\def\Rsqrt@ {\expandafter\Rsqrt@@\romannumeral-`0\ExtractRadical\N,}

\def\Rsqrt@@ #1,#2,{\xintiiifOne{#1}{}{#1}\xintiiifOne{#2}{}{\sqrt{#2}}}

\newcommand* \Rsqrt[1]{%
   \begingroup
     \edef\N{\xinttheiexpr #1\relax}%
     \xintiiifSgn \N
        {\pm\edef\N{\xintiiAbs{\N}}\xintiiifOne\N{}{\Rsqrt@}i}
        {0}
        {\xintiiifOne \N{1}{\Rsqrt@}}
   \endgroup
 }

\makeatother
\usepackage{multicol}

\begin{document}

\parindent0pt\def\columnseprule{.4pt}%

% testing

% \xintFor* #1 in {\xintSeq {0}{50}}\do 
% {\ExtractRadical {#1}\par}

% \ExtractRadical {128}

% \ExtractRadical {1024}
% \stop

% $\Rsqrt{5000}$

% \stop

% \begin{multicols}{4}
% \xintFor* #1 in {\xintSeq {10000}{10099}}\do
%        {$\sqrt{#1}=\Rsqrt{#1}$\par}
% \end{multicols}

$\Rsqrt{-10}, \Rsqrt{-1}, \Rsqrt{-16}$

$\Rsqrt {1e6}, \Rsqrt {1e7}, \Rsqrt {1e21}$%, 

\pdfsetrandomseed 123456789

\begin{multicols}{3}
\xintiloop [1+1]
    \edef\Z {\xinttheiiexpr 
             (\pdfuniformdeviate 1000)^2
             *\pdfuniformdeviate 1000\relax }%
    $\sqrt{\Z}=\Rsqrt{\Z}$\par
\ifnum\xintiloopindex<51
\repeat
\end{multicols}

\end{document}

ingrese la descripción de la imagen aquí


Actualización (2017).

Aquí hay una macro expandible sin paquete, si es necesario. Se expande hasta I,Jdonde Nestá el original I**2 times Jy Jno tiene cuadrados. Solo usos \numexpr. Limitado a <2**31números enteros. Funciona de menor a mayor, igual que el método de factorización elemental. Los criterios de parada deberían mejorarse; el siguiente comentario también se aplica aquí.

\makeatletter

\newcommand\ExtractRadical[1]{%
    \romannumeral0%
    \expandafter
    \ExtractRadical@two@i\expandafter1\expandafter,\the\numexpr#1.%
}%
\def\ExtractRadical@two@i #1,#2.{%
    \ifnum4>#2 \expandafter\ExtractRadical@two@done\fi
    \expandafter\ExtractRadical@two@ii\the\numexpr#2/4;#1,#2.%
}%
\edef\ExtractRadical@two@done #1;#2,#3.%
    {\space#2,#3}% (not sole #2 for readability)
\def\ExtractRadical@two@ii #1;#2,#3.{%
    \ifnum\numexpr#1*4=#3 
      \expandafter\@firstoftwo
    \else
      \expandafter\@secondoftwo
    \fi
   {\expandafter\ExtractRadical@two@i\the\numexpr2*#2,#1.}%
   {\ExtractRadical@i 3;#2,#3.}%
}%
\def\ExtractRadical@i #1;{%
    \expandafter\ExtractRadical@ii\the\numexpr#1*#1.#1;%
}%
\def\ExtractRadical@ii #1.#2;#3,#4.{%
    \ifnum#1>#4 \expandafter\ExtractRadical@done\fi
    \expandafter\ExtractRadical@iii\the\numexpr#4/#1.#1;#4.#2;#3.%
}%
\def\ExtractRadical@iii #1.#2;#3.{%
    \ifnum\numexpr#1*#2=#3
      \expandafter\@firstoftwo
    \else
      \expandafter\@secondoftwo
    \fi
    \ExtractRadical@update
    \ExtractRadical@next
    #1.#2;#3.%
}%
\def\ExtractRadical@update #1.#2;#3.#4;#5.{%
    \expandafter\ExtractRadical@ii
    \the\numexpr#2\expandafter.%
    \the\numexpr#4\expandafter;%
    \the\numexpr#4*#5,#1.%
}%
\def\ExtractRadical@next #1.#2;#3.#4;#5.{%
    \expandafter\ExtractRadical@i\the\numexpr2+#4;#5,#3.%
}%
\edef\ExtractRadical@done #1;#2.#3;#4.{\space#4,#2}%

\makeatother

Respuesta2

Aquí hay una solución basada en LuaLaTeX. El código configura una macro LaTeX llamada \rsqrt, que invoca una función Lua llamada rsqrt. Este último implementa el algoritmo de simplificación que usted propuso, con las siguientes mejoras:

  • Para n=0o n=1, el código simplemente devuelve n(sin símbolo de raíz cuadrada); y

  • Se tiene cuidado de omitir el \sqrt{n/i²}término si es igual a 1, es decir, si nes un "número cuadrado" (4, 9, 16, etc.) o un producto de números cuadrados más pequeños. Por ejemplo n=36, si \rsqrt{36}muestra 6desde 36 = 6^2 = 2^2*3^2.

No se realiza ninguna verificación de validez de la entrada, es decir, el usuario es responsable de proporcionar un argumento \rsqrtque sea un número entero no negativo o que se evalúe como un número entero no negativo. Por lo tanto, está bien escribir \rsqrt{1e6}y \rsqrt{3.6e7}: la macro devolverá 1000y 6000, respectivamente.

Observe que la macro \rsqrtdebe usarse en modo matemático ya que puede generar \sqrtdirectivas.

ingrese la descripción de la imagen aquí

% !TEX TS-program = lualatex  
%% Note: Code updated 2019/10/26 to work with LaTeX 2019-10-01 

%% Create an external file to contain the Lua code
\begin{filecontents*}[overwrite]{rsqrt.lua}
function rsqrt ( n )
  -- n : a non-negative whole number (or something
  --     that evaluates to a non-neg. whole number)
  if n == 0 or n == 1 then   -- Nothing to do
    return ( n )
  else
    i = math.floor ( math.sqrt ( n ) )
    while i > 1 do
      if ( n % i^2 == 0 ) then     -- n is divisible by i^2
        k = math.floor ( n / i^2 ) -- 'math.floor' makes k an explicit integer
        if k == 1 then  -- n is a "square" number (or a product of square numbers)
          return ( i )
        else
          return ( i .. "\\sqrt{" .. k .. "}" )
        end
      end
      i = i-1
    end
    -- No simplification possible:
    return ( "\\sqrt{" .. n .. "}" )
  end
end
-- Define a vector (in form of a Lua table) of whole numbers
nvec = {0,1,2,3,4,5,7,12,16,18,27,32}

-- Lua function to print 3-column array:
function PrintArray()
  for i=1,#nvec do
    u = nvec[i]
    tex.sprint ( math.floor(u) .. 
                "& \\sqrt{" .. math.floor(u) .. 
                "}&" .. rsqrt(u) .. "\\\\" )
  end
end
\end{filecontents*}

\documentclass{article}

%% Load Lua code from external file:
\directlua{dofile("rsqrt.lua")}

%% TeX-side code: "wrapper" macro that invokes the Lua function:
\newcommand\rsqrt[1]{\directlua{tex.sprint(rsqrt(#1))}}

\begin{document}
\[
\renewcommand\arraystretch{1.25}
\begin{array}{@{} rcc @{}}
  \verb+n+ & \verb+\sqrt+ & \verb+\rsqrt+ \\ % print header row
  \directlua{PrintArray()}    % create and print body of 'array'
\end{array}
\]
\end{document} 

Respuesta3

En expl3:

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\rsqrt}{m}
 {
  \manual_rsqrt:n { #1 }
 }

\int_new:N \l_manual_rsqrt_int

\cs_new_protected:Nn \manual_rsqrt:n
 {
  \int_set:Nn \l_manual_rsqrt_int { \fp_to_decimal:n { trunc(sqrt(#1),0) } }
  \bool_until_do:nn
   {
    \int_compare_p:n { \int_mod:nn { #1 } { \l_manual_rsqrt_int * \l_manual_rsqrt_int } == 0 }
   }
   {
    \int_decr:N \l_manual_rsqrt_int
   }
  \int_compare:nTF { \l_manual_rsqrt_int == 1 }
   {
    \sqrt{#1}
   }
   {
    \int_to_arabic:n { \l_manual_rsqrt_int }
    \int_compare:nF { #1 == \l_manual_rsqrt_int*\l_manual_rsqrt_int }
     {
      \sqrt{ \int_to_arabic:n { #1/(\l_manual_rsqrt_int*\l_manual_rsqrt_int) } }
     }
   }
 }
\ExplSyntaxOff

\begin{document}

$\rsqrt{4}$

$\rsqrt{8}$

$\rsqrt{18}$

$\rsqrt{12}$

$\rsqrt{7}$

\end{document}

ingrese la descripción de la imagen aquí

Si desea tratar con los argumentos 0 y 1 y también con argumentos negativos, puede cambiar la definición principal a

\NewDocumentCommand{\rsqrt}{m}
 {
  \int_compare:nTF { #1 < 0 }
   {
    \int_compare:nTF { #1 = -1 } { i } { \manual_rsqrt:n { -#1 } i }
   }
   {
    \int_compare:nTF { #1 < 2 } { #1 } { \manual_rsqrt:n { #1 } }
   }
 }

Ahora la entrada

$\rsqrt{0}$ and $\rsqrt{1}$

$\rsqrt{-1}$ and $\rsqrt{-4}$ and $\rsqrt{-32}$

daría salida

ingrese la descripción de la imagen aquí

Respuesta4

Si no es reacio a saltar fuera de LaTeX, aquí tiene una solución que utiliza el pythontexpaquete. Lo llamé srootraíz simple. Obviamente, puedes llamarlo como quieras. Esta versión requiere un

pdflatex *filename*.tex, pythontex filename*.tex, pdflatex *filename*.texsecuencia de ejecución de su documento.

\documentclass{article}
\usepackage{pythontex}
\begin{document}
\newcommand{\sroot}[1]{\ensuremath{\py{simpleroot(#1)}}}
\begin{pycode}
from math import *
def simpleroot(n):
    if n==0:
        return(str(0))
    j=int(sqrt(n))
    flag_continue=True
    while flag_continue:
        b=n*1./(j*j)
        if b==int(b):
            mystring=str(j)+'\\sqrt{'+str(int(b)) +'}'
            flag_continue=False
        else:
            j-=1

        if int(b)==1:
            mystring=str(j)
        if int(b)==n and b>1:
            mystring='\\sqrt{'+str(int(b)) +'}'

    return(mystring)
\end{pycode}

This is a test.

The $\sqrt{1}$ is \sroot{1}.

The $\sqrt{4}$ is \sroot{4}.

The $\sqrt{7}$ is \sroot{7}.

The $\sqrt{8}$ is \sroot{8}.

The $\sqrt{18}$ is \sroot{18}.

The $\sqrt{23}$ is \sroot{23}.

The $\sqrt{27}$ is \sroot{27}.

The $\sqrt{32}$ is \sroot{32}.

The $\sqrt{64}$ is \sroot{64}.

The $\sqrt{80}$ is \sroot{80}.

The $\sqrt{1000}$ is \sroot{1000}.

The $\sqrt{3000033}$ is \sroot{3000033}.

Goodbye.
\end{document}

información relacionada