Saltar al contenido

Mejor código para encontrar el número narcisista

Este dilema se puede abordar de diversas maneras, pero en este caso te damos la que para nosotros es la solución más completa.

Solución:

Aquí hay un enfoque funcional:

Narciss[x_] :=  With[num = IntegerDigits[x], Total[num^Length[num]] == x]

Aquí hay una versión compilada de la función anterior:

NarcissC =  Compile[x, _Integer, 
  With[num = IntegerDigits[x], Total[num^Length[num]] == x], 
  Parallelization -> True, CompilationTarget -> "C", 
  RuntimeAttributes -> Listable, RuntimeOptions -> "Speed"]

Ahora puedes hacer algo como

AbsoluteTiming[Position[NarcissC[Range[10000000]], True] // Flatten]

1.003214, 1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407, 1634, 8208, 9474, 54748, 92727, 93084, 548834, 1741725, 4210818, 7,980 9926315

para obtener todo el metro-Números narcisistas del 1 al 10000000.

Para un aumento adicional en la velocidad como lo sugiere chyaong, aquí está NarcissC2 (Utilizando Sum en vez de Total)

NarcissC2 = Compile[x, _Integer, 
   With[num = IntegerDigits[x], Sum[i^[email protected], i, num] - x], 
   CompilationTarget -> "C", RuntimeAttributes -> Listable, RuntimeOptions-> "Speed"];

Ahora puedes hacer:

Pick[#, NarcissC2[#], 0] &@Range[10000000] // AbsoluteTiming

Lo que da:

0.475276, 1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407, 1634, 8208, 9474, 54748, 92727, 93084, 548834, 1741725, 4210818, 7,980 9926315

EDITAR

Resulta que puedes obtener un bache usando Total y Pick en vez de Position (no tan rápido como Sum):

  NarcissC1 =  Compile[x, _Integer, 
    With[num = IntegerDigits[x], Total[num^Length[num]] - x], Parallelization -> True, 
    CompilationTarget -> "C", RuntimeAttributes -> Listable, RuntimeOptions -> "Speed"]

Entonces

Pick[#, NarcissC1[#], 0] &@Range[10000000] // AbsoluteTiming

da:

0.626322, 1, 2, 3, 4, 5, 6, 7, 8, 9, 153, 370, 371, 407, 1634, 8208,
   9474, 54748, 92727, 93084, 548834, 1741725, 4210818, 9800817, 9926315

no es una respuesta per sepero dos aclaraciones (que son demasiado largas para la caja de comentarios):

1) La definición de Wiki a la que se ha vinculado para un número narcisista no es realmente adecuada. La página Wiki en realidad describe la definición de un número de Armstrong, también conocido como invariantes digitales pluscuamperfectos, o metro-Números narcisistas, tales como:

$$407 = 4^3 + 0^3 + 7^3$$

Estos requieren el uso del término de potencia $m$ (el 3 en este ejemplo) por encima de los dígitos del entero $n= 407$. Por el contrario, la referencia correcta y adecuada al término ‘número narcisista’ proviene del artículo de Madachy, JS (1966), Matemáticas de vacacionesThomas Nelson & Sons — p.163 a 175, quien los define como números:

“que son representables, de alguna manera, manipulando matemáticamente los dígitos de los propios números”.

Lo que describe la página Wiki… los números de Armstrong… es bastante diferente… no los ‘números narcisistas’, como afirma la página, sino los metro-Números narcisistas. Pero eso es wiki para ti.

2) Finito a infinito: el conjunto de números narcisistas implica una búsqueda finita (como las soluciones anteriores). El problema se vuelve bastante más complicado si permite el uso de radicales o factoriales… porque el problema de búsqueda ya no es finito… sino que puede tener un anidamiento infinito de símbolos de raíces cuadradas o factoriales.

ingrese la descripción de la imagen aquí

Uno puede obtener algunos resultados bonitos cuando permite radicales, como decir:

ingrese la descripción de la imagen aquí

Para obtener más detalles, consulte:

http://www.tri.org.au/numQ/pwn/

o una pequeña pieza divertida que hice titulada:

Números narcisistas radicales, Revista de matemáticas recreativas33(4), 2004-2005, 250-254.

He tenido la intención de poner el código mma para esto también… esto se hizo mucho antes de la era de los multiprocesadores, así que creo que tendré que actualizar el código para núcleos paralelos, lo que marcaría una gran diferencia. aquí.

nar[m_] := 
  ToExpression[
   "Compile[$,Do[With[n=0" <> 
    StringJoin[
     Table["+1" <> Array["0" &, m - 1 - i, 1, StringJoin] <> "a" <> 
       ToString[m - 1 - i], i, 0, m - 1]] <> ",n2=0" <> 
    Table["+a" <> ToString[m - 1 - i] <> "^" <> ToString[m], i, 0, 
      m - 1] <> ",If[n[Equal]n2,[email protected]];];,a0" <> 
    StringJoin[Table[",0,9,a" <> ToString[i], i, 1, m - 1]] <> 
    ",9],RuntimeOptions[Rule]"Speed",CompilationTarget[Rule]"C"
]"];

Reap[nar[7][0]][[2, 1]] // AbsoluteTiming

(*1.184733, 9926315, 1741725, 9800817, 4210818*)

Mi computadora es bastante lenta. El código de @RunnyKine tarda 0,901549 segundos en mi computadora.

Eres capaz de favorecer nuestro análisis mostrando un comentario o valorándolo te lo agradecemos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *