The shortest code to pass all possibilities wins.

In mathematics, the persistence of a number measures how many times a certain operation must be applied to its digits until some certain fixed condition is reached. You can determine the additive persistence of a positive integer by adding the digits of the integer and repeating. You would keep adding the digits of the sum until a single digit number is found. The number of repetitions it took to reach that single digit number is the additive persistence of that number.

Example using 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.

You will be given a sequence of positive integers that you have to calculate the additive persistence of. Each line will contain a different integer to process. Input may be in any standard I/O methods.

For each integer, you must output the integer, followed by a single space, followed by its additive persistence. Each integer processed must be on its own line.

Test Cases

Input Output

99999999999 3
10 1
8 0
19999999999999999999999 4
6234 2
74621 2
39 2
2677889 3
0 0
• Your test cases include some values which are over 2^64, and your spec says that the program only has to handle values up to 2^32. Might be worth clearing that up. – Peter Taylor Mar 25 '11 at 23:40
• @Peter Taylor, forgot to remove those limits. If a program can handle the input I have provided, it shouldn't have an issue with limits. – Kevin Brown Mar 25 '11 at 23:49
• Isn't 999999999999's persistence 2 instead of 3? – Eelvex Mar 26 '11 at 2:13
• @Evelex, that was an incorrect last minute change I guess. Fixed. – Kevin Brown Mar 26 '11 at 21:45
• Several answers here aren't doing output on stdout but rather use J's "interactive" output by returning results after taking command line input. (This includes 2 other J answers and, I'm guessing, the K answer.) Is this considered legit? Because I can shed 18-ish characters if so. – Jesse Millikan Mar 27 '11 at 1:29

K - 29 Chars

Input is a filename passed as an argument, 29 chars not including filename.

0:{5:x,-1+#(+/10_vs)\x}'.:'0:"file"
• 35 -> 31: Remove outside function.
• 31 -> 29: Remove parens.
• -1+# => #1_ – streetster Aug 6 at 11:24

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
• Challenge case:06234 .. result successful challenge :-) – Quixotic Mar 26 '11 at 6:01
• @Debanjan Thanks. Corrected. – fR0DDY Mar 26 '11 at 10:08

p[d]=0
p d=1+(p.show.sum$map((-48+).fromEnum)d) f n=n++' ':shows(p n)"\n" main=interact$(f=<<).lines
• You can save 6 bytes by using read.pure instead of (-48+).fromEnum, try it online! – ბიმო Apr 25 '18 at 15:17

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)
• i think you can remove the space between 9 and err...and – st0le Mar 26 '11 at 8:52
• @st0le:Thanks :-) – Quixotic Mar 28 '11 at 6:17
• and input() instead of int(raw_input()).... – st0le Mar 28 '11 at 6:48
• @st0le:Try this input with that modification:06234. – Quixotic Mar 28 '11 at 7:12

Husk, 10 15 bytes

+5 bytes for horrible I/O requirement

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

Try it online!

Explanation

To support multiple inputs, we need to use m(₁r)¶ (where is the function doing the interesting computation):

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

The function does the following:

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"

bash, 105 chars

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 Hardly any golfing actually involved, but I can't see how to improve it. 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 • You can save 4 bytes by using pure over (:[]) and defining an operator instead of s, try it online! – ბიმო Apr 25 '18 at 15:22 Ruby, 85 Chars puts$<.map{|n|v=n.chop!;c=0;[c+=1,n="#{n.sum-n.size*48}"] while n;[v,c]*' '}*"\n"

I had to borrow the "sum-size*48" idea from Alex, because it's just too neat to miss (in Ruby at least).

Golfscript, 40 chars

