Persistencia Aditiva

20

El código más corto para pasar todas las posibilidades gana.

En matemáticas, la persistencia de un número mide cuántas veces se debe aplicar una determinada operación a sus dígitos hasta que se alcanza cierta condición fija. Puede determinar la persistencia aditiva de un entero positivo sumando los dígitos del entero y repitiendo. Seguiría sumando los dígitos de la suma hasta que se encuentre un número de un solo dígito. El número de repeticiones que tomó para alcanzar ese número de un solo dígito es la persistencia aditiva de ese número.

Ejemplo usando 84523:

84523
8 + 4 + 5 + 2 + 3 = 22
2 + 2 = 4

It took two repetitions to find the single digit number.
So the additive persistence of 84523 is 2.

Se le dará una secuencia de enteros positivos de los que deberá calcular la persistencia aditiva. Cada línea contendrá un número entero diferente para procesar. La entrada puede estar en cualquier método de E / S estándar .

Para cada número entero, debe generar el número entero, seguido de un solo espacio, seguido de su persistencia aditiva. Cada entero procesado debe estar en su propia línea.

Casos de prueba


De entrada y salida

99999999999 3
10 1
8 0
19999999999999999999999 4
6234 2
74621 2
39 2
2677889 3
0 0
Kevin Brown
fuente
1
Sus casos de prueba incluyen algunos valores que están por encima de 2 ^ 64, y su especificación dice que el programa solo tiene que manejar valores de hasta 2 ^ 32. Puede valer la pena aclarar eso.
Peter Taylor
@ Peter Taylor, olvidé eliminar esos límites. Si un programa puede manejar la entrada que he proporcionado, no debería tener un problema con los límites.
Kevin Brown
55
¿No es la persistencia de 999999999999 2 en lugar de 3?
Eelvex
@Evelex, supongo que fue un cambio incorrecto de última hora. Fijo.
Kevin Brown
Varias respuestas aquí no están dando salida en stdout sino que usan la salida "interactiva" de J devolviendo resultados después de tomar la entrada de la línea de comandos. (Esto incluye otras 2 respuestas J y, supongo, la respuesta K). ¿Se considera esto legítimo? Porque puedo arrojar caracteres de 18 ish si es así.
Jesse Millikan

Respuestas:

6

K - 29 caracteres

La entrada es un nombre de archivo pasado como argumento, 29 caracteres sin incluir el nombre de archivo.

