Упрощение квадратных корней

Упрощение квадратных корней

Я хочу создать команду, которая для заданного целого числа nтипа устанавливает упрощенный квадратный корень из n. Например, вывод

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

будет таким же, как и у

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

где \rsqrt{}находится команда, о которой идет речь.

Я знаю, что алгоритм будет выглядеть примерно так

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

где n— заданное целое число, i— число перед ним \sqrt, а n/i²— аргумент \sqrt{...}.

Но я понятия не имею, как это реализовать в латексе?

EDIT: Уточнено, что вводимое число всегда будет целым числом.

решение1

Алгоритм в вопросе очень неэффективен: за исключением, конечно, случая, когда исходное целое число является полным квадратом.

Этот ответ (в хронологическом порядке):

  1. подход с макросами, который имитирует простейший алгоритм факторизации,

  2. расширяемый подход с использованием алгоритма, как в OP.обновлятьочень стыдно, что автор не понял алгоритм OP и после того, как нашел упрощение, Iтакое как I^2divided N, он пошел по нему рекурсивно, N<-N/I^2не понимая, что алгоритм может остановиться на этом. (в качестве слабого оправдания он сначала реализовал способ "снизу вверх", который требует рекурсии, в отличие от способа "сверху вниз" (менее эффективного)). Таким образом, ответ обновлен, извинения всем великодушным доверчивым ранним голосующим "за".

    Я снова обновляю (извините), потому что теперь я прочитал больше xintexpr.styдокументации, и я переключился для эффективности с i=sqrt(N)..1на i=-sqrt(N)++(доступного нет --, отсюда трюк со знаком минус). Первый генерирует заранее весь список floor(\sqrt{N})чисел ( sqrtозначает усеченный квадратный корень в \xintiiexpr), последний является итератором, который ничего не генерирует заранее. Более того, первый синтаксис может генерировать только около 5000значений ( sqrt(N)..[-1]..1не будет иметь такого ограничения, но все равно сгенерирует все заранее).

  3. расширяемая реализация более быстрого алгоритма (типа школьной факторизации), как в подходе 1.

Честно говоря, 2., 3. и даже 1., вероятно, было бы лучше написать полностью, используя \numexprих притворство об обработке чисел, больших, чем 2^31, поскольку это немного натянуто, требуется время для простого числа из 10 цифр, чтобы выполнить десятки тысяч делений, чтобы сделать вывод о том, что оно бесквадратное... Реализация 2. имеет внутреннее ограничение, поскольку 2^62квадратный корень должен быть числом TeX (из-за некоторой внутренней конструкции).

В 2. и 3. мы немного выходим за рамки разумного диапазона возможностей \xintexprсинтаксиса с рекурсивными последовательностями. Нотация немного громоздкая. Кроме того, xintexpr.sty 1.2gона нужна, потому что изменила соответствующий синтаксис.

  1. наконец (2017) я также добавляю расширяемый подход без пакета numexpr.

Первый подход (меняем алгоритм)

Не сказать, что это простая задача. Немного поиска в Google показывает, что, по-видимому, математики в настоящее время считают, что нахождение квадратного свободного радикала целого числа может быть таким же сложным, как полная факторизация:https://math.stackexchange.com/questions/171568/поиск-радикала-целого-числаиhttps://math.stackexchange.com/questions/14667/square-free-integers-factorization.

Вот подход (с использованием макросов), который имитирует простейшую форму алгоритма факторизации.

Пакет xintexprиспользуется только для того, чтобы разрешить ввод, такой как 1e7или даже выражения. Он также загружает xinttools, что используется в синтаксисе.

Кроме того, все операции выполняются с помощью макросов, доступных из xint. Поскольку в примере мы имеем дело практически только с числами, <2^31мы могли бы использовать вариант, где все операции выполнялись бы с использованием uniquely \numexpr, естественно, это было бы намного быстрее.

Код использует \xintiiDivision, который одновременно вычисляет частное и остаток. Вот почему \xintAssignиспользуется для сохранения их в двух макросах \Aи \B. Код проверяет, \Bисчезает ли , чтобы обнаружить делимость на 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}

введите описание изображения здесь


Второй подход (такой же алгоритм, как в OP, расширяемая реализация)

С исходным алгоритмом. Здесь мы определяем, \ExtractRadicalкакой расширяемый возвращает A,Bс N=A^2 B. Нерасширяемая оболочка повторяет цикл \Rsqrtболее быстрого подхода выше для получения A\sqrt{B}, различая случаи отрицательного Nили N=0, 1.

Я добавил комментарии к коду, чтобы объяснить реализацию. Более ранняя версия была очень хромой (см. начало ответа) и дополнительно требовала, xintexpr 1.2gчто больше не актуально.

\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}

введите описание изображения здесь


Третий подход: снова более быстрый алгоритм, но с возможностью расширения.

Было бы разумнее закодировать это а-ля \numexprно хорошо. Подробности в комментарии к коду. В примере теперь 51 случайный пример, и забавно, что недостающий (из первого подхода) оказался случайным квадратом (со случайным начальным значением для генератора случайных чисел pdftex, установленным на 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}

введите описание изображения здесь


Обновление (2017).

Вот макрос, расширяемый без пакета, если нужно. Он расширяется до того места, где находится I,Jоригинал, и не содержит квадратов. Использует только . Ограничено целыми числами. Работает от меньшего к большему, как и метод элементарной факторизации. Критерии остановки следует улучшить, комментарий ниже применим и здесь.NI**2 times JJ\numexpr<2**31

\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

решение2

Вот решение на основе LuaLaTeX. Код устанавливает макрос LaTeX с именем \rsqrt, который вызывает функцию Lua с именем rsqrt. Последняя реализует предложенный вами алгоритм упрощения — со следующими уточнениями:

  • Для n=0или n=1код просто возвращает n(без символа квадратного корня); и

  • Следует проявлять осторожность, чтобы опустить \sqrt{n/i²}член, если он равен 1, т. е. если nэто «квадратное число» (4, 9, 16 и т. д.) или произведение меньших квадратных чисел. Например, если n=36, \rsqrt{36}показывает 6, что 36 = 6^2 = 2^2*3^2.

Проверка корректности ввода не выполняется, т. е. пользователь несет ответственность за предоставление аргумента, \rsqrtкоторый является либо неотрицательным целым числом, либо оценивается как неотрицательное целое число. Таким образом, можно писать \rsqrt{1e6}и \rsqrt{3.6e7}: макрос вернет 1000и 6000, соответственно.

Обратите внимание, что макрос \rsqrtнеобходимо использовать в математическом режиме, поскольку он может выводить \sqrtдирективы.

введите описание изображения здесь

% !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} 

решение3

В 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}

введите описание изображения здесь

Если вы хотите иметь дело с аргументами 0 и 1, а также с отрицательными аргументами, вы можете изменить основное определение на

\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 } }
   }
 }

Теперь ввод

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

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

выведет

введите описание изображения здесь

решение4

Если вы не против выйти за рамки LaTeX, вот решение с использованием пакета pythontex. Я назвал его srootдля простого корня. Очевидно, вы можете назвать его как угодно. Эта версия требует

pdflatex *filename*.tex, pythontex filename*.tex, pdflatex *filename*.texпоследовательность выполнения для вашего документа.

\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}

Связанный контент