n%{.:${;${48-}%{+}*:$,}%.,1>\1?+' '\n}% J - 45 Chars Reads from stdin (,' ',[:":@<:@#+/&.:("."0)^:a:)&><;._2(1!:1)3 • I was trying to use ^:a: myself but I couldn't find some proper documentation... any hints? – Eelvex Mar 26 '11 at 16:12 • The dictionary entry for u^:n has info on its usage but it is a bit dense. ^:a: is like any other call to power but it collects the results and ends when the argument to consecutive calls is the same(converges). – isawdrones Mar 26 '11 at 17:21 • @Eelvex FWIW I discovered a: through the ^:a: trick in the J Reference Card[PDF] – J B Mar 27 '11 at 0:55 • @JB: That's the only reference on ^:a: that I knew :D – Eelvex Mar 27 '11 at 0:59 • @Eelvex Oh. I had the opposite experience then. I discovered the functionality in the dictionary, and used it as some variant of ^:(<'') at first (probably for Kaprekar), until I spotted it in the card, and learned about a: for the occasion. – J B Mar 27 '11 at 10:43 c -- 519 (or 137 if you credit me for the framework...) Rather than solving just this one operation, I decided to produce a framework for solving all persistence problems. #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;}} Only the two lines starting from char*b are unique to this problem. It treats the input as strings, meaning that leading "0"s are not strip before the output stage. The above has had comments, error checking and reporting, and file reading (input must come from the standard input) striped out of: /* 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,"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; } } A little more could be saved if we were willing to leak memory like a sieve. Likewise by #defineing return and the like, but at this point I don't care to make it any uglier. J, 74 chars i=:<;._2(1!:1)3 i&((],' ',":@(0 i.~9<[:".([:":[:+/"."0)^:(i.9)))@>@{~)i.#i Edits • (86 → 83) Some Caps [: to Ats @ • (83 → 79) Unneeded parentheses • (79 → 75) Changing 0". to ". simplifies things • (75 → 74) Better Cutting E.g 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 • Output is formatted wrong for multiple inputs. See "single space" – Jesse Millikan Mar 27 '11 at 1:54 • @Jesse: I see nothing wrong. Could you write an example please? – Eelvex Mar 27 '11 at 2:09 • I have no idea, I'm seeing things I guess. – Jesse Millikan Mar 27 '11 at 2:18 I think this is about the best I can come up with. 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}"}
• Actually, chop! instead of chomp! gives me a one character savings. 97 chars. – Alex Bartlow Mar 26 '11 at 2:20
• Just did some more golfing at it - 91 chars. – Alex Bartlow Mar 26 '11 at 2:26

PARI/GP 101 Chars

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)))

Unfortunately, there's no input function for GP, so i guess this lacks the IO part. :( Fixed: Thanks Eelvex! :)

• Sure there is: input() :) – Eelvex Mar 26 '11 at 5:23
• @Eelvex, done. :) – st0le Mar 26 '11 at 5:53

Javascript - 95

EDIT: Whoops does'nt do the multi-lines

• Just noticed this doesn't output it correctly. – Kevin Brown Mar 30 '11 at 19:04

f=:[:+/"."0&":

Try it online!

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;}

Try it online!

There's probable potential to golf it further, but I'll look into that in the future, but for now, I'm pretty happy with this little result.

• – Jonathan Frech Apr 15 '18 at 18:46

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)))

proc P {v n\ 0} {set V $v while \$v>9 {set v [expr [join [split $v ""] +]] incr n} puts$V\ $n} Try it online! • Because the next newest answer is a full 6 years old, which i think is before TIO existed – fəˈnɛtɪk Apr 15 '18 at 0:35 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. Try it online! PHP, 72+1 bytes +1 for -R flag. for($i=0,$a=$argn;$a>9;$i++)$a=array_sum(str_split($a));echo"$argn$i
";

Run as pipe with -R.

• running PHP as pipe will execute the code once for every input line
• but it does not unset variables inbetween; so $i must be initialized. (Also, it would print nothing instead of 0 for single digits without the initialization.) 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

Try it online!

Should be saved to a script called a and placed in the system's PATH, as it calls itself recursively. Takes input from command line, like a 1999. Returns by exit code.

TIO has some limitations on what you can do with a script, so there's some boilerplate code to make this run in the header.

Prints an error to stderr for input larger than bash integers can handle, but since the actual computation is done with strings, it still gives the right result anyway.