`0:{5:x,-1+#(+/10_vs)\x}'.:'0:"file"
  • 35 -> 31: Eliminar la función exterior.
  • 31 -> 29: Eliminar parens.
isawdrones
fuente
1
-1+#=>#1_
streetter
4

Python 84 Chars

while 1:
 m=n=int(raw_input());c=0
 while n>9:c+=1;n=sum(map(int,str(n)))
 print m,c
fR0DDY
fuente
Caso de desafío: 06234.. resultado desafío exitoso :-)
Quixotic
@Debanjan Gracias. Corregido
fR0DDY
4

Haskell, 100 personajes

p[d]=0
p d=1+(p.show.sum$map((-48+).fromEnum)d)
f n=n++' ':shows(p n)"\n"
main=interact$(f=<<).lines
MtnViewMark
fuente
Puede guardar 6 bytes usando en read.purelugar de (-48+).fromEnum, ¡ pruébelo en línea!
ბიმო
4

Python (93 bytes)

f=lambda n,c:n>9and f(sum(map(int,str(n))),c+1)or c
while 1:n=int(raw_input());print n,f(n,0)
Quijotesco
fuente
Creo que puede eliminar el espacio entre 9y err ...and
st0le
@ st0le: Gracias :-)
Quixotic
y en input()lugar de int(raw_input())....
st0le
@ st0le: Pruebe esta entrada con esa modificación: 06234.
Quixotic
4

Casco , 10 15 bytes

+5 bytes para requisitos de E / S horribles

m(wΓ·,LU¡oΣdr)¶

Pruébalo en línea!

Explicación

Para admitir múltiples entradas, necesitamos usar m(₁r)¶(¿dónde está la función haciendo el cálculo interesante?):

m(₁r)¶  -- expects newline-separated inputs: "x₁␤x₂␤…␤xₙ"
     ¶  -- split on newlines: ["x₁","x₂",…,"xₙ"]
m(  )   -- map over each string
 ( r)   -- | read integer: [x₁,x₂,…,xₙ]
 (₁ )   -- | apply the function described below

La función hace lo siguiente:

wΓ·,LU¡(Σd)  -- input is an integer, eg: 1234
      ¡(  )  -- iterate the following forever and collect results in list:
       ( d)  -- | digits: [1,2,3,4]
       (Σ )  -- | sum: 10
             -- : [1234,10,1,1,1,…
     U       -- keep longest prefix until repetition: [1234,10,1]
 Γ           -- pattern match (x = first element (1234), xs = tail ([10,1])) with:
  · L        -- | length of xs: 2
   ,         -- | construct tuple: (1234,2)
w            -- join with space: "1234 2"
ბიმო
fuente
3

bash, 105 caracteres

while read x
do
for((i=0,z=x;x>9;i++))do
for((y=0;x>0;y+=x%10,x/=10))do :
done
x=$y
done
echo $z $i
done

Casi ningún golf realmente estuvo involucrado, pero no veo cómo mejorarlo.

Peter Taylor
fuente
3

Haskell - 114

s t n|n>9=s(t+1)$sum$map(read.(:[]))$show n|1>0=show t
f n=show n++" "++s 0n++"\n"
main=interact$(f.read=<<).lines
Joey Adams
fuente
Puede guardar 4 bytes mediante el uso de puremás (:[])y la definición de un operador en lugar de s, probarlo en línea!
ბიმო
3

Ruby, 85 caracteres

puts $<.map{|n|v=n.chop!;c=0;[c+=1,n="#{n.sum-n.size*48}"] while n[1];[v,c]*' '}*"\n"

Tuve que tomar prestada la idea del "tamaño de la suma * 48" de Alex, porque es demasiado buena para perderla (al menos en Ruby).

Ezran
fuente
3

Golfscript, 40 caracteres

n%{.:${;${48-}%{+}*`:$,}%.,1>\1?+' '\n}%

fuente
3

J - 45 caracteres

Lecturas de stdin

(,' ',[:":@<:@#+/&.:("."0)^:a:)&><;._2(1!:1)3
isawdrones
fuente
Estaba tratando de ^:a:usarme pero no pude encontrar la documentación adecuada ... ¿alguna pista?
Eelvex
1
La entrada del diccionario para u ^: n tiene información sobre su uso, pero es un poco densa. ^: a: es como cualquier otra llamada al poder, pero recopila los resultados y finaliza cuando el argumento de las llamadas consecutivas es el mismo (converge).
isawdrones
1
@Eelvex FWIW descubrí a a:través del ^:a:truco en la J Reference Card [PDF]
JB
@JB: Esa es la única referencia ^:a:que conocía: D
Eelvex
@Eelvex Oh. Tuve la experiencia opuesta entonces. Descubrí la funcionalidad en el diccionario, y la usé como una variante ^:(<'')al principio (probablemente para Kaprekar), hasta que la vi en la tarjeta y aprendí sobre a:la ocasión.
JB
3

c - 519

(o 137 si me acreditas por el marco ...)

En lugar de resolver solo esta operación, decidí producir un marco para resolver todos los problemas de persistencia .

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef char*(*O)(char*);
char*b(char*s){long long int v=0,i,l=0;char*t=0;l=strlen(s);t=malloc(l+2);
for(i=0;i<l;i++)v+=s[i]-'0';snprintf(t,l+2,"%lld",v);return t;}
int a(char**s,O o){int r;char*n;n=o(*s);r=!strcmp(*s,n);free(*s);
*s=n;return r;}
int main(int c, char**v){size_t l, m=0;char *d,*n=0;O o=b;FILE*f=stdin;
while(((l=getline(&n,&m,f))>1)&&!feof(f)){int i=0;n=strsep(&n,"\n");
d=strdup(n);while(!a(&n,o))i++;printf("%s %d\n",d,i);free(d);free(n);n=0;m=0;}}

Solo las dos líneas que comienzan char*bson exclusivas de este problema.

Trata la entrada como cadenas, lo que significa que los "0" iniciales no son bandas antes de la etapa de salida.

Lo anterior ha tenido comentarios, verificación de errores e informes, y lectura de archivos (la entrada debe provenir de la entrada estándar) eliminada de:

/* persistence.c
 *
 * A general framework for finding the "persistence" of input strings
 * on opperations.
 *
 * Persistence is defined as the number of times we must apply
 *
 *    value_n+1 <-- Opperation(value_n)
 *
 * before we first reach a fixed point.
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../getline.h"

/* A function pointer type for operations */
typedef char*(op_func)(char*);
typedef op_func* op_ptr;
/* Op functions must
 * + Accept the signature above
 * + return a point to a newly allocated buffer containing the updated str
 */

char* addop(char*s){
  int i,l=0;
  long long int v=0;
  char *t=NULL;
  /* protect against bad input */
  if (NULL==s) return s;
  /* allocate the new buffer */
  l = strlen(s);
  t = malloc(l+2);
  if (NULL==t) return t;
  /* walk the characters of the original adding as we go */
  for (i=0; i<l; i++) v += s[i]-'0';
  //fprintf(stderr,"   '%s' (%d) yields %lld\n",s,l,v);
  snprintf(t,l+2,"%lld",v);
  //fprintf(stderr,"   %lld is converted to '%s'\n",v,t);
  return t;
}

/* Apply op(str), return true if the argument is a fixed point fo
 * falsse otherwise,
 */ 
int apply(char**str, op_ptr op){ 
  int r;
  char*nstr;
  /* protect against bad input */
  if ( NULL==op ) exit(1); 
  if ( NULL==*str ) exit(4); 
  /* apply */
  nstr = op(*str); 
  /* test for bad output */
  if ( NULL==nstr ) exit(2); 
  r = !strcmp(*str,nstr); 
  /* free previous buffer, and reasign the new one */
  free(*str); 
  *str = nstr; 
  return r; 
}

int main(int argc, char**argv){
  size_t len, llen=0;
  char *c,*line=NULL;
  op_ptr op=addop;
  FILE *f=stdin;
  if (argc > 1) f = fopen(argv[1],"r");
  while( ((len=getline(&line,&llen,f))>1) && line!=NULL && !feof(f) ){
    int i=0;
    line=strsep(&line,"\n"); // Strip the ending newline
    /* keep a copy for later */
    c = strdup(line);
    /* count necessary applications */
    while(!apply(&line,op)) i++;
    printf("%s %d\n",c,i);
    /* memory management */
    free(c);
    free(line);
    line=NULL;
    llen=0;
  }
}

Se podría ahorrar un poco más si estuviéramos dispuestos a perder memoria como un tamiz. Del mismo modo, mediante el #defineretorno y similares, pero en este punto no me importa hacer que sea más feo.

dmckee
fuente
273 bytes
ceilingcat
2

J, 74 caracteres

i=:<;._2(1!:1)3
i&((],' ',":@(0 i.~9<[:".([:":[:+/"."0)^:(i.9)))@>@{~)i.#i

Ediciones

  • (86 → 83) Algunos topes [:a Ats@
  • (83 → 79) Paréntesis innecesarios
  • (79 → 75) Cambiar 0".a ".simplifica las cosas
  • (75 → 74) Mejor corte

P.ej

i=:<;._2(1!:1)3
74621
39
2677889
0
i&((],' ',":@(0 i.~9<[:".([:":[:+/"."0)^:(i.9)))@>@{~)i.#i
74621 2  
39 2     
2677889 3
0 0  
Eelvex
fuente
La salida tiene un formato incorrecto para múltiples entradas. Ver "espacio único"
Jesse Millikan
@Jesse: No veo nada malo. ¿Podría escribir un ejemplo por favor?
Eelvex
No tengo idea, estoy viendo cosas, supongo.
Jesse Millikan
1

Creo que esto es lo mejor que se me ocurre.

Ruby 101 Chars

f=->(n){n.sum-n.size*48}
$<.each{|l|i=0;i+=1 while(i+=1;n=f[(n||l.chop!).to_s])>10
puts "#{l} #{i}"}
Alex Bartlow
fuente
En realidad, ¡picar! en lugar de chomp! Me da un ahorro de un personaje. 97 caracteres.
Alex Bartlow
Acabo de jugar un poco más al golf: 91 caracteres.
Alex Bartlow
1

Caracteres PARI / GP 101

s(n)=r=0;while(n>0,r+=n%10;n\=10);r
f(n)=c=0;while(n>9,c++;n=s(n));c
while(n=input(),print(n," ",f(n)))

Desafortunadamente, no hay una función de entrada para GP, así que supongo que esto carece de la parte IO. :( Corregido: ¡Gracias Eelvex! :)

st0le
fuente
Claro que lo hay: input():)
Eelvex
@Eelvex, hecho. :)
st0le
1

Javascript - 95

i=prompt();while(i>9){i=''+i;t=0;for(j=0;j<i.length;j++)t+=parseInt(i.charAt(j));i=t;}alert(t);

EDITAR: Whoops no hace las líneas múltiples

t123
fuente
1
Acabo de notar que esto no lo genera correctamente.
Kevin Brown
1

J 78

f=:[:+/"."0&":
r=:>:@$:@f`0:@.(=f)
(4(1!:2)~LF,~[:":@([,r)".@,&'x');._2(1!:1)3

Solución recursiva. Lecturas de stdin. Escribe en stdout , así que déjame un poco de holgura: se necesitan 18 caracteres adicionales.

Jesse Millikan
fuente
1

Perl - 77 caracteres

sub'_{split//,shift;@_<2?0:1+_(eval join'+',@_)}chop,print$_,$",(_$_),$/for<>
jho
fuente
1

JavaScript , 57 47 bytes

-10 bytes gracias a @ l4m2!

f=(s,c=0)=>s>9?f(eval([...s+""].join`+`),++c):c

Pruébalo en línea!

Oliver
fuente
f=(s,c=0)=>s>9?f([...s+""].reduce((x,y)=>x*1+y*1),++c):c
l4m2
f=(s,c=0)=>s>9?f([...s+""].reduce((x,y)=>x- -y),++c):c
l4m2
1
f=(s,c=0)=>s>9?f(eval([...s+""].join`+`)),++c):c
l4m2
@ l4m2 ¡Gracias! s>9y evalfueron grandes ideas. Creo que tenía un par extra allí, por lo que me salvó un total de 10 bytes :-)
Oliver
Tenga en cuenta la estricta E / S;)
Shaggy
1

05AB1E , 13 bytes

ε.µΔSO¼}¾}<ø»

Entrada como una lista de enteros.

Pruébalo en línea.

Explicación:

ε     # Map each integer in the (implicit) input to:
    #  Reset the counter variable to 0
 Δ    #  Loop until the integer no longer changes:
  S   #   Convert it to a list of digits
   O  #   And take the sum of those
  ¼   #   Increase the counter variable by 1
    #  After the inner loop: Push the counter variable
}<    # After the map: decrease each value by 1
  ø   # Zip/transpose it with the (implicit) input to create a paired list
   »  # Join each pair by a space, and then each string by newlines
      # (after which the result is output implicitly)
Kevin Cruijssen
fuente
1

MathGolf , 11 bytes

hÅ_Σ]▀£(k ?

Pruébalo en línea!

Increíblemente ineficiente, pero eso no nos importa. Básicamente, usando el hecho de que la persistencia aditiva de un número es menor o igual que el número mismo.

Utiliza el hecho de que la persistencia aditiva es menor o igual que el número de dígitos del número. Pasa todos los casos de prueba con facilidad ahora.

El formato de entrada, aunque no es óptimo para algunos idiomas, es en realidad el método estándar de tomar múltiples casos de prueba como entrada en MathGolf. Cada línea de la entrada se procesa como su propia ejecución del programa, y ​​la salida está separada por una nueva línea nueva para cada ejecución.

Explicación (usando n = 6234)

h             push length of number without popping (6234, 4)
 Å            loop 4 times using next 2 operators
  _           duplicate TOS
   Σ          get the digit sum
    ]         wrap stack in array
              this gives the array [6234, 15, 6, 6, 6]
     ▀        unique elements of string/list ([6234, 15, 6])
      £       length of array/string with pop (3)
       (      decrement (2)
        k ?   push input, space, and rotate top 3 elements to produce output (6234 2)
maxb
fuente
1

K (ngn / k) , 16 bytes

Solución:

{x,#1_(+/10\)\x} 

Pruébalo en línea!

Explicación:

{x,#1_(+/10\)\x} / the solution
{              } / lambda taking implicit x
      (     )\x  / iterate until convergence
         10\     / split into base-10 (123 => 1 2 3)
       +/        / sum
    1_           / drop first result (iterate returns input as first result)
   #             / count length of result
 x,              / prepend x (original input)
callejero
fuente
1

Stax , 8 11 bytes

ªwæMε∞ö?îm⌐

Ejecutar y depurarlo

+3 bytes gracias a @Khuldraeseth (la primera respuesta no tuvo salida compatible)

recursivo
fuente
1
Llegué a la misma solución, pero con ien lugar de u. Cumpliendo con las especificaciones draconianas de IO, esto se convierte en 11 bytes .
Khuldraeseth na'Barya
Ups Supongo que no leí los requisitos de IO muy bien. Actualizaré mi respuesta.
recursivo el
0

scala 173:

def s(n:BigInt):BigInt=if(n<=9)n else n%10+s(n/10)
def d(n:BigInt):Int=if(n<10)0 else 1+d(s(n))
Iterator.continually(readInt).takeWhile(_>0).foreach(i=>println(i+" "+d(i)))
usuario desconocido
fuente
0

Java (OpenJDK 8) , 79 bytes

a->{int d=0;while(a/10>0){int c=0;d++;while(a>0){c+=a%10;a/=10;}a=c;}return d;}

Pruébalo en línea!

Hay un potencial probable para seguir jugando al golf, pero lo investigaré en el futuro, pero por ahora, estoy bastante contento con este pequeño resultado.

X1M4L
fuente
1
70 bytes .
Jonathan Frech
Basándose en @JonathanFrech 67 bytes
ceilingcat
0

Python 3 , 82 bytes

while 1:f=lambda n:n//10and 1+f(sum(map(int,str(n))));i=input();print(i,f(int(i)))
PieCot
fuente
0

Tcl , 95 bytes

proc P {v n\ 0} {set V $v
while \$v>9 {set v [expr [join [split $v ""] +]]
incr n}
puts $V\ $n}

Pruébalo en línea!

sergiol
fuente
3
Porque la siguiente respuesta más reciente es un total de 6 años, que creo que es antes de que existiera TIO
fəˈnɛtɪk
0

Japt , 28 bytes

Ë+S+(@D=X©A<D©ì x ªD D<AÃa÷
Ë                            // Map over the inputs and return each, followed by
 +S+                         // a space, followed by the number's persistence.
      D=     ©ì x            // To find it, fold the number up
        X©A<D     ªD         // if we can (handles unfoldable cases),
    (@               D<AÃa   // until it can't be folded up any further.
                          ÷ // Then, join everything up with newlines.

Pruébalo en línea!

Liendre
fuente
0

PHP, 72 + 1 bytes

+1 para -Rbandera.

for($i=0,$a=$argn;$a>9;$i++)$a=array_sum(str_split($a));echo"$argn $i
";

Corre como tubería con -R .

  • ejecutar PHP como pipe ejecutará el código una vez para cada línea de entrada
  • pero no desarma las variables intermedias; entonces $idebe ser inicializado.
    (Además, no imprimiría nada en lugar de 0dígitos únicos sin la inicialización).
Titus
fuente
0

Bash + coreutils, 83 bytes

[ $1 -le 9 ]&&exit $2
let x=$2+1
for z in `fold -w1<<<$1`
do let y+=$z
done
a $y $x

Pruébalo en línea!

Debe guardarse en un script llamado ay colocado en el sistemaPATH , como se llama a sí mismo de forma recursiva. Toma información de la línea de comando, como a 1999. Devoluciones por código de salida.

TIO tiene algunas limitaciones sobre lo que puede hacer con un script, por lo que hay un código repetitivo para que esto se ejecute en el encabezado.

Imprime un error para stderruna entrada más grande de lo que pueden manejar los enteros bash, pero dado que el cálculo real se realiza con cadenas, de todos modos sigue dando el resultado correcto.

Chris
fuente