Iterated digits squaring: Difference between revisions

(Added Wren)
Line 1,715:
 
{{out}}<pre>85744333</pre>
 
=={{header|Nim}}==
An extremely fast version which computes how many numbers gives a sum (starting with one digit and adding digits one by one). If a sum ends with 89, we adds the associated count to the result. As we have no need to deal with the numbers, but only with the sums of square of digits, there is no need to use big numbers.
 
We provide the result for 8 digits and also for 50 digits. The result is obtained in 7 ms.
 
<lang Nim>import tables
 
iterator digits(n: int): int =
## Yield the digits starting from the unit.
var n = n
while true:
yield n mod 10
n = n div 10
if n == 0:
break
 
 
func gen(n: int): int =
## Compute the chain.
result = n
while result notin [1, 89]:
var s = 0
for d in digits(result):
inc s, d * d
result = s
 
 
func chainsEndingWith89(ndigits: Natural): Natural =
## Compute the number of chains ending with 89.
 
# Initialize the count array with the one digit numbers.
var prevCount, currcount: CountTable[int]
for i in 0..9: prevcount[i * i] = 1
 
# Add next digits.
for _ in 2..ndigits:
# Create the next generation count array.
currcount.clear()
for val, count in prevcount:
for newdigit in 0..9:
# As 0 is included, "currcount" includes "prevcount".
currcount.inc(newdigit * newdigit + val, count)
prevcount = currcount
 
for val, count in currcount:
if val != 0 and gen(val) == 89:
inc result, count
 
echo "For 8 digits: ", chainsEndingWith89(8)
echo "For 50 digits: ", chainsEndingWith89(15)</lang>
 
{{out}}
<pre>For 8 digits: 85744333
For 50 digits: 869339034137667</pre>
 
=={{header|Oberon-2}}==
Anonymous user