¡Dobla el número entero para ahorrar espacio!


20

El loco matemático posee una amplia colección de números y, por lo tanto, el espacio que le queda es bastante limitado. Para salvar a algunos, debe doblar sus enteros, pero desafortunadamente es muy vago. Su tarea, si desea ayudarlo, es crear una función / programa que pliegue un entero positivo dado para nuestro número loco.

¿Cómo doblar un número entero?

Si es divisible por la suma de sus dígitos, divídalo por la suma de sus dígitos. Si no cumple con ese requisito, tome su resto cuando se divida por la suma de sus dígitos. Repita el proceso hasta que llegue el resultado 1. El número entero plegado es el número de operaciones que tuvo que realizar. Tomemos un ejemplo (digamos 1782):

  1. Obtener la suma de sus dígitos: 1 + 7 + 8 + 2 = 18. 1782es divisible por 18, entonces el siguiente número es 1782 / 18 = 99.

  2. 99No es divisible por 9 + 9 = 18, por lo tanto, tomamos el resto: 99 % 18 = 9.

  3. 9obviamente es divisible por 9, entonces lo dividimos y obtenemos 1.

El resultado es 3, porque se necesitaron 3 operaciones para llegar 1.

Reglas y especificaciones

  • Algunos enteros pueden tener la suma de dígitos igual a 1, como 10o 100. Su programa no necesita manejar tales casos. Eso significa que se le garantizará que el entero dado como entrada no tiene la suma de dígitos igual a 1, y ninguna operación con el entero dado dará como resultado un número cuya suma de dígitos es 1(a excepción de 1sí mismo, que es el " objetivo"). Por ejemplo, nunca recibirá 10ni 20como entrada.

  • La entrada será un número entero positivo mayor que 1.

  • Se aplican las lagunas predeterminadas .

  • Puede tomar entrada y proporcionar salida por cualquier medio estándar .


Casos de prueba

Entrada -> Salida

2 -> 1
5 -> 1
9 -> 1
18 -> 2
72 -> 2
152790 -> 2
152 -> 3
666 -> 3
777 -> 3
2010 -> 3
898786854 -> 4

Aquí hay un programa que le permite visualizar el proceso y probar más casos de prueba.


Este es el , por lo que gana el código más corto en cada idioma (puntuado en bytes).


Inspirado por este desafío , aunque al principio no parezca relacionado.
Sr. Xcoder

3
Esto funcionará como una solución provisional, pero a largo plazo, el matemático realmente debería considerar comprar uno de los hoteles de Hilbert . Siempre puedes encontrar alguna habitación sin usar en uno de esos.
Ray

Si bien 8987868546es una entrada válida, romperá su herramienta de prueba, y también muchas (si no todas) las respuestas ...
Mischa

@MischaBehrend Su ejemplo no es una entrada válida. Creo que copiaste mal mi último caso de prueba. La entrada válida era 898786854, no 8987868546(ha agregado un 6al final)
Sr. Xcoder

NVM ... debe leer la toda primera regla ... dejar esto aquí para que sepa por qué, pensé que es válido: no fue un error ... lo cambié intencional para poner a prueba estos scripts ... y la lectura de las normas de TI Es una entrada válida. La suma de todos los dígitos 8987868546 no es 1 (se cumple la Regla 1 ) y 8987868546es un entero positivo mayor que 1 ( Se cumple la Regla 2 ).
Mischa

Respuestas:


6

05AB1E , 13 12 bytes

[¼DSO‰0Kθ©#®

Pruébalo en línea!

Explicación

[               # start loop
 ¼              # increment counter
  D             # duplicate current value
   SO           # sum the digits in the copy
     ‰          # divmod the current value by its digit-sum
      0K        # remove 0 from the resulting list
        θ       # pop the last element
         ©      # store a copy in register
          #     # if the current value is 1, break
           ®    # push the copy from register
                # implicitly output counter


5

Haskell, 85 78 bytes

f 1=0
f n|r<1=1+f(n`div`s)|1<2=1+f r where s=sum(read.pure<$>show n);r=n`rem`s

Guardado 7 bytes gracias a Bruce Forte.

Pruébalo en línea.


Ahorre algunos bytes más usando divMody soltando where: ¡ Pruébelo en línea!
Laikoni

@Laikoni Wow, ¡eso es una gran mejora! Por favor publíquelo como una respuesta diferente; Es lo suficientemente diferente al mío. Por cierto: estaba buscando un truco para deshacerme de él where. Usaré esto en el futuro. :)
Cristian Lupascu

sum[read[d]|d<-show n]guarda un byte
nimi

5

JavaScript (ES6), 66 58 51 49 bytes

Toma la entrada como un entero. Las devoluciones falsede 0o 1y lanza un error de desbordamiento cuando se encuentra con cualquier número cuyos dígitos suman 1.

f=n=>n>1&&f(n%(x=eval([...""+n].join`+`))||n/x)+1
  • 8 bytes guardados con la ayuda de Justin .

Pruébalo

o.innerText=(

f=n=>n>1&&f(n%(x=eval([...""+n].join`+`))||n/x)+1

)(i.value=898786854);oninput=_=>o.innerText=f(+i.value)
<input id=i type=number><pre id=o>


1
¿Podría guardar algunos bytes sumando los dígitos usando eval(array.join`+`)?
Justin Mariner

De hecho, podría, @JustinMariner: ¡me engañaste! Gracias :)
Shaggy

4

Casco , 12 bytes

←€1¡Ṡ§|÷%oΣd

Pruébalo en línea!

