La secuencia Agregar-Multiplicar-Agregar

27

( Relacionado )

Dado un número entero n > 1,
1) Construya el rango de números n, n-1, n-2, ... 3, 2, 1y calcule la suma
2) Tome los dígitos individuales de ese número y calcule el producto
3) Tome los dígitos individuales de ese número y calcule la suma
4) Repita los pasos 2 y 3 hasta que alcanzar un solo dígito. Ese dígito es el resultado.

Los primeros veinte términos de la secuencia están a continuación:

3, 6, 0, 5, 2, 7, 9, 2, 7, 9, 1, 9, 0, 0, 9, 6, 7, 0, 0, 6

Nota: Esta secuencia NO está en OEIS.

E / S y reglas

  • Los números se harán muy grandes rápidamente, por lo que la solución debe ser capaz de manejar números de entrada de hasta 100,000 sin fallas (está bien si su código puede manejar más allá de eso).
  • La entrada y la salida se pueden dar por cualquier método conveniente .
  • Un programa completo o una función son aceptables. Si es una función, puede devolver el resultado en lugar de imprimirlo.
  • Las lagunas estándar están prohibidas.
  • Este es el por lo que se aplican todas las reglas habituales de golf, y gana el código más corto (en bytes).

Ejemplos

n     output
1234   9
3005   3
5007   5
9854   8
75849  8
100000 0
AdmBorkBork
fuente
3
+1 para un desafío de secuencia que no está en el OEIS
JAD
2
Siempre que n ≤ 100000 , solo dos iteraciones de los pasos 2 y 3 son suficientes para obtener el resultado. ¿Podemos aprovechar eso o el algoritmo que elegimos debería funcionar para valores mayores de n ?
Dennis
2
@Dennis El algoritmo debería funcionar para cualquier valor de n. La solución publicada solo tiene que funcionar hasta n = 100000.
AdmBorkBork
3
Numbers will get very large quicklyno, no lo hace
l4m2
3
@ l4m2 No es la salida. Pero 100000 + 99999 + ... + 1 = 5000050000 es un número de 33 bits, que su idioma de elección puede o no tener problemas para representar.
Dennis

Respuestas:

10

Python 2 , 77 72 71 62 60 bytes

lambda n:reduce(lambda x,c:eval(c.join(`x`)),'*+'*n,-n*~n/2)

¡Gracias a @xnor por jugar 2 bytes!

Pruébalo en línea!

Dennis
fuente
Me acaba de cambiar a un bucle, pero voy a tener que recordar ese truco para el futuro.
Dennis
Where's el repeat until you reach a single digit?
Titus
2
@Titus Simplemente realizo n iteraciones de los pasos 2 y 3, que siempre es suficiente. De hecho, como n ≤ 100000 , tres iteraciones serían suficientes.
Dennis
Ahora que lo menciona: en realidad, la entrada más pequeña que requeriría tres iteraciones es 236172; y ese es el único por debajo de 1 millón.
Titus
Puede reducir
xnor
8

05AB1E , 7 bytes

LOΔSPSO

Pruébalo en línea!

Exlpacion

L         # push range [1 ... input]
 O        # sum range
  Δ       # loop until top of stack stops changing
   SP     # product of digits
     SO   # sum of digits
Emigna
fuente
¡Casi solo ASCII! : D
AdmBorkBork
@AdmBorkBork: Sí, no es terriblemente común: P
Emigna
4

Jalea , 8 bytes

RSDPDƲÐL

Pruébalo en línea!

Programa completo (devuelve una matriz singleton que contiene el resultado, pero los corchetes no son visibles en STDOUT).

Erik el Outgolfer
fuente
Esta es la respuesta Jelly más "natural" que he visto hasta ahora. Solo hay 2 caracteres no ASCII
RedClover,
Uh, ¿podemos por favor no tener la discusión por aquí, gracias. : P TNB podría ser un lugar alternativo para discutir esto, si no se hace ruido. ;)
Erik the Outgolfer
4

