Digitangular numbers

A triangular number is a number that can be expressed as the sum of consecutive positive integers, starting at 1. They can also be expressed with the formula n(n + 1) / 2, where n is some positive integer.

A number's digitangular counterpart is calculated in the following way:

1. Split a number into an array of its digits e.g. 613 => [6 1 3]
2. For each number in the array, calculate the nth triangular number; [6 1 3] => [21 1 6]
3. Sum the resultant array; [21 1 6] => 28

Your task is, given an integer n, repeatedly calculate n's digitangular counterpart, until the result is equal to 1, then output all values that were calculated. You may output the values in any order, and with an optional inclusion of the original number at the start of the array. This is a so the shortest code wins.

Test cases

23 => 9 45 25 18 37 34 16 22 6 21 4 10 1
72 => 31 7 28 39 51 16 22 6 21 4 10 1
55 => 30 6 21 4 10 1
78 => 64 31 7 28 39 51 16 22 6 21 4 10 1
613 => 28 39 51 16 22 6 21 4 10 1
8392 => 90 45 25 18 37 34 16 22 6 21 4 10 1
11111 => 5 15 16 22 6 21 4 10 1
8592025 => 117 30 6 21 4 10 1
999999999 => 405 25 18 37 34 16 22 6 21 4 10 1

• May we include the original number as first in the resultant array? Nov 21, 2017 at 23:28
• How do we know it always goes down to 1? Nov 21, 2017 at 23:50
• Let's suppose that a number is larger than 141 and has n digits. The maximum value its digitangular counterpart can have is 45n, so digi-△(x) ≤ 45n < 45(1+log_10(x)), and for x > 141, we have 45(1+log_10(x)) < x, hence digi-△(x) ≤ x-1 for x > 141, and once we pass the 141 limit, well, we brute force prove via programs. Nov 22, 2017 at 0:02
• Can I have trailing 1's at the end of my output? Nov 22, 2017 at 12:10
• Related: Digitangular numbers, seeking alternative proofs that this sequence goes to 1 eventually. Nov 22, 2017 at 12:33

Husk, 6 bytes

