Iterated digits squaring: Difference between revisions
lang -> syntaxhighlight
m (→{{header|Oberon-2}}: Added missing '}' at end of 'works with' template which was causing a number of entries to be hidden.) |
(lang -> syntaxhighlight) |
||
Line 7:
An example in Python:
<
>>> iterate = lambda x: x if x in [1, 89] else iterate(step(x))
>>> [iterate(x) for x in xrange(1, 20)]
[1, 89, 89, 89, 89, 89, 1, 89, 89, 1, 89, 89, 1, 89, 89, 89, 89, 89, 1]</
Line 32:
{{trans|Python}}
<
V result = 0
L x > 0
Line 82:
result += check(number)
print(result)</
{{out}}
Line 90:
=={{header|Ada}}==
<
procedure Digits_Squaring is
Line 129:
end loop;
Put_Line ("In range 1 .. 99_999_999: " & Count'Image);
end Digits_Squaring;</
{{out}}
Line 137:
=={{header|ALGOL 68}}==
Brute-force with some caching.
<
# compute a table of the sum of the squared digits of the numbers 00 to 99 #
Line 185:
OD;
print( ( "Number of values whose squared digit sum is 89: ", whole( count 89, -10 ), newline ) )</
{{out}}
<pre>
Line 193:
=={{header|Arturo}}==
{{trans|Nim}}
<
result: n
while [not? in? result [1 89]][
Line 233:
"Number chains for integers <100000000 that end with an 89 value:"
chainsEndingWith89 8
]</
{{out}}
Line 241:
=={{header|AWK}}==
We use a brute-force approach with buffering for better performance. Numbers are assumed to be double precision floats, which is true for most implementations. It runs in about 320 s on an Intel i5.
<
BEGIN {
# Setup buffer for results up to 9*9*8
Line 268:
}
return r
}</
{{out}}
<pre>
Line 285:
{{works with|BBC BASIC for Windows}}
Three versions timed on a 2.50GHz Intel Desktop.
<
REM ---------------------------------------------------------
T%=TIME
Line 342:
PRINT "Version 3: ";N% " in ";(TIME-T%)/100 " seconds."
END</
{{out}}
<pre>
Line 353:
This is just a brute force solution, so it's not very fast. A decent interpreter will probably take a minute or two for a 1,000,000 iterations. If you want to test with 100,000,000 iterations, change the <tt>::**</tt> (100³) near the end of the first line to <tt>:*:*</tt> (100²<sup>²</sup>). With that many iterations, though, you'll almost certainly want to be using a compiler, otherwise you'll be waiting a long time for the result.
<
v0:\+<_:55+%:*^^"d":+1$<:
>\`!#^ _$:"Y"-#v_$\1+\:^0
>01-\0^ @,+55.<>:1>-!>#^_
>,,,$." >=",,,^ >>".1">#<</
{{out}}
Line 369:
A simple solution is to compute all square-digit sums in the desired range as an addition table, then repeatedly select from this list using itself as an index so that all values that end at 1 converge (those that reach 89 will find some point in the cycle, but not always the same one).
<
856929</
It will take a lot of memory and many seconds to compute the count under 1e8 this way. The following program computes the count for numbers below <code>
<
d
m
c
s
e
¯1 +´ c×e # Total up; subtract 1 to exclude 0
}</
<
2 80
3 857
Line 401:
15 869339034137667
16 8754780882739336
=={{header|C}}==
C99, tested with "gcc -std=c99". Record how many digit square sum combinations there are. This reduces <math>10^n</math> numbers to <math>81n</math>, and the complexity is about <math>O(n^2)</math>. The 64 bit integer counter is good for up to <math>10^{19}</math>, which takes practically no time to run.
<
typedef unsigned long long ull;
Line 451:
return 0;
}</
{{out}}
<pre>
Line 476:
</pre>
Fast C implementation (<1 second my machine), which performs iterated digits squaring only once for each unique 8 digit combination. The cases 0 and 100,000,000 are ignored since they don't sum to 89:
<syntaxhighlight lang=c>
#include <stdio.h>
Line 559:
return 0;
}
</syntaxhighlight>
{{out}}
<pre>85744333</pre>
Line 566:
The largest sum possible for any number is 9*9*9, so the first 730 numbers are calculated and stored in an array.<br/>
The rest is then looked up. A limit of 100 million takes about 6 seconds. int.MaxValue takes about 2 and a half minutes.
<
public static class IteratedDigitsSquaring
{
Line 599:
}
}</
{{out}}
<pre>
Line 610:
{{Libheader|System.Numerics}}
Translation of the first C version, with BigIntegers. This can get pretty far in six seconds, even on Tio.run.
<
using System.Numerics;
Line 647:
Console.WriteLine("{0} seconds elapsed.", (DateTime.Now - st).TotalSeconds);
}
}</
{{out}}
<pre style="height:30ex;overflow:scroll">1->10^1 : 7
Line 883:
=={{header|C++}}==
Slow (~10 seconds on my machine) brute force C++ implementation:
<
#include <iostream>
Line 921:
return 0;
}
</syntaxhighlight>
{{out}}
<pre>85744333</pre>
=={{header|Ceylon}}==
<
function digitsSquaredSum(variable Integer n) {
Line 953:
}
print(eightyNines);
}</
=={{header|Clojure}}==
===Direct Method===
<
(:require [clojure.math.numeric-tower :as math])
(:use [criterium.core])
Line 994:
(time (println (direct-method 8)))
</syntaxhighlight>
{{Output}}
<pre>
Line 1,001:
</pre>
===Using Combinations===
<syntaxhighlight>
(def DIGITS (range 0 10))
Line 1,049:
(println (itertools-comb 8))
;; Time obtained using benchmark library (i.e. (bench (itertools-comb 8)) )
</syntaxhighlight>
{{{Output}}
<pre>
Line 1,058:
=={{header|Common Lisp}}==
<
(defun square (number)
(expt number 2))
Line 1,091:
(incf count))
:finally (return count)))
</syntaxhighlight>
{{out}}
Line 1,108:
=={{header|D}}==
A simple memoizing partially-imperative brute-force solution:
<
uint step(uint x) pure nothrow @safe @nogc {
Line 1,125:
void main() {
iota(1, 100_000_000).filter!(x => x.iterate == 89).count.writeln;
}</
{{out}}
<pre>85744333</pre>
Line 1,131:
A fast imperative brute-force solution:
<
import core.stdc.stdio: printf;
Line 1,171:
printf("%u\n", magicCount);
}</
The output is the same.
The run-time is less than 3 seconds compiled with ldc2.
A more efficient solution:
<
enum factorial = (in uint n) pure nothrow @safe @nogc
Line 1,249:
printf("%u\n", result);
}</
The output is the same.
The run-time is about 0.04 seconds or less.
Line 1,257:
A purely functional version, from the Haskell code. It includes two functions currently missing in Phobos used in the Haskell code.
{{trans|Haskell}}
<
auto divMod(T)(T x, T y) pure nothrow @safe @nogc {
Line 1,316:
void main() {
iota(1u, 100_000u).filter!(n => n.iter == 89).count.writeln;
}</
With a small back-porting (to run it with the Phobos of LDC2 2.065) it runs in about 15.5 seconds.
=={{header|ERRE}}==
<
PROGRAM ITERATION
Line 1,339:
PRINT
END PROGRAM
</syntaxhighlight>
This program verifies a number only. With a FOR..END FOR loop it's possible to verify a number range.
=={{header|Factor}}==
A brute-force approach with some optimizations. It uses the fact that the first digit-square-sum of any number < 100,000,000 is, at most, 648. These few chains are rapidly memoized as the results for all hundred-million numbers are calculated for the first time or looked up.
<
prettyprint sequences tools.time ;
IN: rosetta-code.iterated-digits-squaring
Line 1,360:
] loop
drop .
] time</
{{out}}
<pre>
Line 1,367:
</pre>
=={{header|Forth}}==
<
Tested for VFX Forth and GForth in Linux
\ To explain the algorithm: Each iteration is performed in set-count-sumsq below.
Line 1,491:
I 5 .r 2 SPACES I count-89s . CR
LOOP ;
</syntaxhighlight>
{{out}}
<pre>
Line 1,517:
=={{header|FreeBASIC}}==
<
' similar to C Language (first approach)
Line 1,563:
Print
Print "Press any key to quit"
Sleep</
{{out}}
Line 1,572:
=={{header|Frink}}==
<
total = 0
d = new dict
Line 1,603:
println[total]
</syntaxhighlight>
{{out}}
Line 1,610:
</pre>
=={{header|
Programs in
In '''[https://formulae.org/?example=Iterated_digits_squaring this]''' page you can see the program(s) related to this task and their results.
Line 1,621:
It's basic. Runs in about 30 seconds on an old laptop.
<
import (
Line 1,650:
}
fmt.Println(u89)
}</
{{out}}
<pre>
Line 1,658:
=={{header|Haskell}}==
Basic solution that contains just a little more than the essence of this computation. This runs in less than eight minutes:
<
import Data.Tuple (swap)
Line 1,670:
main = do
print $ length $ filter ((== 89) . iter) [1 .. 99999999]</
{{out}}
<pre>85744333</pre>
Line 1,678:
Here's an expression to turn a number into digits:
<
And here's an expression to square them and find their sum:
<
But note that while the task description claims "you always end with either 1 or 89", that claim is somewhat arbitrary.
:But only somewhat the loop is 89
<
15 26 40 16 37 58 89 145 42 20 4 16 37 58 89 145</
You could just as easily claim that you always end with either 1 or 4. So here's a routine which repeats the sum-square process until the sequence converges, or until it reaches the value 4:
<
But we do not actually need to iterate. The largest value after the first iteration would be:
<
648</
So we could write a routine which works for the intended range, and stops after the first iteration:
<
digsq1e8=:(I.itdigsq1 i.649) e.~ sumdigsq</
In other words, if the result after the first iteration is any of the numbers in the range 0..648 which converges to 1, it's not a result which would converge to the other loop. This is considerably faster than trying to converge 1e8 sequences, and also evades having to pick an arbitrary stopping point for the sequence which loops for the bulk computation.
Line 1,706:
And this is sufficient to find our result. We don't want to compute the entire batch of values in one pass, however, so let's break this up into 100 batches of one million each:
<
85744333</
Of course, there are faster ways of obtaining that result. The fastest is probably this:
<
85744333</
This might be thought of as representing the behavior of a highly optimized compiled program. We could abstract this further by using the previous expression at compile time, so we would not have to hard code it.
Line 1,717:
=={{header|Java}}==
{{works with|Java|8}}
<
public class IteratedDigitsSquaring {
Line 1,740:
return n;
}
}</
<pre>85744333</pre>
Line 1,752:
'''Part 1: Foundations'''
<
# Pick n items (with replacement) from the input array,
Line 1,774:
else . + [[$item, 1]]
end
end ) ;</
'''Part 2: The Generic Task'''
Count how many number chains beginning with n (where 0 < n < 10^D) end with a value 89.
<
# sum of the squared digits
def ssdigits: tostring | explode | map(. - 48 | .*.) | add;
Line 1,805:
| if $cache[$ss] then . + ($digits|combinations($Dfactorial))
else .
end) ;</
'''Part 3: D=8'''
<syntaxhighlight lang
{{out}}
<
85744333
Line 1,818:
# Using jq 1.4:
# user 0m3.942s
# sys 0m0.009s</
=={{header|Julia}}==
{{works with|Julia|0.6}}
'''Brute force solution''':
<
while m != 1 && m != 89
s = 0
Line 1,834:
return m
end
itercount(k::Integer) = count(x -> iterate(x) == 89, 1:k)</
'''More clever solution''':
<
function itercountcombos(ndigits::Integer)
cnt = 0
Line 1,864:
end
return cnt
end</
'''Benchmarks'''
<
@time itercountcombos(8)
@time itercountcombos(17)</
{{out}}
<pre> 8.866063 seconds (4.32 k allocations: 232.908 KiB)
Line 1,877:
=={{header|Kotlin}}==
{{trans|FreeBASIC}}
<
fun endsWith89(n: Int): Boolean {
Line 1,912:
if (endsWith89(i)) count89 += sums[i]
println("There are $count89 numbers from 1 to 100 million ending with 89")
}</
{{out}}
Line 1,920:
=={{header|Lua}}==
<
for i = 0, 9 do
Line 1,966:
end
print(counter)</
{{out}}
<pre>85744333</pre>
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<
stopValues = Join[{1}, NestList[sumDigitsSquared, 89, 7]];
iterate[n_Integer] :=
Line 2,007:
b}, {_?(MemberQ[iteratesToOne, #] &), _}][[All, 2]]];
(10^numberOfDigits - 1) - onesCount</
{{out}}<pre>85744333</pre>
Line 2,016:
We provide the result for 8 digits and also for 50 digits. The result is obtained in 7 ms.
<
iterator digits(n: int): int =
Line 2,060:
echo "For 8 digits: ", chainsEndingWith89(8)
echo "For 50 digits: ", chainsEndingWith89(15)</
{{out}}
Line 2,068:
=={{header|Oberon-2}}==
{{works with|oo2c Version 2}}
<
MODULE DigitsSquaring;
IMPORT
Line 2,102:
END DigitsSquaring.
</syntaxhighlight>
{{out}}
<pre>
Line 2,114:
=={{header|Objeck}}==
<
function : Main(args : String[]) ~ Nil {
Count89s(1000000)->PrintLine();
Line 2,157:
return sum;
}
}</
Output:
Line 2,169:
Brute force implementation
<
while (n 1 <> n 89 <> and ) [
0 while(n) [ n 10 /mod ->n dup * + ]
Line 2,175:
] n ;
: iterDigits | i | 0 100000000 loop: i [ i sq_digits 89 &= + ] . ;</
{{out}}
Line 2,183:
=={{header|PARI/GP}}==
<
happy(n)=while(n>6, n=ssd(n)); n==1;
ct(n)=my(f=n!,s=10^n-1,d); forvec(v=vector(9,i,[0,n]), d=vector(9,i, if(i>8,n,v[i+1])-v[i]); if(happy(sum(i=1,9,d[i]*i^2)), s-=f/prod(i=1,9,d[i]!)/v[1]!), 1); s;
ct(8)</
{{out}}
<pre>%1 = 85744333</pre>
Line 2,203:
Tested with freepascal.
<
const
maxdigCnt = 14;
Line 2,339:
writeln('there are ',upperlimit-res,' 89s ');
end.
</
10e18
//658 small counts out of 1000000000
Line 2,359:
{{trans|Raku}}
<
use strict;
Line 2,382:
}
print $cnt;</
85744333
Line 2,388:
=={{header|Phix}}==
{{trans|C}}
<!--<
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">MAXINT</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">machine_bits</span><span style="color: #0000FF;">()=</span><span style="color: #000000;">32</span><span style="color: #0000FF;">?</span><span style="color: #000000;">53</span><span style="color: #0000FF;">:</span><span style="color: #000000;">64</span><span style="color: #0000FF;">))</span>
Line 2,431:
<span style="color: #000000;">main</span><span style="color: #0000FF;">(</span><span style="color: #000000;">20</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span>
<!--</
{{out}}
on 32 bit:
Line 2,466:
I realised I needed to do this in two stages.<br>
Phase 1. Make sure we can count.
<!--<
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">comb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">set</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">at</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">chosen</span><span style="color: #0000FF;">={})</span>
Line 2,494:
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%V\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">comb</span><span style="color: #0000FF;">({</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">},</span><span style="color: #000000;">nums</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</
Starting with the combinations method from http://rosettacode.org/wiki/Combinations_with_repetitions#Phix converted to a function, make sure we
are covering all the numbers correctly by checking that we have indeed found power(10,n) of them, and show we are looking at significantly fewer combinations.
Line 2,510:
Phase 2. Add in the rest of the logic, as suggested count 1's in preference to 89's and subtract from 10^n to get the answer.<br>
[PS There is an eerie similarity between this and the 2nd C version, but I swear it is not a copy, and I noticed that later.]
<!--<
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">is1</span>
Line 2,572:
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">elapsed</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t00</span><span style="color: #0000FF;">)</span>
<!--</
{{out}}
Sadly, while still very much faster than brute force, several times slower than the translated from C version.
Line 2,597:
=={{header|PicoLisp}}==
Brute force with caching
<
(de 1or89 (N)
Line 2,605:
(prog1
(1or89 N)
(idx '*Idx1or89 (cons N @) T) ) ) ) )</
Test:
<
(for I 100000000
(and (=1 (1or89 I)) (inc 'Ones)) )
(println (- 100000000 Ones)) )</
Output:
<pre>85744333</pre>
=={{header|PL/I}}==
<
test: procedure options (main, reorder); /* 6 August 2015 */
Line 2,645:
end test;
</syntaxhighlight>
Output:
<pre>
Line 2,654:
=={{header|PureBasic}}==
{{Trans|C}}
<
Procedure is89(x)
Repeat
Line 2,691:
main()
Print("elapsed milliseconds= "+Str(ElapsedMilliseconds()-start))
Input()</
{{out}}
<pre>1->10^1 : 7
Line 2,715:
elapsed milliseconds= 9</pre>
{{Trans|C++}}
<
Procedure sum_square_digits(n)
num=n : sum=0
Line 2,745:
main()
Print("elapsed milliseconds: "+Str(ElapsedMilliseconds()-start))
Input()</
{{out}}
<pre>85744333
Line 2,754:
====Translation of D====
{{trans|D}}
<
def next_step(x):
Line 2,809:
print result
main()</
{{out}}
85744333
Line 2,815:
====Translation of Ruby====
{{trans|Ruby}}
<
from itertools import combinations_with_replacement
from array import array
Line 2,858:
print "\nD==" + str(D) + "\n " + str(z) + " numbers produce 1 and " + str(10**D-z) + " numbers produce 89"
print "Time ~= " + str(ee) + " secs"
</syntaxhighlight>
{{out}}
<pre>
Line 2,879:
===Python: Simple caching===
<
>>> @lru_cache(maxsize=1024)
def ids(n):
Line 2,892:
>>> sum(ids(x) == 89 for x in range(1, 100000000))
85744333
>>> </
This took a much longer time, in the order of hours.
Line 2,898:
===Python: Enhanced caching===
Notes that the order of digits in a number does not affect the final result so caches the digits of the number in sorted order for more hits.
<
>>> @lru_cache(maxsize=1024)
def _ids(nt):
Line 2,916:
>>> _ids.cache_info()
CacheInfo(hits=99991418, misses=5867462, maxsize=1024, currsize=1024)
>>> </
This took tens of minutes to run.
Line 2,922:
===Count digit sums===
If we always count up to powers of 10, it's faster to just record how many different numbers have the same digit square sum. The <code>check89()</code> function is pretty simple-minded, because it doesn't need to be fancy here.
<
from itertools import count
Line 2,941:
x = sum(a[i] for i in range(len(a)) if is89[i])
print("10^%d" % n, x)</
=={{header|QBasic}}==
Line 2,947:
{{works with|QuickBasic}}
{{trans|BBC BASIC}}
<
T = TIMER
Line 2,964:
NEXT i
PRINT USING "Version 1: ####### in ##.### seconds."; n1; (TIMER - T)
END</
=={{header|Quackery}}==
<
[ base share /mod
dup *
Line 2,984:
[ i^ 1+ chainends
89 = + ]
echo</
{{out}}
Line 2,994:
This contains two versions (in one go). The naive version which can (and should, probably) be used for investigating a single number. The second version can count the IDSes leading to 89 for powers of 10.
<
;; Tim-brown 2014-09-11
Line 3,089:
(length (all-digit-lists 3)) => 220
(count-89s-in-100... 1000000) => 856929]
}</
{{out}}
Line 3,115:
This fairly abstract version does caching and filtering to reduce the number of values it needs to check and moves calculations out of the hot loop, but is still interminably slow... even for just up to 1,000,000.
<
my $cnt = 0;
Line 3,128:
}
say $cnt;</
{{out}}
<pre>856929</pre>
All is not lost, however. Through the use of gradual typing, Raku scales down as well as up, so this jit-friendly version is performant enough to brute force the larger calculation:
<
@cache[1] = 1;
@cache[89] = 89;
Line 3,164:
$cnt = $cnt + 1 if Euler92($n) == 89;
}
say $cnt;</
{{out}}
<pre>85744333</pre>
Line 3,171:
The biggest gains are often from choosing the right algorithm.
<
my $digit;
my $sum = 0;
Line 3,203:
my $ends-with-one = sum flat @sums[(1 .. $k*81).grep: { endsWithOne($_) }], +endsWithOne(10**$k);
say 10**$k - $ends-with-one;</
{{out}}
Line 3,209:
=={{header|REXX}}==
{Both REXX versions don't depend on a specific
===with memoization===
<
parse arg n . /*obtain optional arguments from the CL*/
if n=='' | n=="," then n=10 * 1000000 /*Not specified? Then use the default.*/
!.=0; do m=1 for 9; !.m=m**2; end /*m*/ /*build a
a.=.; #.=!. /*intermediate counts of some numbers. */
do j=1 for n; x=j /* [
do q=1 until s==89 | s==1; s=0 /*add sum of the squared decimal digits*/
do until x=='' /*process each of the dec. digits in X.*/
parse var x _ +1 x; s=s + !._ /*get a digit; sum the fast square, */
end /*until x ··· */ /* [
z.q=s /*assign sum to a temporary auxiliary. */
if a.s\==. then do; s=a.s; leave; end /*Found a previous sum? Then use that.*/
x=s /*substitute the sum for the "new" X. */
end /*q*/ /* [
do f=1 for q; _=a.f; a._=s /*use the auxiliary arrays (for lookup)*/
end /*f*/
Line 3,232:
do k=1 by 88 for 2; @k=right('"'k'"', 5) /*display two results; define a literal*/
say 'count of' @k " chains for all natural numbers up to " n ' is:' #.k
end /*k*/ /*stick a fork in it, we're all done. */</
{{out|output|text= when using the default input:}}
<br>(ten million)
Line 3,242:
===process in chunks===
This version is about <big> 2½ </big> times faster than the previous REXX version.
<
parse arg n . /*obtain optional arguments from the CL*/
if n=='' | n=="," then n=10 * 1000000 /*Not specified? Then use the default.*/
!.=0; do m=1 for 9; !.m=m**2; end /*m*/ /*build a
$.=.; $.0=0; $.00=0; $.000=0; $.0000=0; @.=$. /*short-cuts for sub-group summations. */
#.=0 /*count of 1 and 89 results so far.*/
do j=1 for n; s=sumDs(j) /* [
#.s=#.s + 1 /*bump the counter for 1's or 89's. */
end /*j*/
Line 3,256:
end /*k*/ /*stick a fork in it, we're all done. */
exit /*stick a fork in it, we're all done. */
/*--------------------------------------------------------------------------------------*/
sumDs: parse arg z; chunk=3 /*obtain the number (for adding digits)*/
p=0 /*set partial sum of the decimal digits*/
do m=1 by chunk to length(z) /*process the number, in chunks of four*/
y=substr(z, m, chunk) /*extract a
if @.y==. then do; oy=y; a=0 /*Not done before? Then sum the number*/
do until y=='' /*process each of the dec. digits in Y.*/
parse var y _ +1 y /*obtain a decimal digit; add it to A.*/
a=a + !._ /*obtain a decimal digit; add it to A.*/
end /*until y ···*/ /* [
@.oy=a /*mark original Y as being summed. */
end
else a=@.y /*use the
p=p + a /*add all the parts of number together.*/
end /*m*/
Line 3,277:
do until y=='' /*process each decimal digits in X.*/
parse var y _ +1 y; s=s + !._ /*get a dec. digit; sum the fast square*/
end /*until y ···*/ /* [
y=s /*substitute the sum for a "new" X. */
end /*until s ···*/ /* [
$.p=s /*use this for memoization for the sum.*/
return s</
{{out|output|text= when using the input of: <tt> 100000000 </tt>}}
<br>(one hundred million)
Line 3,290:
=={{header|Ring}}==
<
nr = 1000
num = 0
Line 3,301:
next
see "Total under 1000 is : " + num + nl
</syntaxhighlight>
Output:
<pre>
Line 3,347:
=={{header|Ruby}}==
<
def iterated_square_digit(d)
f = Array.new(d+1){|n| (1..n).inject(1, :*)} #Some small factorials
Line 3,371:
iterated_square_digit(d)
puts " #{Time.now - t0} sec"
end</
{{out}}
Line 3,398:
'''Naive Recursion'''
<
let mut sum = 0;
while num != 0 {
Line 3,417:
let count = (1..100_000_000).filter(|&n| last_in_chain(n) == 89).count();
println!("{}", count);
}</
{{out}}
<pre>85744333</pre>
Line 3,423:
'''With precomputation'''
<
let mut sum = 0;
while num != 0 {
Line 3,444:
let count = (1..100_000_000).filter(|&n| prec[dig_sq_sum(n)] == 89).count();
println!("{}", count);
}</
Runtime: 1.7s on a 2500k @ 4Ghz
{{out}}
Line 3,452:
===Naïve Version, conventional iteration and (tail) recursive in one===
{{Out}}Best seen running in your browser either by [https://scalafiddle.io/sf/3XRtgEE/0 ScalaFiddle (ES aka JavaScript, non JVM)] or [https://scastie.scala-lang.org/6HeszTpxTXOqvrytzShUzg Scastie (remote JVM)] to compare the run times.
<
object Euler92 extends App {
Line 3,494:
println(s"Runtime recursive loop. [total ${compat.Platform.currentTime - executionStart0} ms]")
}</
=={{header|Sidef}}==
<
if ((n == 1) || (n == 89)) {
Line 3,506:
}
say (1..1e6 -> count_by { digit_square_sum_iter(_) == 89 })</
{{out}}
<pre>
Line 3,518:
With nth power support.
<
func is89(_ n: Int) -> Bool {
Line 3,570:
}
iterSquare(upToPower: 8)</
{{out}}
Line 3,585:
All three versions below produce identical output (<tt>85744333</tt>), but the third is fastest and the first is the slowest, both by substantial margins.
===''Very'' Naïve Version===
<
while {$n != 1 && $n != 89} {
set n [tcl::mathop::+ {*}[lmap x [split $n ""] {expr {$x**2}}]]
Line 3,594:
incr count [expr {[ids $i] == 89}]
}
puts $count</
===Intelligent Version===
Conversion back and forth between numbers and strings is slow. Using math operations directly is much faster (around 4 times in informal testing).
<
while {$n != 1 && $n != 89} {
for {set m 0} {$n} {set n [expr {$n / 10}]} {
Line 3,609:
incr count [expr {[ids $i] == 89}]
}
puts $count</
===Substantially More Intelligent Version===
Using the observation that the maximum value after 1 step is obtained for <tt>999999999</tt>, which is <math>9^3=729</math>. Thus, running one step of the reduction and then using a lookup table (which we can construct quickly at the start of the run, and which has excellent performance) is much faster overall, approximately 3–4 times than the second version above (and over 12 times faster than the first version).
<!-- It takes about 200 seconds on my machine, but I can't compare with anyone else's system… -->
:Donald, you have 1 too many 9's the value after step 1 is 81*8 = 648. Not that that is the problem here, you can not afford to go around this loop 100 million times. Notice that IDS[21] == IDS[12], IDS[123] == IDS[132] == IDS[213} ... etc, etc. The Ruby version takes about a tenth of a second.--[[User:Nigel Galloway|Nigel Galloway]] ([[User talk:Nigel Galloway|talk]]) 12:47, 31 August 2014 (UTC)
<
proc ids n {
while {$n != 1 && $n != 89} {
Line 3,645:
}
puts $count
}}</
=={{header|VBScript}}==
<syntaxhighlight lang=vb>
start_time = Now
cnt = 0
Line 3,669:
WScript.Echo "Elapse Time: " & DateDiff("s",start_time,end_time) &_
vbCrLf & "Count: " & cnt
</syntaxhighlight>
{{Out}}
Line 3,680:
=={{header|Wren}}==
{{trans|FreeBASIC}}
<
var digit = 0
var sum = 0
Line 3,717:
}
}
System.print("Took %(((System.clock - start)*1000).round) milliseconds.")</
{{out}}
Line 3,728:
=={{header|X86 Assembly}}==
{{works with|nasm}}
<
section .data
count dd 0
Line 3,781:
mov eax, 0
ret
</syntaxhighlight>
=={{header|zkl}}==
Line 3,788:
{{trans|D}}
{{trans|http://www.mathblog.dk/project-euler-92-square-digits-number-chain/}}
<
candidate:=number.reduce(fcn(sum,n){ sum*10 + n },0); // digits to int
Line 3,819:
}
}
println(result);</
{{out}}
<pre>85744333</pre>
Line 3,826:
{{trans|BBC_BASIC}}
Very, very slow. Use a ZX Spectrum emulator and run with maximum speed option enabled.
<
20 FOR i=1 TO 1000
30 LET j=i
Line 3,839:
110 NEXT i
120 PRINT "Version 1: ";n
200 DEF FN m(a,b)=a-INT (a/b)*b: REM modulo</
{{out}}
<pre>Version 1: 857</pre>
|