MATL , 15 13 bytes

En homenaje a la lengua del mes :

:`sV!UpV!Utnq

Pruébalo en línea!

No creo que haya una forma más simple de obtener los dígitos de un número que convertir el número en una cadena V, luego transponerlo !y convertir este vector vertical a uno numérico U.

¡Ahorró 2 bytes gracias al Creador 1 mismo! Olvidé el final implícito, lo que significa que podría eliminar ], y en lugar de comparar el número de elementos 1, simplemente podría disminuir ese valor y usarlo como un booleano directamente.

Entonces, la explicación es la siguiente:

                 % Grab input n implicitly
:                % Range from 1 ... n inclusive
 `               % Do ... while
  s               % sum the vector
   V!U            % Convert the number to digits
      p           % Take the product of these digits
       V!U        % Convert the product into digits
          t       % Duplicate the result
           n      % Count the number of elements
            q     % Decrement the number of elements
                  % Loop until the number of elements is 1
                 % Implicit end

1 ... de MATL, Luis Mendo.

Stewie Griffin
fuente
3

JavaScript (ES6), 60 bytes

f=(n,k=n*++n/2)=>k>9?f(!n,eval([...k+''].join('*+'[+!n]))):k

Pruébalo en línea!

Comentado

f = (                     // f = recursive function taking:
  n,                      //   n = original input
  k = n * ++n / 2         //   k = current value, initialized to sum(i=1..n)(i)
) =>                      //
  k > 9 ?                 // if k has more than 1 digit:
    f(                    //   recursive call to f() with:
      !n,                 //     a logical NOT applied to n
      eval(               //     the result of the expression built by:
        [...k + '']       //       turning k into a list of digits
        .join('*+'[+!n])  //       joining with '*' on even iterations or '+' on odd ones
      )                   //     end of eval()
    )                     //   end of recursive call
  :                       // else:
    k                     //   stop recursion and return the last value

Versión alternativa, 59 bytes (no competitiva)

Una versión no recursiva que solo funciona para n <236172 . (Cubre el rango solicitado pero no califica como un algoritmo genérico válido).

n=>[...'*+*+'].map(o=>n=eval([...n+''].join(o)),n*=++n/2)|n

Pruébalo en línea!

Arnauld
fuente
su versión principal se rompe cuando N> = 77534568790. Funciona cuando N = 7753456879; No estoy seguro exactamente dónde está el punto de interrupción. Por supuesto, esto no importa porque el requisito es solo manejar hasta N = 100,000, por lo que no estoy seguro de por qué escribí esto ...
Ross Presser
1
@RossPresser Como estimación aproximada, diría que funciona bastante bien Number.MAX_SAFE_INTEGER ** 0.5 ~= 94906265.
Arnauld
3

Haskell , 72 71 63 bytes

g=map(read.pure).show
f n=until(<10)(sum.g.product.g)$sum[1..n]

¡Gracias a @BMO por un byte y @nimi por 8 bytes!

Pruébalo en línea!

Angs
fuente
2

Stax , 14 13 10 bytes

ñu┌↕a√äJ²┐

Ejecutar y depurarlo

Fue muy divertido de hacer. Me pregunto si hay una forma más concisa de hacer la comparación al final.

Explicación

|+wE:*E|+c9>                 # Full Program Unpacked
|+                           # Create range and sum it
   wE:*                      # Start loop, digitize number, product of digits
       E|+                   # Digitize number, sum digits
          c9>                # Duplicate, check length is = 1
                             # Otherwise loop back to the 'w' character

-1 bytes gracias a ovs

-3 bytes gracias a Scrooble

Multi
fuente
2

R , 152 130 109 bytes

function(w,x=w*(w+1)/2,y=prod(d(x)),z=sum(d(y)))"if"(z>9,f(,z),z)
d=function(x)x%/%10^(0:max(0,log10(x)))%%10

Pruébalo en línea!