Explicación

←€1¡Ṡ§|÷%oΣd  Implicit input, e.g. n=1782
    Ṡ§|÷%oΣd  This part defines the transformation.
         oΣ   Sum of
           d  digits: s=18
    Ṡ   %     n mod s: 0
     §|       or (take this branch if last result was 0)
       ÷      n divided by s: 99
   ¡          Iterate the transformation: [1782,99,9,1,1,1,...
 €1           Index of 1 (1-based): 4
←             Decrement: 3
              Print implicitly.



2

Retina , 100 bytes

$
;
{`(.+);
$1$*1;$&
(?<=;.*)\d(?=.*;)
$*
.*;1;(.*)
$.1
r`(1)*(\3)*;(1+);
$#1;$#2;1
0;(.*);|;.*;
$1;

Pruébalo en línea! Link solo incluye casos de prueba más pequeños, ya que los más grandes tardan demasiado.


2

Mathematica, 73 bytes

(t=#;For[r=0,t>1,r++,If[(s=Mod[t,g=Tr@IntegerDigits@t])<1,t=t/g,t=s]];r)&

Se ==0puede reemplazar con <1?
Sr. Xcoder

@ Mr.Xcoder sí, por supuesto! Hice una versión del clasificador ...
J42161217

2

PHP, 68 + 1 bytes

salida unaria:

for($n=$argn;$n>1;$n=$n%($s=array_sum(str_split($n)))?:$n/$s)echo 1;

salida decimal, 73 + 1 bytes:

for($n=$argn;$n>1;$i++)$n=$n%($s=array_sum(str_split($n)))?:$n/$s;echo$i;

Ejecutar como tubería -nRo probarlo en línea .


El operador de Elvis requiere PHP 5.3 o posterior. Para PHP más antiguo, reemplace ?:con ?$n%$s:(+5 bytes).


2

Ruby, 46 bytes

f=->n{s=n.digits.sum;n<2?0:1+f[n%s<1?n/s:n%s]}

2

Haskell , 94 93 89 88 bytes

Esto se siente muy largo ...

length.fst.span(/=1).iterate g
g x|(d,m)<-x`divMod`sum[read[d]|d<-show x]=last$m:[d|m<1]

Pruébalo en línea!

¡Gracias @Laikoni y @nimi por jugar 1 byte cada uno!





1

Perl, 71 bytes, 64 bytes, 63 bytes

-pl

$c=0;while($_>1){$s=0;$s+=$_ for/./g;$_=$_%$s?$_%$s:$_/$s;++$c};$_=$c

Pruébalo en línea

EDITAR: guardado 7 bytes, gracias al comentario de Xcali

-p

while($_>1){$s=0;$s+=$_ for/./g;$_=$_%$s?$_%$s:$_/$s;++$c}$_=$c

EDITAR: desde 5.14 sustitución no destructiva s /// r

-pl

while($_>1){$s=eval s/\B/+/gr;$_=$_%$s?$_%$s:$_/$s;++$c}$_=$c

¿Se -plsupone que la parte superior es una bandera de línea de comandos?
Erik the Outgolfer

sí, son opciones de Perl
Nahuel Fouilleul

Deberías contar la -plbandera de acuerdo con esta publicación .
Erik the Outgolfer

Conté 69 bytes +2 para las opciones de pl, ¿es correcto?
Nahuel Fouilleul

Puedes jugar golf un poco más abajo. $cNo necesita ser inicializado. Comenzará en el undefque es 0. El punto y coma después del cierre puede irse. Además, no necesitas -l. No es necesario tomar múltiples entradas en una ejecución.
Xcali

1

Dyalog APL, 36 bytes

{x←+/⍎¨⍕⍵⋄1=⍵:00=x|⍵:1+∇⍵÷x1+∇x|⍵}

Pruébalo en línea!

¿Cómo?

{
   x←+/⍎¨⍕⍵       x = digit sum
   1=⍵:0          if arg = 1: bye
   0=x|⍵:1+∇⍵÷x   if arg divisible by x: recurse with arg/x
   1+∇x|⍵         recurse with arg mod x
}

1

Gaia , 13 bytes

-@{:ΣZ¤∨)‡}°\

Pruébalo en línea!

Explicación

-              Push -1 (this will be the counter)
 @             Push input (the starting number)
  {:ΣZ¤∨)‡}°   Repeat this block until the results of 2 consecutive runs are the same:
   :            Copy the number
    Σ           Digital sum
     Z          Divmod number by digital sum
      ¤         Swap
       ∨        Logical or: left-most non-zero out of (number mod sum, number div sum)
        )‡      Increment the counter
            \  Delete the final 1, implicitly print the counter

1

Matlab, 150 bytes

function[d]=X(x) 
d=0;while ~strcmp(x,'1')z='sum(str2num(x(:)))';a=eval(['rem(',x,',',z,')']);y=num2str(a*(a>0)+eval([x,'/',z])*(a==0));x=y;d=d+1;end

Las entradas deben darse a la función como una cadena, como X ('152').

La función funciona mientras se repite e incrementa d. La x=y;línea era necesaria para evitar un error de Matlab al intentar leer y sobrescribir un valor variable al mismo tiempo, aparentemente, que era nuevo para mí.

Sin golf:

function[d]=X(x) 
d=0;
while ~strcmp(x,'1')
    z='sum(str2num(x(:)))';
    a=eval(['rem(',x,',',z,')']);
    y=num2str(a*(a>0)+eval([x,'/',z])*(a==0));
    x=y;
    d=d+1;
end


Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.