Menu Close

La función de Smarandache

La función de Smarandache, también conocida como la función de Kempner, es la función que asigna a cada número entero positivo n el menor número cuyo factorial es divisible por n y se representa por S(n). Por ejemplo, el número 8 no divide a 1!, 2!, 3!, pero sí divide 4!; por tanto, S(8) = 4.

Definir las funciones

   smarandache        :: Integer -> Integer
   graficaSmarandache :: Integer -> IO ()

tales que

  • (smarandache n) es el menor número cuyo factorial es divisible por n. Por ejemplo,
     smarandache 8   ==  4
     smarandache 10  ==  5
     smarandache 16  ==  6
  • (graficaSmarandache n) dibuja la gráfica de los n primeros términos de la sucesión de Smarandache. Por ejemplo, (graficaSmarandache 100) dibuja
    La_funcion_de_Smarandache_100
    (graficaSmarandache 500) dibuja
    La_funcion_de_Smarandache_500

Soluciones

import Data.List (genericLength)
import Graphics.Gnuplot.Simple
 
smarandache :: Integer -> Integer
smarandache x =
  head [n | (n,y) <- zip [0..] factoriales
          , y `mod` x == 0]
 
-- factoriales es la lista de los factoriales. Por ejemplo, 
--    λ> take 12 factoriales
--    [1,1,2,6,24,120,720,5040,40320,362880,3628800,39916800]
factoriales :: [Integer]
factoriales = 1 : scanl1 (*) [1..]
 
graficaSmarandache :: Integer -> IO ()
graficaSmarandache n =
  plotList [Key Nothing
           , PNG ("La_funcion_de_Smarandache_" ++ show n ++ ".png")
           ]
           (map smarandache [1..n])
Inicial