@Giuseppe encontró 21 42 bytes con varias cosas R a las que todavía no estoy acostumbrado, ¡junto con una forma de obtener los dígitos de un número sin forzar la cadena y viceversa, y con menos bytes!

# Old
d=function(x)strtoi(el(strsplit(paste(x),"")))
# New
d=function(x)x%/%10^(0:max(0,log10(x)))%%10

options(scipen=9) se requería para el caso de 9854 para la función anterior, porque la primera etapa del producto termina en 80000, que R imprime como 8e + 05.

ngm
fuente
Ah, ya veo. Notación científica de salida. ¡Buena atrapada!
AdmBorkBork
1
Finalmente conseguí scipen: ¡ Pruébalo en línea ! tenga en cuenta que max(0,log10(x))es porque si x=0, entonces lo log10(0)=-Infque causa un error.
Giuseppe
1

Pyth , 11 bytes

usj*FjGTTsS

Pruébalo aquí!

usj * FjGTTsS - Programa completo. N = La entrada.
          S - Rango. Rendimiento [1, N] ⋂ ℤ.
         s - Suma.
u - Si bien no hay dos iteraciones consecutivas que den el mismo resultado, do (var: G):
   * FjGT - Producto digital.
 sj T: suma digital.
Sr. Xcoder
fuente
1

Carbón , 18 bytes

≔Σ…·¹NθW›θ⁹≔ΣΠθθIθ

Pruébalo en línea! El enlace es a la versión detallada del código. Explicación:

≔Σ…·¹Nθ

Suma los enteros hasta la entrada.

 W›θ⁹≔ΣΠθθ

Si bien el resultado es mayor que 9, tome la suma de dígitos del producto de dígitos.

Iθ

Transmita el resultado a una cadena e imprímalo implícitamente.

Neil
fuente
1

Gaia , 8 bytes

┅⟨Σ₸∨Π⟩°

Pruébalo en línea!

La vieja explicación (antes de corregir un error que es culpa de Gaia IMO: P):

┅⟨ΣΠ⟩ ° - Programa completo. N = La entrada.
┅ - Rango. Empuje [1, N] ⋂ ℤ a la pila.
 ⟨⟩ ° - Si bien no hay dos iteraciones consecutivas que den el mismo resultado, haga lo siguiente:
  Σ - Suma (o suma digital, cuando se aplica a un número entero).
   Π - Producto digital.

Guardado 1 byte gracias a Dennis .