U¡(ṁΣd


Try it online!

Explanation

U¡(ṁΣd
¡(       Iterate the following function on the input:
d       Split the number into digits
ṁΣ        Map each digit to its triangular number, then sum the results
U         Take the results of iteration until before the first repeated one


05AB1E, 6 5 bytes

Δ=SLO


Try it online! Edit: Saved 1 byte thanks to @Emigna. Explanation:

Δ       Repeat until value doesn't change
=      Print current value
S     Split into characters
L    Turn each character into range from 1 to N
O   Sum

• If you replace € with S, you can skip one O. Nov 22, 2017 at 8:03
• @Emigna ...why does L even behave that way?
– Neil
Nov 22, 2017 at 8:44
• If I recall correctly it was a bug that turned out to be useful and got to remain as a feature. I think it was one the first methods that vectorized. Nov 22, 2017 at 10:12

J, 20 19 bytes

(1#.2!1+,.&.":)^:a:


Try it online!

Outputs the original number, too.

Explanation

(1#.2!1+,.&.":)^:a:
^:a:  Apply until input converges, storing all results in an array
(1#.2!1+,.&.":)      Digitangular sum
,.&.":         Split to digits
&.":           Convert to string, apply left function, then undo conversion
,.               Ravel items (make array of singleton arrays of items)
This ensures that when cast back to integers, the digits are split.
2!                 Compute (n choose 2) on each (nth triangular number)
1#.                   Sum (debase 1)

• [:+/ ->1#. meow! Nov 22, 2017 at 2:07
• @FrownyFrog not an original trick, though I certainly make ample use of it when I remember to.
– cole
Nov 22, 2017 at 2:08

APL (Dyalog), 2320 17 bytes

3 bytes saved thanks to @ngn

{⍵∪⍨+/∊⍳¨⍎¨⍕⊃⍵}⍣≡


Try it online!

How?

⍵∪⍨ - prepend current array to the

+/ - sum of

∊ - flattened

⍳¨ - ranges of each

⍎¨⍕ - digit of the

⊃⍵ - previous value

⍣≡ until convergence. The usage of ∪ (union) makes sure after the first 1 is joined, the next will be excluded due to set uniqueness, and the array will converge.

• Out of curiosity, how long would it be if you weren't allowed to output the original value as well? Nov 21, 2017 at 23:31
• @cairdcoinheringaahing 2 bytes - 1↓ (drop first) Nov 21, 2017 at 23:56
• @Uriel Here power limit (⍣≡) gives a shorter solution than recursion: {⍵∪⍨+/∊⍳¨⍎¨⍕⊃⍵}⍣≡ but it's a shame APL doesn't have a concise way to collect all iterations of a function until convergence: ⍵(f⍵)(f⍣2⊢⍵)(f⍣3⊢⍵)...
– ngn
Nov 22, 2017 at 9:54
• @ngn thanks! I did try to use the power operator, but I didn't think about the fact it converges after 1. Will update soon Nov 22, 2017 at 9:59
• @ngn any idea on how to use {+/∊⍳¨⍎¨⍕⎕←⍵}⍣≡ without getting the last 1 printed? Nov 22, 2017 at 11:49

f 1=[1]
f x=x:f(sum$do d<-show x;[1..read[d]])  Try it online! f 1=[1] -- if x == 1, return the singleton list [1] f x= -- else do d<-show x -- for each char 'd' in the string representation of x -- (using the list monad) [1..read[d]] -- make a list of [1..d] -- (the list monad concatenates all those lists into a single list) sum -- sum those numbers f -- call f on it x: -- and put x in front of it  Edit: @H.PWiz saved a byte. Thanks! Python 2, 62 bytes f=lambda x:x<2and[1]or[x]+f(sum(-~int(i)*int(i)/2for i inx))  Try it online! Wolfram Language (Mathematica), 43 41 bytes Echo@#>1&&#0[#.(#+1)/2&@IntegerDigits@#]&  Try it online! How it works The expression #.(#+1)/2&@IntegerDigits@# gives the digitangular counterpart of #. We Echo the input, use short-circuit evaluation with && to stop if we've reached 1, and otherwise recurse on the digitangular counterpart. -2 bytes thanks to Martin Ender for the . trick: we don't have to use Tr to sum the digits if we replace the multiplication #(#+1)/2 by the dot product #.(#+1)/2. • Only just saw your answer now. You can beat mine by using the scalar product trick to avoid the Tr: Echo@#>1&&#0[#.(#+1)/2&@IntegerDigits@#]& Nov 22, 2017 at 11:03 • @MartinEnder Thanks, that's a neat trick. I wonder if there any even golfier ways to do "print all iterations of this function on the way to a fixed point" (essentially, reimplementing FixedPointList except for how that prints the fixed point twice). It seems like that should have come up before. Nov 22, 2017 at 17:31 Wolfram Language (Mathematica), 4942 39 bytes Thanks to Misha Lavrov for saving 3 bytes. #//.x_:>(y=IntegerDigits@Echo@x).++y/2&  Try it online! (TIO needs parentheses around the ++y for some reason. In my local Mathematica installation it works without them, as it should.) Prints each value on its own line, preceded by >>, and includes the starting number. • You can go back to beating my answer with #//.x_:>(y=IntegerDigits@Echo@x).++y/2&. (...maybe. For some reason, TIO doesn't like this, but Mathematica's fine with it?) Nov 23, 2017 at 1:16 • Well, #//.x_:>(y=IntegerDigits@Echo@x).(++y)/2& is 41 bytes and works in TIO. But my copy of Mathematica doesn't think the parentheses are necessary. Nov 23, 2017 at 1:27 • @MishaLavrov Thanks. Yeah, no clue why TIO needs the parentheses, but syntax in script files is sometimes a bit wonky. Nov 23, 2017 at 12:23 Ohm v2, 9 7 bytes ·Ω}#ΣΣu  Try it online! Explanation  Implicit input as a string ·Ω Evaluate until the result has already been seen, pushing intermediate results } Split digits # Range from 0 to N ΣΣ Sum u Convert to string  • Isn't u unnecessary? Nov 28, 2017 at 0:02 • It's necessary otherwise } won't split the digits Nov 28, 2017 at 6:25 • Hm. That might be a bug. I'll check it out. Nov 28, 2017 at 13:34 Retina, 21 bytes ;{:G .$*1¶
1
$%1 1  Try it online! (The outputs of the individual cases aren't well separated, but each output ends with a 1.) Prints each number on its own line, in order, including the starting number. Explanation ;{:G  This is just some configuration of the program. { makes the program loop until it fails to change the result (which happens once we get to 1), : prints number before each iteration, and ; prevents the final result from being printed twice at the end of the program. The G is just my usual way of creating a no-op stage. .$*1¶


Convert each digit to unary and put it on its own line.

1
$%1  Compute the triangular number on each line, by replacing each 1 with its prefix. We could also use M!&1+ here, which gives us all suffixes of each line. 1  Count all 1s, which sums up all the triangular numbers and converts the result back to decimal. • Is Retina a turing complete language? – user72349 Nov 22, 2017 at 11:51 • @ThePirateBay yes. Nov 22, 2017 at 11:54 Ruby, 60 47 42 bytes -13 bytes by @JustinMariner -5 bytes by @GB ->x{p x=x.digits.sum{|k|k*-~k/2}while x>1}  Try it online! • You can drop the array and splat ([*...]) and change (k+1) to -~k to save a total of 5 bytes: Try it online! Additionally, you can save 8 more by switching to an anonymous lambda function: Try it online! Nov 22, 2017 at 2:32 • Hm, no idea why I thought .map couldn't take arrays. Nov 22, 2017 at 2:54 • You can use "sum{...}" instead of "map{...}.sum" and then remove the space before "while" – G B Nov 22, 2017 at 11:55 Befunge-93, 51 bytes p&>>:25*%:1+*2/v |:/*52p00+g00< 00<vp000_@#-1.::g  Try it online! James Holderness cleverly reshaped my progarm into a 51-byte form. Thanks! Pushy, 242221 17 bytes [sL:R{;Svc^#&1=?i  Try it online! Explanation [sL:R{;Svc^#&1=?i [ &1=?i \ Loop until result == 1: s \ Split last result into digits L: ; \ For each digit n: R{ \ Push the range (1, n) inclusive S \ Sum the ranges vc^ \ Delete all stack items, except the sum # \ Print result  Japt, 1917 10 bytes Doesn't include the input as the first element. Æ=ì cò xÃâ  Try it Æ=ì cò xÃâ :Implicit input of integer U Æ :Map the range [0,U) = : Reassign to U ì : Convert to digit array c : Flat map ò : Range [0,digit] x : Reduce by addition Ã :End map â :Deduplicate  R, 70 bytes f=function(n)"if"(n-1,c(n,f((d=n%/%10^(nchar(n):0)%%10)%*%(d+1)/2)),n)  Try it online! Returns the original value as well. R, 80 bytes function(n){o={} while(n-1){n=(d=n%/%10^(nchar(n):0)%%10)%*%(d+1)/2 o=c(o,n)} o}  Try it online! Does not return the original value. Lua, 91 bytes function f(n)x=0 for d in((0|n)..""):gmatch"."do x=x+d*(d+1)/2 end print(x)c=x==1or f(x)end  Try it online! 05AB1E, 20 12 bytes Saved 2 bytes thanks to caird coinheringaahing ΔD,þ€iLO}O}}  Try it online! Explanation (old version) Δþ€iD>*;}OD1›iD,}}1, Main program Δ } Repeat until there is no changes þ Push digits of the input number €i } Apply for each digit D>*; Calculate the triangular number for given digit O Sum all numbers D1›iD,} Print if greater than 1 1, Print 1 at the end  JavaScript, 61 57 bytes f=a=>a-1?([...a+[]].map(b=>a+=b++*b/2,a=0),a)+' '+f(a):''  Try it online! Python 2, 69 bytes def f(x): while x>1: x=sum(-~int(z)*int(z)/2for z inx) print x  Try it online! • 64 – user72349 Nov 22, 2017 at 0:32 Charcoal, 18 bytes Ｗ⊖Ｉθ«≔ＩΣ⭆θΣ…·0κθθ⸿  Try it online! Link is to verbose version of code. Explanation:  θ Input Ｉ Cast to integer ⊖ Decrement Ｗ « Loop while not zero θ Current value ⭆ Map over characters and concatenate 0 Literal character 0 κ Current character …· Inclusive range Σ Concatenate Σ Sum of digits Ｉ Cast to string ≔ θ Assign back to value θ Output latest value ⸿ Move to start of next line  dc, 62 bytes ?sj[0soljZ1-[dljr10r^/10%d1+*2/lo+sod1-r0<i]dsixlopdsj1<b]dsbx  Try it online! k, 19 bytes {+/(+/1+!"I"$)'$x}\  Unsurprisingly works similarly to the already posted APL and J solutions $x    cast x (implicit var of lambda) to string
(         )'      apply composition (function train) to each character of string
+/1+!"I"$cast character to number, create list from 1 to n, sum it +/ sum triangular numbers { }\ iterate lambda until result converges, appending each result  Jelly, 7 bytes DRFSµÐĿ  Try it online! • DRFSµÐĿ: Full program / monadic link. • ÐĿ: Loop until results are no longer unique (if something other than 1 would occur twice, then the given input does not have a defined result, since it would never reach 1). • D: Convert from integer to decimal. • R: Range (1-indexed). Vectorizes. • F: Flatten and S: Sum (µ just creates a new monadic chain) dc, 31 bytes [[I~d1+*2/rd0<m+]dsmxpd1<f]dsfx  The function m computes the digitangular function of its input; f repeats this until the result reaches 1. Note that we use the input radix to extract digits - this means it will work in any base system, not only decimal. Demo for i in 23 72 55 78 613 8392 11111 8592025 999999999 do echo$i '=>' $(dc -e$i'[[I~d1+*2/rd0<m+]dsmxpd1<f]dsfx')
done

23 => 9 45 25 18 37 34 16 22 6 21 4 10 1
72 => 31 7 28 39 51 16 22 6 21 4 10 1
55 => 30 6 21 4 10 1
78 => 64 31 7 28 39 51 16 22 6 21 4 10 1
613 => 28 39 51 16 22 6 21 4 10 1
8392 => 90 45 25 18 37 34 16 22 6 21 4 10 1
11111 => 5 15 16 22 6 21 4 10 1
8592025 => 117 30 6 21 4 10 1
999999999 => 405 25 18 37 34 16 22 6 21 4 10 1


Python 2, 76 bytes

f=lambda k,s=0:k+s<2and[1]or[k]*(s<1)+f(*[k/10,s,s+k%10*(k%10+1)/2][k<1::2])


Try it online!

Neim, 8 bytes

ͻ𝐂t𝕕𝐬D÷D


Explanation:

ͻ             Start infinite loop
𝐂            Split top of stack into each of its characters
t           Push infinite list of triangular numbers
𝕕          For each of the characters, get the nth element in the above list.
𝐬          Sum.
D         Duplicate.
÷        If top of stack is equal to 1, break.
D       Duplicate.
Implicitly print all elements in the stack, concatenated.


Try it online!

Formatted output

D, 140 bytes

import std.algorithm,std.range,std.conv,std.stdio;void f(T)(T n){n=n.text.map!(u=>u.to!T-48+(u.to!T-48).iota.sum).sum;n.writeln;if(n-1)n.f;}


Try it online!

PHP, 71+1 bytes

for(;1<$n="$s"?:$argn;print$s._)for($i=$s=0;$p--||~$p=$n[$i++];)$s+=$p;


Run as pipe with -nR or try it online. (requires PHP 5.3 or later for the Elvis operator)

• What's the Elvis operator? Nov 24, 2017 at 17:29
• @cairdcoinheringaahing A?:B: if A is truthy then A else B Nov 24, 2017 at 17:57

D,f,@,EDBFEREss
+?
y:1
W!,$f>x,O  Try it online! Doesn't output the first value How it works D,f,@, - Create a monadic function, f. - Example argument: [613] ED - Digits; STACK = [[6 1 3]] BF - Flatten; STACK = [6 1 3] ER - Range; STACK = [[1 2 3 4 5 6] [1] [1 2 3]] Es - Sum each; STACK = [21 1 6] s - Sum; STACK = [28] f calculates n's digitangular counterpart +? - Take input; x = 613; y = 0 y:1 - Set y to 1; x = 613; y = 1 W!, - While x != y...$f>x, -   Call f;       x =  28; y = 1
O     -   Print x;


Perl 6, 36 bytes

{$_,{sum map {sum 1..$_},.comb}...1}
`

Try it online!

Includes the input number in the output list.