14 soluciones de “La función de Smarandache

  1. alerodrod5
     
    import Graphics.Gnuplot.Simple
    smarandache        :: Integer -> Integer
    smarandache n = head [ x | x<-[1..], factorial x `mod`n ==0]
      where factorial 0 = 1
            factorial n = n*factorial (n-1)
     
    smarandaches :: [Integer]
    smarandaches = map smarandache [1..]
     
    graficaSmarandache :: Integer -> IO ()
    graficaSmarandache n= plotList [Key Nothing] (take (fromInteger n) smarandaches)
  2. menvealer
    smarandache :: Integer -> Integer
    smarandache n = aux n 1
      where aux n l | mod (factorial l) n == 0 = l
                    | otherwise = aux n (l+1)
     
    factorial :: Integer -> Integer
    factorial n = product [1..n]
    • menvealer
      Voy a cambiar el nombre de la variable "l" de la función auxiliar, ya que no se diferencia con los "1" (unos)
      smarandache :: Integer -> Integer
      smarandache n = aux n 1
        where aux n k | mod (factorial k) n == 0 = k
                      | otherwise = aux n (k+1)
       
      factorial :: Integer -> Integer
      factorial n = product [1..n]
  3. anadebla
     
    smarandache :: Integer -> Integer
    smarandache n = snd (head (filter ((x,y) -> x == 0) (listaFinal n)))
     
    factorial n = product [x | x <- [1..n]]
     
    listaModFactoriales n = [mod (factorial x) n| x <- [1..]]
    listaFactoriales = [factorial x | x <- [1..]]
     
    listaFinal n = zip (listaModFactoriales n) [1..]
  4. albcarcas1
    import Graphics.Gnuplot.Simple
     
    smarandache :: Integer -> Integer
    smarandache n = head[x | x <- [1..n], rem (factorial x) n == 0] 
     
    factorial :: Integer -> Integer
    factorial n = product [1..n]
     
    graficaSmarandache :: Integer -> IO ()
    graficaSmarandache n = plotList [Title "Grafica Smarandache", Key Nothing]  (map smarandache [1..n])
  5. angruicam1
    import Data.Array              (array, (!))
    import Data.Numbers.Primes     (isPrime)
    import Graphics.Gnuplot.Simple (plotList, Attribute (Key))
     
    smarandache :: Integer -> Integer
    smarandache n | isPrime n = n
                  | otherwise =
                    head [i | i <- [0..n`div`2+2], v!i `mod` n == 0]
      where v = array (0,n`div`2+2)
                ([(0,1)] ++ [(i,i*v!(i-1)) | i <- [1..n`div`2+2]])
     
    graficaSmarandache :: Integer -> IO ()
    graficaSmarandache n =
      plotList
      [Key Nothing]
      (map smarandache [1..n])

    La elección de la cota para el vector puede apreciarse representando la siguiente gráfica (aunque convendría probar que se cumple siempre):

    import Graphics.Gnuplot.Simple (plotLists)
     
    graficaSmarandache2 :: Integer -> IO ()
    graficaSmarandache2 n =
      plotLists
      [Key Nothing]
      ([map smarandache [1..n], [1..n], map ((+2) . (`div` 2)) [1..n]])
  6. josejuan

    Si tenemos la factorización de n (para lo cual no se conoce algoritmo eficiente), puede calcularse el smarandache de forma eficiente, pues podemos obtener un índice para cada primo y potencia de la factorización para el mínimo factorial que lo contiene (ese primo con esa potencia).

    import Data.Numbers.Primes
    import Data.List (group)
     
    -- potencia del primo p en el factorial de n
    powerOnFact :: Integral a => a -> a -> a
    powerOnFact p = sum . tail . takeWhile (>0) . iterate (`div` p)
     
    -- powerOnFact p x = y tiene una pendiente y/x asintótica a sum{1/p^k}k=1..
    -- con valor 1/(p-1), el valor asintótico es una cota superior, por tanto no va a dar
    -- una cota inferior al hacer x=y/m
    minFactPower :: Integral a => a -> a -> a
    minFactPower p k = head [n | n <- [k * (p - 1)..], powerOnFact p n >= k]
     
    -- el mínimo será el máximo de los mínimos necesarios para cada descomposición prima
    smarandache :: Integral a => a -> a
    smarandache = maximum . map (xs@(x:_) -> minFactPower x (fromIntegral $ length xs)) . group . primeFactors
     
    -- ahora el único problema es factorizar números enormes (que pueden ser difíciles de factorizar)
    -- pero calcular el mínimo factorial es inmediato, por ejemplo, hacerlo para un número de 97.000 dígitos
    -- formado por el producto de los primeros 20.000 primos
    *Main> smarandache (product $ take 20000 primes)
    224737
    (1.86 secs, 1,575,488,232 bytes)
  7. Chema Cortés
    import           Data.List               (genericLength)
    import           Graphics.Gnuplot.Simple
     
    smarandache :: Integer -> Integer
    smarandache 0 = 0
    smarandache n = (+1) . genericLength
                  . takeWhile ((/=0).(`mod` n))
                  $ scanl1 (*) [1..]
     
    graficaSmarandache :: Integer -> IO ()
    graficaSmarandache n = plotList [Key Nothing] (map smarandache [0..n])
  8. Chema Cortés

    Una solución mucho más optimizada:

    smarandache2 :: Integer -> Integer
    smarandache2 = aux [1..]
      where
        aux (m:ms) n | d == n     = m
                     | otherwise  = aux ms (n `div` d)
          where d = gcd n m
  9. jaibengue
    import Data.Numbers.Primes
    import Data.List
     
    smarandache :: Integer -> Integer
    smarandache = maximum.map menorN.descomposicionN
     
    -- Dado un primo P nos devuelve una lista donde el N-ésimo elemento es el
    -- mayor entero E tal que P^E divide a P*N:
     
    exponentesP :: Integer -> [Int]
    exponentesP p = 1 : aux[1] 2
      where aux xs n = a ++ aux b (n+1)
              where a = init(concat(init c)) ++ [n]
                    b = init(concat(c)) ++ [n]
                    c = take (fromIntegral p) (repeat xs)
     
    -- Dado un entero N lo descompone en todos los pares (P_1,L_1), (P_2,L_2), ... ,(P_k,L_k)
    -- donde N = P_1^(L_1) * P_2^(L_2) * ... * P_k^(L_k) y P_1, P_2, ... , P_k son primos:
     
    descomposicionN :: Integer -> [(Integer,Int)]
    descomposicionN = map (p@(x:xs) -> (x,length p)).group.primeFactors
     
    -- Dado un par (P,L) nos da el menor entero N tal que P^L divide a N!
     
    menorN :: (Integer,Int) -> Integer
    menorN (p,l) = aux (exponentesP p) 0 0
      where aux (x:xs) s n | s < l = aux xs (s+x) (n+1) 
                           | otherwise = p*n
  10. rocruimon
     
    smarandache :: Integer -> Integer
    smarandache n = head[y | y<-[1..div n 2], mod (factorial y) n == 0]
     
    factorial :: Integer -> Integer
    factorial n= product [1..n]
     
    graficaSmarandache :: Integer -> IO ()
    graficaSmarandache n= plotList [Key Nothing] (map smarandache [1..n])
    • rocruimon
      -- Aunque para los ejemplos funcione debería ser así mejor
       
       
      smarandache :: Integer -> Integer
      smarandache n =head [y | y<-[1..2*n], mod (factorial y) n ==0]
  11. carbremor

    En Maxima:

    (%i1)   fact(n) :=
          if n = 0 then 1
          else     n*fact(n-1)$
     
    (%i2)   smarandache(a) := block([m:0], 
            while (mod(fact(m), a)  # 0) do
                   (m : m+1), m)$
     
    (%i5)    smarandache(8);
         smarandache(10);
         smarandache(16);
    (%o3)   4
    (%o4)   5
    (%o5)   6
     
    (%i7)   smarandache(1490);
         elapsed_run_time ();
    (%o6)   149
    (%o7)   0.21
     
    /* La función  elapsed_run_time ();  devuelve una estimación en segundos (incluyendo fracciones de segundo) durante los cuales Maxima ha estado realizando cálculos desde que se inició la sesión */

Escribe tu solución

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.