Sr. Xcoder
fuente
┅⟨ΣΠ⟩°Guarda un byte.
Dennis
Esto no funciona para los valores donde la suma digital es 0, como4
Jo King
@JoKing Fixed, gracias por ver eso. Desafortunadamente, en Gaia, tomando los dígitos de los 0resultados []por alguna razón :(
Sr. Xcoder
1

F #, 175 bytes

let d n=seq{for i in(string n).ToCharArray() do yield string i|>uint64}
let c n=
 let mutable r=Seq.sum{1UL..n}
 while r>9UL do r<-d r|>Seq.reduce(fun a x->x*a)|>d|>Seq.sum
 r

Pruébalo en línea!

La única advertencia a la función es que el valor de entrada debe ser de tipo uint64.

Ungolfed es un poco así:

let d n=seq{for i in(string n).ToCharArray() do yield string i|>uint64}

let c n =
 let mutable r = Seq.sum {1UL..n}
 while r > 9UL do
  r<-d r
  |> Seq.reduce(fun a x->x*a)
  |> d
  |> Seq.sum
 r

La función d nconvierte el número nen sus dígitos componentes. Primero se convierte en una cadena, luego obtiene cada carácter en la cadena. Cada carácter debe convertirse de nuevo en una cadena, de lo contrario los caracteres se convertirán a sus valores ASCII en lugar de sus valores "reales".

La c nfunción es la función principal, con nel valor inicial. En esta función res nuestro valor de ejecución. El whilebucle hace lo siguiente:

  • Convierte ren sus dígitos componentes ( d r).
  • Obtenga el producto de todos esos dígitos. Esto utiliza lo Seq.reduceque toma una función con el valor acumulado ( a) y el siguiente valor en la secuencia ( x) y en este caso devuelve el producto. El valor inicial es el primer elemento de la secuencia.
  • Convierta este valor del producto en sus dígitos componentes ( d).
  • Suma los dígitos de antes y asigna esto a r.
Ciaran_McCarthy
fuente
1

Befunge, 136 bytes

101p&::*+2/>:82+%01g*01p82+/:#v_$01gv
X      v_v# #:/+82p10+g10%+82: <p100<
v:g10$ >#<#^                 #<^
>82+/#v_.@
      >101p^

Puedes probarlo aquí .

Si bien no todos los intérpretes tienen un tamaño de celda lo suficientemente grande, funciona con números pequeños para casi cualquier persona. Para un número mayor de nlo que pueda necesitar un intérprete como BefunExec .

Gegell
fuente
1

Gol> <> , 35 33 bytes

1AY:P*2,TYMR*YR+:a(?Bt
:a(qlBaSD$

Pruébalo en línea!

-2 bytes por Jo King.

Uso extenso de funciones y bucles infinitos implícitos.

Programa completo de ejemplo y cómo funciona

1AGIE;GN
2AY:P*2,YlMR*YlR+:a(?B8R!
:a(?BaSD$

<main program>
1AG       Register row 1 as function G
   IE;    Take number input; halt on EOF
      GN  Call G and print the result as number
          Repeat indefinitely

<function G>
2AY            Register row 2 as function Y
   :P*2,       Sum of 1 to n
        Y      Call Y (break into digits)
         lMR*  Product
Y              Call Y
 lR+           Sum (an implicit zero is used)
    :a(?B      Return if the result is less than 10
         8R!   Skip initial 8 commands
               Repeat indefinitely

<function Y>
:a(?B      Return if the top is less than 10
     aSD   Divmod by 10; [... n] => [... n/10 n%10]
        $  Swap top two, so the "div" goes to the top
Bubbler
fuente
33 bytes
Jo King
1

Japt, 16 14 13 bytes

_ì ×ìx}gN®õ x

Intentalo


Explicación

                  :Implicit input of integer U
         ®        :Map
        N         :The array of inputs (which just contains U)
          õ       :  Range [1,U]
            x     :  Reduce by addition
_     }g          :Take the last element of N, run it through the following function and push the result to N
                  : Repeat U times and then return the last element of N
 ì                :  Split to an array of digits
   ×              :  Reduce by multiplication
    ìx            :  Split to an array of digits and reduce by addition
Lanudo
fuente
Genial, intenté resolver esto yo mismo pero no encontré una buena solución, así que es interesante ver la tuya.
Nit
Gracias, @Nit. Sin embargo, debe haber un camino más corto.
Shaggy
@Nit, lo tengo! Aún convencido de que tiene que haber un camino más corto, sin embargo.
Shaggy
0

PHP 7, 89 bytes

for($a=$argn*-~+$argn/2;$a>9;)$a=array_sum(($s=str_split)(array_product($s($a))));echo$a;

Ejecutar como tubería con -ro probarlo en línea .

  • PHP siempre toma la entrada como una cadena, por lo que tengo que usar +para convertir a int para ~que funcione como lo desee.
  • El incremento previo no funcionaría: no importa dónde lo coloque, afectaría a ambos operandos.
  • Pero: no importa si el único dígito tiene lugar antes o después de la iteración (las iteraciones adicionales no cambiarían nada); entonces puedo usar en for()lugar de do ... while().
  • Se requiere PHP 7 o posterior para la asignación en línea del nombre de la función.
    El PHP anterior requiere un byte más: for($s=str_split,$a=...;$a>9;)$a=array_sum($s(...));
    (No asignarlo str_splita una variable desperdiciaría otro byte).
Titus
fuente
0

Perl 6 , 49 bytes

{($_*.succ/2,{[+] ([*] .comb).comb}...9>=*).tail}

Pruébalo en línea!

Sean
fuente
Puede usar en [*](.comb).comblugar de([*] .comb).comb
Brad Gilbert b2gills
0

PowerShell Core , 91101 93 bytes

Function F($a){$o=$a*($a+1)/2;1,2|%{$o=[char[]]"$([char[]]"$o"-join'*'|iex)"-join'+'|iex};$o}

Pruébalo en línea!

Ungolfed un poco ...

Function F ($a)
{
    $o=$a*($a+1)/2;
    1..2 | % {
        $o = [char[]]"$o"-join '*' | iex;
        $o = [char[]]"$o"-join '+' | iex;
    }
    $o | Write-Output
}

Los primeros pasos fueron dividir los enteros en dígitos; esto se hizo dividiendo el entero en una serie de caracteres de cadenas . Luego, inserte el operando y luego evalúe la cadena como un comando. Luego, se trata de hacer el ciclo de suma múltiple hasta que la entrada sea de un dígito.

iexes un alias para el Invoke-Commandque evalúa una cadena pasada a la primera posición de parámetro.

Editar: según lo solicitado por @AdmBorkBork , he agregado un encabezado de función al recuento de bytes. Además, hice un poco de matemática y me di cuenta de que hay un límite superior en el número de iteraciones < log log 10^6 < log 6 < 2, por lo que ahorré otros seis bytes.

Editar x2: @AdmBorkBork encontró una forma más concisa de convertir el entero en una expresión matemática, y luego sugirió conectarlo iex. Esto ahorró 8 bytes. ¡Gracias!

Jeff Freeman
fuente
¡Es bueno ver a otro PowerSheller alrededor! Sin embargo, creo que debe incluir la definición de la función Function F($a){ }en su recuento de bytes. Sin embargo, creo que deberías poder guardar algo usando en [char[]]lugar de -split''-ne'',
AdmBorkBork
[char[]]1234=Ӓ, que no es válido; Podría ser capaz de hacerlo funcionar, pero puede que no sea obvio en este momento. ¡Gracias por la sugerencia!
Jeff Freeman
Lo siento, no estaba claro, [char[]]"$o"y en |iexlugar de eso iex( ).
AdmBorkBork
Este consejo eliminó el 8% de mi código. Increíble. ¡Gracias!
Jeff Freeman
0

Java 8, 129 bytes

n->{long r=1,i=n;for(;i>1;r+=i--);for(;r>9;r=(i+"").chars().map(p->p-48).sum(),i=1)for(int s:(r+"").getBytes())i*=s-48;return r;}

Pruébalo en línea.

Explicación:

n->{            // Method with integer parameter and long return-type
  long r=1,     //  Result-long, starting at 1
       i=n;     //  Temp integer, starting at the input `n`
  for(;i>1;     //  Loop as long as `i` is not 1 yet
      r+=i--);  //   And increase `r` by `i`
  for(;r>9      //  Loop as long as `r` is not a single digit yet
      ;         //    After every iteration:
       r=(i+"").chars().map(p->p-48).sum(),
                //     Set `r` to the sum of digits of `i`
       i=1)     //     And reset `i` to 1
    for(int s:(r+"").getBytes())i*=s-48;
                //    Set `i` to the product of the digits of `r`
  return r;}    //  Return `r` as result
Kevin Cruijssen
fuente
0

Julia 0.6 , 56 bytes

f(n,k=(n+1)n÷2)=k>9?f(0,sum(digits(prod(digits(k))))):k

Pruébalo en línea!

Bastante sencillo: calcule la (n+1)n÷2suma de 1..n, verifique si es un número de un solo dígito ( >9), si no lo es, intente nuevamente con k establecido en la suma de los dígitos del producto de los dígitos de k, de lo contrario devuelva k.

sundar - Restablecer a Monica
fuente