Iterated digits squaring: Difference between revisions

(Add Swift)
 
(40 intermediate revisions by 25 users not shown)
Line 7:
An example in Python:
 
<langsyntaxhighlight lang="python">>>> step = lambda x: sum(int(d) ** 2 for d in str(x))
>>> 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]</langsyntaxhighlight>
 
 
Line 27:
* [[Digital root]]
* [[Digital root/Multiplicative digital root]]
* [[Happy numbers]]
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">F next_step(=x)
V result = 0
L x > 0
result += (x % 10) ^ 2
x I/= 10
R result
 
F check(number)
V candidate = 0
L(n) number
candidate = candidate * 10 + n
 
L candidate != 89 & candidate != 1
candidate = next_step(candidate)
 
I candidate == 89
V digits_count = [0] * 10
L(d) number
digits_count[d]++
 
V result = factorial(number.len)
L(c) digits_count
result I/= factorial(c)
R result
 
R 0
 
V limit = 100000000
V cache_size = Int(ceil(log10(limit)))
assert(10 ^ cache_size == limit)
 
V number = [0] * cache_size
V result = 0
V i = cache_size - 1
 
L
I i == 0 & number[i] == 9
L.break
I i == cache_size - 1 & number[i] < 9
number[i]++
result += check(number)
E I number[i] == 9
i--
E
number[i]++
L(j) i + 1 .< cache_size
number[j] = number[i]
i = cache_size - 1
result += check(number)
 
print(result)</syntaxhighlight>
 
{{out}}
<pre>
85744333
</pre>
 
=={{header|Ada}}==
<syntaxhighlight lang="ada">with Ada.Text_IO;
 
procedure Digits_Squaring is
 
function Is_89 (Number : in Positive) return Boolean
is
Squares : constant array (0 .. 9) of Natural :=
(0, 1, 4, 9, 16, 25, 36, 49, 64, 81);
 
Sum : Natural := Number;
Acc : Natural;
begin
loop
Acc := Sum;
Sum := 0;
while Acc > 0 loop
Sum := Sum + Squares (Acc mod 10);
Acc := Acc / 10;
end loop;
 
if Sum = 89 then return True; end if;
if Sum = 1 then return False; end if;
end loop;
end Is_89;
 
use Ada.Text_IO;
Count : Natural := 0;
begin
for A in 1 .. 99_999_999 loop
if Is_89 (A) then
Count := Count + 1;
end if;
 
if A = 999_999 then
Put_Line ("In range 1 .. 999_999: " & Count'Image);
end if;
 
end loop;
Put_Line ("In range 1 .. 99_999_999: " & Count'Image);
end Digits_Squaring;</syntaxhighlight>
 
{{out}}
<pre>In range 1 .. 999_999: 856929
In range 1 .. 99_999_999: 85744333</pre>
 
=={{header|ALGOL 68}}==
Brute-force with some caching.
<langsyntaxhighlight lang="algol68"># count the how many numbers up to 100 000 000 have squared digit sums of 89 #
 
# compute a table of the sum of the squared digits of the numbers 00 to 99 #
Line 79 ⟶ 186:
OD;
 
print( ( "Number of values whose squared digit sum is 89: ", whole( count 89, -10 ), newline ) )</langsyntaxhighlight>
{{out}}
<pre>
Number of values whose squared digit sum is 89: 85744333
</pre>
 
=={{header|Arturo}}==
{{trans|Nim}}
<syntaxhighlight lang="rebol">gen: function [n][
result: n
while [not? in? result [1 89]][
s: new 0
loop digits result 'd ->
's + d*d
result: s
]
return result
]
 
chainsEndingWith89: function [ndigits][
[prevCount,currCount]: #[]
loop 0..9 'i -> prevCount\[i*i]: 1
 
res: new 0
 
loop 2..ndigits 'x [
currCount: #[]
loop prevCount [val,cnt][
v: to :integer val
loop 0..9 'newDigit [
mm: v + newDigit*newDigit
if not? key? currCount mm -> currCount\[mm]: 0
currCount\[mm]: currCount\[mm] + cnt
]
]
prevCount: currCount
]
loop currCount [val,cnt][
v: to :integer val
if and? [v <> 0] [89=gen v] ->
'res + cnt
]
return res
]
 
print [
"Number chains for integers <100000000 that end with an 89 value:"
chainsEndingWith89 8
]</syntaxhighlight>
 
{{out}}
 
<pre>Number chains for integers <100000000 that end with an 89 value: 85744333</pre>
 
=={{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.
<syntaxhighlight lang="awk"># Usage: GAWK -f ITERATED_DIGITS_SQUARING.AWK
BEGIN {
# Setup buffer for results up to 9*9*8
for (i = 1; i <= 648; i++) {
k = i
do {
k = squaredigitsum(k)
} while ((k != 1) && (k != 89))
if (k == 1) # This will give us 90 entries
buffer[i] = ""
}
# Check sequence for every number
pow10 = 1
for (i = 1; i <= 100000000; i++) {
count += (squaredigitsum(i) in buffer) ? 0 : 1
if (i == pow10) {
printf("1->10^%d: %d\n", length(i) - 1, count)
pow10 *= 10
}
}
}
function squaredigitsum(n, r) {
while (n) {
r += (n % 10) ^ 2
n = int(n / 10)
}
return r
}</syntaxhighlight>
{{out}}
<pre>
1->10^0: 0
1->10^1: 7
1->10^2: 80
1->10^3: 857
1->10^4: 8558
1->10^5: 85623
1->10^6: 856929
1->10^7: 8581146
1->10^8: 85744333
</pre>
 
Line 88 ⟶ 286:
{{works with|BBC BASIC for Windows}}
Three versions timed on a 2.50GHz Intel Desktop.
<langsyntaxhighlight lang="bbcbasic"> REM Version 1: Brute force
REM ---------------------------------------------------------
T%=TIME
Line 145 ⟶ 343:
PRINT "Version 3: ";N% " in ";(TIME-T%)/100 " seconds."
 
END</langsyntaxhighlight>
{{out}}
<pre>
Line 156 ⟶ 354:
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.
 
<langsyntaxhighlight lang="befunge">1-1\10v!:/+55\<>::**>>-!|
v0:\+<_:55+%:*^^"d":+1$<:
>\`!#^ _$:"Y"-#v_$\1+\:^0
>01-\0^ @,+55.<>:1>-!>#^_
>,,,$." >=",,,^ >>".1">#<</langsyntaxhighlight>
 
{{out}}
Line 167 ⟶ 365:
 
<pre>1..100000000 => 85744333</pre>
 
=={{header|BQN}}==
 
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).
 
<syntaxhighlight lang="bqn"> +´1?1? ?˜?(?2???) ?+?´6?<ט?10
856929</syntaxhighlight>
 
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>10???</code> by using dynamic programming to determine how many numbers have each possible digit sum. Then it finds the fate of each number in this greatly reduced set. This gives an exact result for inputs up to 16, taking a fraction of a millisecond for each.
 
<syntaxhighlight lang="bqn">DigSq ? {
d ? ט ?10 # Digit values
m ? 1+81×2??? # One plus maximum digit sum
c ? (+´ d ??0?»¨ <)??? m??1 # Count of numbers having each sum
s ? m ? ? d +??(?10??m) 0 # Sum for each sum
e ? 1??˜?(?2???)s # Which sums end at 89
¯1 +´ c×e # Total up; subtract 1 to exclude 0
}</syntaxhighlight>
 
<syntaxhighlight lang="bqn"> >??DigSq¨ 1+?16
+-
? 1 7
2 80
3 857
4 8558
5 85623
6 856929
7 8581146
8 85744333
9 854325192
10 8507390852
11 84908800643
12 850878696414
13 8556721999130
14 86229146720315
15 869339034137667
16 8754780882739336
+</syntaxhighlight>
 
=={{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.
<langsyntaxhighlight lang="c">#include <stdio.h>
 
typedef unsigned long long ull;
Line 216 ⟶ 452:
 
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>
Line 241 ⟶ 477:
</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">
<lang c>
#include <stdio.h>
 
Line 324 ⟶ 560:
return 0;
}
</syntaxhighlight>
</lang>
{{out}}
<pre>85744333</pre>
 
=={{header|C sharp}}==
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.
<syntaxhighlight lang="csharp">using System;
public static class IteratedDigitsSquaring
{
public static void Main() {
Console.WriteLine(Count89s(1_000_000));
Console.WriteLine(Count89s(100_000_000));
}
 
public static int Count89s(int limit) {
if (limit < 1) return 0;
int[] end = new int[Math.Min(limit, 9 * 9 * 9 + 2)];
int result = 0;
 
for (int i = 1; i < end.Length; i++) {
for (end[i] = i; end[i] != 1 && end[i] != 89; end[i] = SquareDigitSum(end[i])) { }
if (end[i] == 89) result++;
}
for (int i = end.Length; i < limit; i++) {
if (end[SquareDigitSum(i)] == 89) result++;
}
return result;
 
int SquareDigitSum(int n) {
int sum = 0;
while (n > 0) {
int digit = n % 10;
sum += digit * digit;
n /= 10;
}
return sum;
}
}
 
}</syntaxhighlight>
{{out}}
<pre>
856929
85744333
</pre>
 
===BigInteger version===
{{trans|C}}
{{Libheader|System.Numerics}}
Translation of the first C version, with BigIntegers. This can get pretty far in six seconds, even on Tio.run.
<syntaxhighlight lang="csharp">using System;
using System.Numerics;
 
class Program {
 
const int MaxPow = 301;
static int [] sq = {1, 4, 9, 16, 25, 36, 49, 64, 81};
static BigInteger [] sums;
 
static bool is89(int x) {
while (true) {
int s = 0, t;
do if ((t = (x % 10) - 1) >= 0) s += sq[t]; while ((x /= 10) > 0);
if (s == 89) return true;
if (s == 1) return false;
x = s;
}
}
 
static BigInteger count89(int n) {
BigInteger result = 0;
for (int i = n * 81; i > 0; i--) {
foreach (int s in sq) { if(s > i) break; sums[i] += sums[i - s]; }
if (is89(i)) result += sums[i];
}
return result;
}
 
static void Main(string[] args) {
BigInteger [] t = new BigInteger[2] {1, 0}; sums = new BigInteger[MaxPow * 81]; Array.Copy(t, sums, t.Length);
DateTime st = DateTime.Now;
for (int n = 1; n < MaxPow; n++) {
Console.Write("1->10^{0,-3}: {1}\n", n, count89(n));
if ((DateTime.Now - st).TotalSeconds > 6) break;
}
Console.WriteLine("{0} seconds elapsed.", (DateTime.Now - st).TotalSeconds);
}
}</syntaxhighlight>
{{out}}
<pre style="height:30ex;overflow:scroll">1->10^1 : 7
1->10^2 : 80
1->10^3 : 857
1->10^4 : 8558
1->10^5 : 85623
1->10^6 : 856929
1->10^7 : 8581146
1->10^8 : 85744333
1->10^9 : 854325192
1->10^10 : 8507390852
1->10^11 : 84908800643
1->10^12 : 850878696414
1->10^13 : 8556721999130
1->10^14 : 86229146720315
1->10^15 : 869339034137667
1->10^16 : 8754780882739336
1->10^17 : 87975303595231975
1->10^18 : 881773944919974509
1->10^19 : 8816770037940618762
1->10^20 : 87994965555707002706
1->10^21 : 877214809753814412449
1->10^22 : 8740475212714948184620
1->10^23 : 87086767569032964273481
1->10^24 : 867912763131207135645491
1->10^25 : 8652685884347431487002838
1->10^26 : 86292591735549905389544085
1->10^27 : 860834491746260610360036431
1->10^28 : 8589383648492973833587962133
1->10^29 : 85719021282987319689186339605
1->10^30 : 855551075003449256539175506135
1->10^31 : 8539846767881104092122936276127
1->10^32 : 85245373514507207808857201531419
1->10^33 : 850921798797738318678358430121498
1->10^34 : 8493602724656082624921256124945709
1->10^35 : 84775765928320499747460839463166887
1->10^36 : 846127234701773214379999133850790428
1->10^37 : 8445101119798901092741398494615146552
1->10^38 : 84297231641833173945386163054551847907
1->10^39 : 841596309978956515337376882969248454407
1->10^40 : 8404688192812158407616126296428757287918
1->10^41 : 83966751636707267524727665346136900559808
1->10^42 : 839249062380369832617111284115323596416189
1->10^43 : 8392404334111393647768734710144578436411820
1->10^44 : 83963458265257975880706035079312646291089162
1->10^45 : 840390620671402119260216748725664301844515595
1->10^46 : 8414380030090502032224993998030998898525187113
1->10^47 : 84268378296544752164579356732419005387066100619
1->10^48 : 844021806190251380758758476585216084473498054164
1->10^49 : 8453427257465803796850958549692384862623307213954
1->10^50 : 84654382110763756920355712358557288888652143589824
1->10^51 : 847537750217936548550698726085731005366031699187697
1->10^52 : 8482595213704622541116090344851904585191448008008698
1->10^53 : 84867114171087369978017651353669784240040553506347863
1->10^54 : 848763596449838290475849513610494144653829069301555744
1->10^55 : 8485560484449848898784875907345401899210439410548661905
1->10^56 : 84809241613331707710051455489300240267084096119421192555
1->10^57 : 847435762855526547824875506635678396375585724580676401281
1->10^58 : 8466611716350744168054316461343227422117005648835357501042
1->10^59 : 84584794275749872157313978459784905712596125963065261887087
1->10^60 : 845072003706634444132974487900963836188835216550117810064042
1->10^61 : 8443993493344896883975002240891650144660444520675597442455846
1->10^62 : 84388114632696697235622301117847815843833846024601175739193818
1->10^63 : 843550873686677877815689986525235580589881417969543147823955468
1->10^64 : 8434235773893302085490040550865199018569738474571414542759091420
1->10^65 : 84349704267294170985441634483996250787548886013951222960902661326
1->10^66 : 843754473866041852258692025296354310048924258957916675280270848383
1->10^67 : 8441681459520956437757926334685945498961397097395903879157454648255
1->10^68 : 84470346186515545447015226246395087364669380975589204241143094714939
1->10^69 : 845322904478358163301387625325558514367250680088175647529431667836984
1->10^70 : 8459894886866423548013102102792807954026974401198186041921374671243280
1->10^71 : 84666946651672233790199404593444235036570835062615369577576893503846807
1->10^72 : 847334186689171226140326334304533885325304121282085041331744831976064350
1->10^73 : 8479611353077227882670645671814119173057689480878540635598355377828682030
1->10^74 : 84853427154299528465645782338465354008595064980299709100384597454288492601
1->10^75 : 849043816798387454378741585441510256257380507579571260789337785619852662347
1->10^76 : 8494856623561856764693867992374031564067482173292744174563186543401165633828
1->10^77 : 84986053947449161776274594245379439290411038180766518290148488651233497246177
1->10^78 : 850173060522433967868762132659331655304647077578564191004961947049948444228365
1->10^79 : 8504307025056582630550030771632855466797975344124296918801658700334809780702180
1->10^80 : 85064277463177819389470781000622284519150163101058649012431344960771964694651571
1->10^81 : 850819394401164074041611461274974545538571046366755739155832724445684685332968364
1->10^82 : 8509704926350516030551921703403722812551632988675827388709515859909259694851647834
1->10^83 : 85110487385572993176128742106677248626395367895834794577983294930763809503319428014
1->10^84 : 851229369385484114012959335791260147114430529630506351180704055826749898923602659534
1->10^85 : 8513481307977862280230328507187688326498927519035854456240791004629338052316252944962
1->10^86 : 85146211618619610403764635439165512633290370187486987569410348341895803492714570487527
1->10^87 : 851568818184158929602427279369759555161328403821517914312791180281061345268793327734747
1->10^88 : 8516622700452095396072535230209391313806399904195398975658231816363535402709890663189362
1->10^89 : 85173334571538953250258781660855404353386662001559167780912035060599928280076465921472154
1->10^90 : 851770344573699439297915741793926110106776082569441364749653121400250416057006702446954384
1->10^91 : 8517598250615252557316601155045090636911412094296867452464613221521534622516854479200111167
1->10^92 : 85168762749001784598676830952569236245621633296172168977732463493080042840432604954811508256
1->10^93 : 851540008029830880300994057100452233115864754809360142651983875738294861965389543527957072529
1->10^94 : 8513047953516561208480829418619110455666666761484728667018453838522192578086491705360981209049
1->10^95 : 85097247949654801901491432145587952810159950536920233184462924578646829963281410434249631392723
1->10^96 : 850537149051806438025447330906036177346231271896967500380026706058200824325895506679143940414076
1->10^97 : 8499972063859782028890346555815409171233558167321697969098574428852568869015102044124776256646518
1->10^98 : 84935580971302195864938049552661540297299353108396246935346418128128262766226035981031392864950607
1->10^99 : 848621012961290009929016807175952691990221212867104144408323613154869710828195585404753698625209870
1->10^100: 8478055976550795533989641628119784566456389856922225836863058100833148222237810283684193376704453622
1->10^101: 84692661332197101015983198300119859021702958967680338663444073316601738058829066776089854542212989340
1->10^102: 846004662712490384489176693903976456406275569081651590341922175721977994554886920688273660628038615530
1->10^103: 8450629841618941841374846246720140022439681757127967533191099545085398501977517119347590327770355321434
1->10^104: 84412639494761330308514535722479416772282357055894579094485879248099506197188362019049795338340624012301
1->10^105: 843220166084720035321606859999967460448483170329902742792363249370695697719160653283805304587721253017361
1->10^106: 8423689005669735317756774969292543189691443702455489905512071638162495163070141112432829369072721001438803
1->10^107: 84159548379569442293630345909810266521615950102980331577692671042526244954280499017296253855362379723006790
1->10^108: 840920167282889832940657933809381773679300456385012266847912623238503960535214111183445921289786823658787691
1->10^109: 8403598353292268590336072525335623277440130064609705442801138149158666937015259427681264313068009086176250877
1->10^110: 83992749011849425594102987318631343125622400751939263715871477971837511761611183001200425931121955124445796563
1->10^111: 839631974560024541066376425245637209524348207271199051409239974688509717594962340253156692813877667108301744106
1->10^112: 8394779353899880586911134833609814206804364692659236923514863543225711320256322212826981126418518735060793772750
1->10^113: 83946601270617664302492383399919020477597958169554254483427394351411967951182614872496928963913457889190568112395
1->10^114: 839593227424935347188648037914393774879073981203516129165175570585940253228070179608775423063767686629889237370343
1->10^115: 8398535261578467944398129353883159481758437570367304189005134894914805401432837029302170166444526790097924367111503
1->10^116: 84023843454035852573265864848894850643884841292094243539904097304702512644040636408661949798936846401719392744529025
1->10^117: 840737765642794051888186278689979033461813727159185802383506635349749710904137817158720048137762867500712046819247594
1->10^118: 8413403299481449636810051588954342805968283459950501545886836317455395792682501121057127293827832135213161768368219253
1->10^119: 84203459731804372791295301224645565239535230919259257974175798305292830946699497417228262643161300276076207336625610134
1->10^120: 842809268870874063928885672713544280450769176965833988262182876494615882586594316787946370157216295565316434490326651405
1->10^121: 8436537269586024582444789405103627999973329698521927747116692346516613959566150658077870051889885971990610726551245907282
1->10^122: 84455834344493608566315467696492314037782180434561295410998128008344540731783028824982047820404300118155481934579800141088
1->10^123: 845514639154622335439026676162812633638571876699098045234551483696103405951596419680669149347110570074557588539445728510018
1->10^124: 8465152995954852314095072658655816590955469635973935795588056505433337123869586772927379963580066217729825686876675663167185
1->10^125: 84755406288317367647502726863830973688269578307186392087532645236745222242400899454278308118658816773299796554538815106946662
1->10^126: 848625504457571338232292398385105460655500154346371677749525133665065153305513976195700074289083571929361989667922170389107535
1->10^127: 8497247491606457974773951687008958065830712221221672428563728962952710482456410072989046167006589524549671922187923421293104261
1->10^128: 85084714431998555684542412118169794176587616263302937222006603793644213669647672530734324336062593730448168482490463581934163209
1->10^129: 851987927694394695842385097569051414740093541977628250087327027568711635166984043208988142923913857460666864202533480163816074202
1->10^130: 8531419217683749662902274331887012779776215625286974893028601621512119501265453211740142140831505959855845555950934192931323135091
1->10^131: 85430328139300947018442720074404606897400678689137949606360116452651125380471435832121200992460847030421534496794199309573886358524
1->10^132: 855465315738173678760862649212737686693137920889352300831379756993911053972720948424411094181836238208234099960617208156267778781898
1->10^133: 8566203985676470440731224844367227028626203877233764214723360280287402102216808298088324826982839611954201836019907306964986020317159
1->10^134: 85775997358049954163025460353028420873131413549826277262221703709641647709337930451236309466814929967802548158100676076963356874077035
1->10^135: 858874654517946257331373751494744684697894687286199674069180793094186295509981754114205911144101048543298035168442378180859108201796265
1->10^136: 8599544133518541190729470603965905587527154359647919952067163387372304281858539652528774948622565592410227289026773964696225096635862537
1->10^137: 86098884446696506849205217476298801856531759087495262915652873693105198539437793396587535380166248596923904768946564631519624154608822690
1->10^138: 861967488519975027278659230468829107364665645483477317437018410008632482976457415861327948074033275571831029811199126478567233637434713802
1->10^139: 8628801966906107103794870359515838367624418995487887432274900379678186901156278250379655878138155038529537336691569617421296295380371760340
1->10^140: 86371751432755850734211313782502597168356853194847423187885795766026223040981206579899447886878504305410691164655066591417733867217657409811
1->10^141: 864471062463358928035890212882855394973552211508640566300839272774044673907427647532988481646812971525433236154760961951830488066552534999023
1->10^142: 8651338962123525381382585497345224517243502289336494055582727855432102914169042172702045582244422419844751183011546403203406688188535065077322
1->10^143: 86570082053814840071676786387711389238199465843648958320947100960909947309631925605038600684044214317481472519092808161209930532770395663770781
1->10^144: 866168646140024454232290939392340553469733795408720476998913174615258133882405119795696045709637935842786961080230573092926927470162827652342923
1->10^145: 8665363711233461583131718626220667710334246969605082108793313417232622503508731655200858605762988314178800129280340217618589701154413543656985768
1->10^146: 86680527755718649759685176307373285371506102115475732941737986612281052787642500311258388070351873908022137905978541886761549544508105211635516228
1->10^147: 866978935858429040804614015372620947011463145811894778944224644840965029116656072947888551840966766335486237021126810837001330600241756682469168167
1->10^148: 8670631140523282973971782080001983833731728340683112114855303301784698980848631949401710274261706144525939388879900371490715240712970153368815534367
1->10^149: 86706559321625893654219061535654670226251515192444823540942376968150754206994835939850628017684192061166333847144398807182953462336351429576667101351
1->10^150: 866995894677201410904770273181085867673520667933560075983432420563205634118449857866990239690356187026767184415381247787966191029231566995411712911007
1->10^151: 8668649286520103298110693613874545220931966501441595187981603679256058680844995640768730126032798906817769842612438159035028750557047429668482063638625
1->10^152: 86668457782766182106365998476602923925113815986769356535308077952464501916435251498791257040294658754611725463671013282549956507413788549087648641846098
1->10^153: 866467232703588323761623292919053615805349473853030836383461617368439378625942338161355425237008265428317731976385096608438676681105037540093273504844483
1->10^154: 8662252981878105789584061011021060141399639813427794770240893198981230593010055187290079715875704519459746894597845545067244523511239294665336648278040637
1->10^155: 86597069279331973627870277117295560971212134258887952139164522646395290648630256852565891654443101159408986732677200310584518068043543948322349006452151755
1->10^156: 865714362687450998043815943867869054665470989918126698474385057239018213934641784542968962053533734187459455324174294359416548556344040132940037126509574890
1->10^157: 8654658327106972791669605830924233521101999366448366696413768175647650132585930189666095910251594686212883617926599504812573308511497426284397573601012279375
1->10^158: 86523281525978906450144206624921581416241237156433481656480265807221677603408225926171146763083505699243678209180779205409664726743837972061944584770689307884
1->10^159: 865020895640273664634221805288900266279823536202089144549284863821848719729621871794854384484450827784422753936554110189466495950347084459481187597192205418793
1->10^160: 8648333092180248361231569929436471172695159651290083551629519955961094099569126130177616360908316038756710670681403062201420194924583089357076176913473551489817
1->10^161: 86467082158234917505257945501916111178867219946014491779173744896435884955641567959785164124416182157534690566327230254824916687748403437579928718500003240088350
1->10^162: 864531718178004477579328299078477740103286866685836705893778259068484361910954920040103346818883066344256341407619054890526196017651798464562371916742275514078096
1->10^163: 8644119047175677532754512732881650797783914476890547159332150786248814701309170973662384365694682365725345684746385423597293333794783119696118927072215437319257440
1->10^164: 86430511442728833953474406348743455606569468731398316056046331180619896926256415048429340648516795318606702261936259185655191185135897215949312081438663747406505352
1->10^165: 864203213098456917179089416334228304803823157191121623901676225339391935646182411440896586741908176885056293738329991372321077500327578045864902843222595891799567806
1->10^166: 8640965882937716485397501931334347152458001316883441819080947648945115844393354807154067487578858173020177220644862075271361572635046969133096397262003200031012088816
1->10^167: 86397460514795855219888182686863463583022651832659752347275952763764870817118284418230695316619420880587709262736889606859182358084380751509419091890525660564555427901
1->10^168: 863826108212994733968753648916344180650270462271158599364947882912609226359091464049878200409969696906956615971127829923562306335697890300823826175463538490380690739451
1->10^169: 8636399468812722554622656891339014659756492411987212588808905238038013917598506567892281064118123161436622230807092368588797239398601813995192754544282167394183895076163
1->10^170: 86340550115810963737132600434455522470569445567277315861058710137153565317691542777881722463942842675087823559441027338766864911001309033038846460880092552344039469739333
1->10^171: 863113184960208420682902249205892077992533001572322252023394244226663293763935715908577243441852383675532094794872800029273307246757568352279588128123766425105968866901616
1->10^172: 8627549056314884656085758650988354705410677397535432663170381749859818305061157900374193823460026020453498398255516128456675018659144733546914336443286666016242464534892623
1->10^173: 86232446087184919482081527092941285304657064140735231468756283252665952399658175811031283829089578449010792434421243969476874537741281407520376270606159166994743509790579870
1->10^174: 861817857595365546195764878782545616412299953305644834253961921594884506100246389780862738254371890536265325177953967353668527189935970175680262525003852416511702685102182441
1->10^175: 8612335411616785098274560702996374588709528639692603595138354547577954344338556793950612531193867992899537665396961790126485441261162978457728277055887715863633046672606059241
1->10^176: 86057252772491914510352333999906105981829362686305939974861378757443054109080895856413489539176272606128074757709987886142026849718775210459324179053970375798833643674653299146
1->10^177: 859838436879206181835365262115744403026095659693962971028229600944239019463572625102155108901336581755998940232822992950041279925927692909953068033242268448253671491806888602951
1->10^178: 8590374261184353667886274109282646777037742508789286305748696410656346178086122686714500258721415114247208450827752012664251102329405203342553434732973912035701717886506338020826
1->10^179: 85817803266299770850481644986303982631777128860751635552122752691142344851161667201711396408118161670019162565320967870657007411787078526807901817918683806698015174468543495149290
1->10^180: 857270931762460513913686774682703804324648224726040993071441204202938055376046440338560584347422946756765924309947940529727632781070244946475500609399411949683310388884381375784900
1->10^181: 8563286235265958004060828215056362716815395263188715179579008718784822735717230155520124874918608746486038288964871349973344482831835476012896645188257511452828884518822322381868751
1->10^182: 85536506257695171155764934949044365934306619258958532693184485997594236754853608694928818673632500990117929221007432007050799573098773278108453310625432989672233773221665984566985995
1->10^183: 854395246301416621734481057207967339862582992135509483575290027545350116527551368346220282638515725751863036555147858491593940486596084736024013227696715945480172650891444104216038874
1->10^184: 8534347782308749360706135913155759188845911594327933372849111132502671161496334420163904587424902551554260396210079867764136411801104476918881616206260973044707888081268917988811150838
1->10^185: 85249942307314506171903880472476276738180469673363011061550119400987556101451609644450156397637792635015315854436060260243452215710896132576011311208019157400087495036186110550299101573
1->10^186: 851604669298520104411896383155212891608415861472826352206829071810468404388469834164266030803667279410619332283818403448641099135191033340387858650321494900510343924107016585921016978274
1->10^187: 8507653139600643336183748904571443328144024262070249799701460854985028722322233794461184321883481989831191858421401529058385608717609471948486505331480282427844359667187865490014911613477
1->10^188: 84999508275236126020381830508721543111473067554541966121589517605650398866751293320363799608712233989549184897359325724581354866372415617540113985299280733097725364579425684134507256488872
1->10^189: 849306296274651882683597422387001923066889384195634499192702671890502375676555190136845726720160747215701213796501622133175006452307225424987441822517508280951544748121555031660346304639001
1->10^190: 8487095911796817623434988696115120825517986522671534265823536015609746863774499420587993803271710140150813684221232159026871093033542365679393034583857094925097687013070985086109793273080806
1->10^191: 84821370246558618609839073367520567864334999557370002647757230099277664105830851234474210899445947000757007737070796386462591548949557365070963572571938326301912601377555644042593381481793406
1->10^192: 847825310704237766880070980506466839658817888477084199818418242818651205859175872441362805453796299246427513786781377975949558744142534256078247658163358081519312966146099874702063865152192028
1->10^193: 8475489555842905339842177447569741889165387333475856347815246130384309138300825424276838743453380208632107646061552066006714782109537135813874993527510102283805650143962763452053420700390547699
1->10^194: 84738701485690450024204013592451605689013445522452704386773936803484296887639018283654199502249150235096649421520132242000546408214958227307607245837895669350870541210854287264223165212086998226
1->10^195: 847339745670078204744803652316933944651393806640268021489971965448240790293322017482045797037713314415845471889231439866706574167693441163081038944023000406430511708854956075209156416422852179500
1->10^196: 8474053834141387286935964031508774220009550200077496813045300456052204100457807211493137607068260269409818097530282626325036633749271383972601174815602843212760330743419406501022962731951260401758
1->10^197: 84758029161467432826119523898351898166282436501022577393790061641703167401164409394596608786688863136133007710604265705419119450632223820509239634351960138619310640443557197024847616720893834274556
1->10^198: 847859155127420710222264067465116270942345054705199086260046652911576677856574523726808872321246548759971208827865770218551918373067777291678034921219960068578854130134085087015093149046394684100436
1->10^199: 8482352079297050413772331207215755280136129216773296221264447386959877587192996245987959911290858363977880814068455839545348484912691954109930202230242025230487816060905500273627824722575046074286281
1->10^200: 84870048617336420197389727058863637424671320482647512598431088512958837365267475929180277480415786149971408009142371369019940386605860817912162814180167542797887574063677218639448400450114606809880493
1->10^201: 849246096864711958382140828789832341037541146449645765069443078515013899970754673189319764864878892878621617974941584582320988065756019066241199502894793046393859712076059928423517853448438863067863226
1->10^202: 8498624925606251826356755549843759984710649122272275679601866626755415511646464540638291701107135708359249734273392831194179172090092563707579355305268689407169443037588913674810901899690254156949367275
1->10^203: 85053974280141213857917842958407824057059580960693420355947997850134934176999635011238282707984566250378973275121221997840304574485093785863913446713844175190847992565857356412233852383266765346485977576
1->10^204: 851267793619122872630161782552104405308466360210406324429007428807568945258070114676614779203675989708980801172282855929544686979305743506670689733623543666749958573824475094895872235404030549992394708150
1->10^205: 8520367073359573551884982418477013557872986932518885258980976615694060910595076784527929984289747991467246665285419316072687197970688845733149905180272321105942958007079330817594754267934705067270350499956
1->10^206: 85283687596660830853502342927042854500321341431910436337225191217936420987092196489885047475301196582960695295636335734026004076930907280217960505685464052960893990657933932574032561361873483568439847208942
1->10^207: 853659202819987541247160120887834521284760886339623274004394773066680299538480440121545335974469636403243323858304782951228852284398676153012813966360440529328380943838264684632008844950545647229432408419763
1->10^208: 8544952483138354272479452096326871415134170280533803383323382424225457971898051136208471099688648406254320867700931409630655569469573762186473633746768288944756293766713800079402839068636993722539464464014343
1->10^209: 85533733751997391022351921893082947709535591919068528290332852883967864327556645461585949789541151338595934256435388217939077881109820952288423214884499900454917289123598440879211618935608105485422232130901905
1->10^210: 856178628495280232427926168171704244059740501955488094383750755874097867668689843542569526012394028099851590049094767507865596216897633456922557606621505076739639542878814850925266187250164585329019683542629923
1->10^211: 8570131419693618760966628804173079377257638567195555240493311797353797176489667120305647330718511690292693777674170531508951053735086796114378779311384689107558641543989958869638931709314824117850451000380143021
1->10^212: 85783575440047109414461631493979767235315177615543985312544659159056610182875530781537114391430809057845669077275617329819355730217516493005290650519511006772034807212815853844586588988998227020982705473135728765
1->10^213: 858642157725030348223249509804854637186812832528125424148240160404301905107061460749243511335395491708297289251008381529398185566019895635547713725083517506594429645460660280089932247894935780442351898303313140945
1->10^214: 8594287902664891352913658993716294858626490086433812797669386361846753520746735854191540089415236757792436360765472598893490276479705293275725004645785633334970346652528315678317371791476569985195862855380417401542
1->10^215: 86019274419595998866603848298462306888943095199436257368964632161654631977139765349618577697513221456293489609436575083556837195728003126429131084775756767513323846022083954060095590650961801996674310643811350499369
1->10^216: 860931655618474553063989578082933761682457487457489431016612890143003640365600635223968806347174143526789184001346670039335478957198921437817108109746919660278785057686592225736631570790200460497279046021138265882633
1->10^217: 8616435837729622438277275972924774728615421337934287445283316837787898004557496433610326251817310796184207726389126647218963569950986844300319174321919640256132751161493356727133356946791128243709978104039611221929848
1->10^218: 86232688597037059510650496264090044650582001854485728865997396326431091394758611347974329812789632648546842598755241789989941130068748668444311151669575147062603211288550024198424668424830168061712646711077510494361276
1->10^219: 862980094753456140909290085044350220214633094993933779019549067941866017572800599010552481547901256759922208947964802924199156525319895138745088257779570795905170294076748630599291864563865074304312620545350757654949167
1->10^220: 8636018033559847409410591107268210323615373240747163973441778682144682091271457867694794590752142037466191114879096481073228275415949941743493243536215269195973060634460249426462226091308923903368436341962027769078827045
1->10^221: 86419056489171874993789903489060892796455772565320723803637734001174467305715397474011039116397479926656101081127323729931224029537185192310507718579127400181923630610893970171709931933408787373551201437680240028108283958
1->10^222: 864744809847891662279169612523698598292488130571716275496525629546147011808378355197408294680827690818106146785428930909260093817332410616456120307490986571108036081906704392578762581319448395342866886631949686317950079685
1->10^223: 8652627854354814142021372274236655285412150520596931780504767483938734335443732380812376622197005225828947530209843225214814025134173901180081812700123059474516130142427254496259962223594226063501914926447312107963923255816
1->10^224: 86574251920745435851516366426371437236500297164193572646840936487152446338309838340335914152667764515000963423743096085244510673418048367379825329583910629778255879869131857325574114859632491805222223301052145753142373402038
1->10^225: 866181808148306233153035741070162251220868553540999914228623747312278276373367606857723265686649243714013350573228296681022846168327651205292941587217634862968933831862883106033509203213506996294508078581405379889390718900884
1->10^226: 8665782332173490493624385682733920863071548417814598549460323221230417435701507196058986103580683262649034387808689514519733914026030490404939317647480340690773539215255948949250489348489232493792231877166169779541100947510992
1->10^227: 86692919814710675783589991859619703285754546114420206472621039807364718363865261702270566986525194821577798634423416768340074070191330534224131123412508988375899005313698308076230449814177068560441644180880325653197748136923185
1->10^228: 867231990206473247052871536000445102504192081962389666619381949130498077603334870783904602961079237586504849633880397962186289424840869477113707180313165669320870472468535571056811158182157681436281093030894644992830298477981244
1->10^229: 8674838596801362677923547970017972903037995901012236697795083419765821418590394410295854079897879829098141309577554554785416139269074776459368918266410283727698808695686584095897235693981445795558726984321580750493111552025864339
1->10^230: 86768211402812128806590576564537513494737520987736487082881857738963221877281843731844788716420658593474347727365894819526796319707828593251356370569187398794672340428112756386987781701631240923503544557476729747177320351749598558
6.0396929 seconds elapsed.</pre>It doesn't always get to 10^230 in six seconds at Tio.run, sometimes it only gets to 10^201 or so.
 
=={{header|C++}}==
Slow (~10 seconds on my machine) brute force C++ implementation:
<langsyntaxhighlight lang="cpp">
#include <iostream>
 
Line 368 ⟶ 922:
return 0;
}
</syntaxhighlight>
</lang>
{{out}}
<pre>85744333</pre>
 
=={{header|C sharp}}==
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.
<lang csharp>using System;
public static class IteratedDigitsSquaring
{
public static void Main() {
Console.WriteLine(Count89s(1_000_000));
Console.WriteLine(Count89s(100_000_000));
}
 
public static int Count89s(int limit) {
if (limit < 1) return 0;
int[] end = new int[Math.Min(limit, 9 * 9 * 9 + 2)];
int result = 0;
 
for (int i = 1; i < end.Length; i++) {
for (end[i] = i; end[i] != 1 && end[i] != 89; end[i] = SquareDigitSum(end[i])) { }
if (end[i] == 89) result++;
}
for (int i = end.Length; i < limit; i++) {
if (end[SquareDigitSum(i)] == 89) result++;
}
return result;
 
int SquareDigitSum(int n) {
int sum = 0;
while (n > 0) {
int digit = n % 10;
sum += digit * digit;
n /= 10;
}
return sum;
}
}
 
}</lang>
{{out}}
<pre>
856929
85744333
</pre>
 
=={{header|Ceylon}}==
<langsyntaxhighlight lang="ceylon">shared void run() {
function digitsSquaredSum(variable Integer n) {
Line 443 ⟶ 954:
}
print(eightyNines);
}</langsyntaxhighlight>
 
=={{header|Clojure}}==
===Direct Method===
<langsyntaxhighlight lang="lisp">(ns async-example.core
(:require [clojure.math.numeric-tower :as math])
(:use [criterium.core])
Line 484 ⟶ 995:
 
(time (println (direct-method 8)))
</syntaxhighlight>
</lang>
{{Output}}
<pre>
Line 491 ⟶ 1,002:
</pre>
===Using Combinations===
<syntaxhighlight lang="lisp">
(def DIGITS (range 0 10))
 
Line 539 ⟶ 1,050:
(println (itertools-comb 8))
;; Time obtained using benchmark library (i.e. (bench (itertools-comb 8)) )
</syntaxhighlight>
</lang>
{{{Output}}
<pre>
Line 546 ⟶ 1,057:
both tested on i7 CPU 920@2.67GHZ)
</pre>
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">
(defun square (number)
(expt number 2))
Line 580 ⟶ 1,092:
(incf count))
:finally (return count)))
</syntaxhighlight>
</lang>
 
{{out}}
Line 593 ⟶ 1,105:
 
*
</pre>
 
=={{header|Craft Basic}}==
<syntaxhighlight lang="basic">for i = 1 to 1000
 
let j = i
 
do
 
let k = 0
 
do
 
let k = int(k + (j % 10) ^ 2)
let j = int(j / 10)
 
wait
 
loop j <> 0
 
let j = k
 
loopuntil j = 89 or j = 1
 
if j > 1 then
 
let n = n + 1
 
endif
 
print "iterations: ", i
 
next i
 
print "count result: ", n
 
end</syntaxhighlight>
 
{{out}}
<pre>
857
</pre>
 
=={{header|D}}==
A simple memoizing partially-imperative brute-force solution:
<langsyntaxhighlight lang="d">import std.stdio, std.algorithm, std.range, std.functional;
 
uint step(uint x) pure nothrow @safe @nogc {
Line 614 ⟶ 1,167:
void main() {
iota(1, 100_000_000).filter!(x => x.iterate == 89).count.writeln;
}</langsyntaxhighlight>
{{out}}
<pre>85744333</pre>
Line 620 ⟶ 1,173:
 
A fast imperative brute-force solution:
<langsyntaxhighlight lang="d">void main() nothrow @nogc {
import core.stdc.stdio: printf;
 
Line 660 ⟶ 1,213:
 
printf("%u\n", magicCount);
}</langsyntaxhighlight>
The output is the same.
The run-time is less than 3 seconds compiled with ldc2.
 
A more efficient solution:
<langsyntaxhighlight lang="d">import core.stdc.stdio, std.algorithm, std.range;
 
enum factorial = (in uint n) pure nothrow @safe @nogc
Line 738 ⟶ 1,291:
 
printf("%u\n", result);
}</langsyntaxhighlight>
The output is the same.
The run-time is about 0.04 seconds or less.
Line 746 ⟶ 1,299:
A purely functional version, from the Haskell code. It includes two functions currently missing in Phobos used in the Haskell code.
{{trans|Haskell}}
<langsyntaxhighlight lang="d">import std.stdio, std.typecons, std.traits, std.typetuple, std.range, std.algorithm;
 
auto divMod(T)(T x, T y) pure nothrow @safe @nogc {
Line 805 ⟶ 1,358:
void main() {
iota(1u, 100_000u).filter!(n => n.iter == 89).count.writeln;
}</langsyntaxhighlight>
With a small back-porting (to run it with the Phobos of LDC2 2.065) it runs in about 15.5 seconds.
 
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,StdCtrls}}
Takes 16 seconds to complete on an a Ryzen 7 Win11 machine
 
<syntaxhighlight lang="Delphi">
function SumSquaredDigits(N: integer): integer;
{Sum the squares of the digits in a number}
var T: integer;
begin
Result:=0;
repeat
begin
T:=N mod 10;
N:=N div 10;
Result:=Result+T*T;
end
until N<1;
end;
 
 
function TestNumber(N: integer): integer;
{Sum the squares of the digits of number, and do it again}
{with tne new number until the result is either 89 or 1}
begin
Result:=N;
repeat Result:=SumSquaredDigits(Result);
until (Result=89) or (Result=1);
end;
 
 
procedure TestSquareDigitsSum(Memo: TMemo);
{Count the number of square digit sums end up 89}
var I,Cnt: integer;
begin
Cnt:=0;
for I:=1 to 100000000 do
if TestNumber(I)=89 then Inc(Cnt);
Memo.Lines.Add(IntToStr(Cnt));
end;
 
</syntaxhighlight>
{{out}}
<pre>
85744333
</pre>
 
 
=={{header|ERRE}}==
<syntaxhighlight lang="erre">
<lang ERRE>
PROGRAM ITERATION
 
Line 828 ⟶ 1,430:
PRINT
END PROGRAM
</syntaxhighlight>
</lang>
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.
<syntaxhighlight lang="factor">USING: kernel math math.ranges math.text.utils memoize
prettyprint sequences tools.time ;
IN: rosetta-code.iterated-digits-squaring
Line 849 ⟶ 1,451:
] loop
drop .
] time</langsyntaxhighlight>
{{out}}
<pre>
85744333
Running time: 55.76544594 seconds
</pre>
=={{header|Forth}}==
<syntaxhighlight lang="forth">
Tested for VFX Forth and GForth in Linux
\ To explain the algorithm: Each iteration is performed in set-count-sumsq below.
\ sum square of digits for 1 digit numbers are
\ Base 1 2 3 4 5 6 7 8 9
\ Sumsq: 1 4 9 16 25 36 49 54 81
\ Adding 10 to the base adds 1 to the sumsq,
\ Adding 20 to the base adds 4
\ ||
\ Adding 90 adds 81
\ Similarly for n00, n000 etc..
 
\ Worked example for base 3 ( to keep the lists short ).
\ The base 10 version performs 1.1 .. 1.9 with shifts of 1, 4, 9 .. 81 cells
\
\ Ix 0 1 2 3 4 5 6 7 8
\ 0 [ 1 ]
\ 1.1 [ 1 ] Previous result shifted 1 cell ( 1**2 )
\ 1.2 [ 1 ] Previous result shifted 4 cells ( 2** 2 )
\ ------------------------------
\ Sum [ 1, 1, 0, 0, 1 ]
\ 2.1 [ 1, 1, 0, 0, 1 ] Previous result shifted 1 cell ( 1**2 )
\ 2.2 [ 1, 1, 0, 0, 1 ] Previous result shifted 4 cells ( 2** 2 )
\ --------------------------------------------
\ Sum [ 1, 2, 1, 0, 2, 2, 0, 0, 1 ] Number of integers with ix as first iteration sum of digits sq
 
CELL 8 * 301 * 1000 / CONSTANT max-digits \ 301 1000 / is log10( 2 )
\ 19 for a 64 bit Forth and 9 for a 32 bit one.
 
\ **********************************
\ **** Create a counted array ****
\ **********************************
 
: counted-array \ create: #elements -- ; does> -- a ;
CREATE
HERE SWAP 1+ CELLS DUP ALLOT ERASE
DOES> ;
 
\ ***********************************
\ **** Array manipulation words. ****
\ ***********************************
 
: arr-copy \ a-src a-dest -- ; \ Copy array array at a-src to array at a-dest
OVER @ 1+ CELLS CMOVE ;
 
: arr-count \ a -- a' ct ;
\ Fetch the count of cells in the array and shift addr to point to element 0.
DUP CELL+ SWAP @ ;
 
: th-element \ a ix -- a' ; \ Leave address of the ix th element of array at a on the stack
1+ CELLS + ;
 
: arr-empty \ a -- ; \ Sets all array elements to zero and zero length
dup @ 1+ CELLS ERASE ;
 
: arr+ \ a-src a-dest count -- ;
\ Add each cell from a-src to the cells from a-dest for count elements
\ Storing the result in a-dest
CELLS 0 DO
OVER I + @ OVER I + +! \ I is a byte count offset into either array
CELL +LOOP
2DROP ; \ DROP the two base addresses
 
: arr. \ a -- ; \ Print the array. Used to debug.
." [ " arr-count CELLS BOUNDS ?DO i @ . CELL +LOOP ." ]" ;
 
\ ***********************************
\ **** Sum digit squared words ****
\ ***********************************
 
: sum-digit-sq \ n -- n' ;
0 SWAP
BEGIN DUP WHILE
10 /MOD >R DUP * + R>
REPEAT DROP ;
 
: 89or1<> \ n -- f ; \ True if n not equal to 89 or 1.
DUP 89 <> AND 1 > ;
 
: iterated-89= \ n -- f ; \ True if n iterates to 89, false once it iterates to 1 ( or 0 ).
BEGIN DUP 89or1<> WHILE
sum-digit-sq
REPEAT 89 = ;
 
\ *****************************************************
\ **** Create `count-sumsq` and `sumsq-old` arrays ****
\ *****************************************************
 
max-digits 81 * 1+ counted-array count-sumsq
max-digits 1- 81 * 1+ counted-array sumsq-old
 
: init-count-sumsq \ -- ; \ Initialise the count-sumsq to [ 1 ]
count-sumsq arr-empty \ Ensure all zero
1 count-sumsq ! \ Set the length of the count-sumsq to 1 cell.
1 count-sumsq 0 th-element ! ; \ Store 1 in the first element.
 
: set-count-sumsq \ #digits -- ; \ The main work. Only called with valid #digits
init-count-sumsq
0 ?DO
count-sumsq sumsq-old arr-copy \ copy count-sumsq to sumsq-old
81 count-sumsq +! \ Extend count-sumsq by 81 (9*9) cells
10 1 DO
sumsq-old arr-count ( a-sumsq-old' len )
count-sumsq I DUP * th-element SWAP arr+
LOOP
LOOP ;
 
: count-89s \ #digits -- n ;
DUP max-digits U> IF
." Number of digits must be between 0 and " max-digits .
DROP 0
ELSE
set-count-sumsq
0 count-sumsq @ 0 DO
count-sumsq I th-element @ ( cum ith-count )
I iterated-89= \ True if the index delivers 89.
AND + \ True is -1 ( all bits set ) AND with the count and add to the cum.
LOOP
THEN ;
 
: test \ #digits :
CR max-digits min 1+ 1 ?DO
I 5 .r 2 SPACES I count-89s . CR
LOOP ;
</syntaxhighlight>
{{out}}
<pre>
19 test
1 7
2 80
3 857
4 8558
5 85623
6 856929
7 8581146
8 85744333
9 854325192
10 8507390852
11 84908800643
12 850878696414
13 8556721999130
14 86229146720315
15 869339034137667
16 8754780882739336
17 87975303595231975
18 881773944919974509
19 8816770037940618762
</pre>
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang="freebasic">' FB 1.05.0 Win64
 
' similar to C Language (first approach)
Line 903 ⟶ 1,654:
Print
Print "Press any key to quit"
Sleep</langsyntaxhighlight>
 
{{out}}
Line 912 ⟶ 1,663:
 
=={{header|Frink}}==
<langsyntaxhighlight lang="frink">
total = 0
d = new dict
Line 943 ⟶ 1,694:
 
println[total]
</syntaxhighlight>
</lang>
 
{{out}}
Line 949 ⟶ 1,700:
85744333
</pre>
 
=={{header|Fōrmulæ}}==
 
{{FormulaeEntry|page=https://formulae.org/?script=examples/Iterated_digits_squaring}}
 
'''Solution'''
 
The following function returns the end value (either 1 or 89) of a given number:
 
[[File:Fōrmulæ - Iterated digits squaring 01.png]]
 
The following function calculates the number of 89 endings, from 1 to a given number:
 
[[File:Fōrmulæ - Iterated digits squaring 02.png]]
 
'''Test case'''
 
[[File:Fōrmulæ - Iterated digits squaring 03.png]]
 
[[File:Fōrmulæ - Iterated digits squaring 04.png]]
 
=={{header|Go}}==
It's basic. Runs in about 30 seconds on an old laptop.
 
<langsyntaxhighlight lang="go">package main
 
import (
Line 982 ⟶ 1,753:
}
fmt.Println(u89)
}</langsyntaxhighlight>
{{out}}
<pre>
Line 990 ⟶ 1,761:
=={{header|Haskell}}==
Basic solution that contains just a little more than the essence of this computation. This runs in less than eight minutes:
<langsyntaxhighlight lang="haskell">import Data.List (unfoldr)
import Data.Tuple (swap)
 
Line 1,002 ⟶ 1,773:
 
main = do
print $ length $ filter ((== 89) . iter) [1 .. 99999999]</langsyntaxhighlight>
{{out}}
<pre>85744333</pre>
Line 1,010 ⟶ 1,781:
Here's an expression to turn a number into digits:
 
<langsyntaxhighlight Jlang="j">digits=: 10&#.inv</langsyntaxhighlight>
 
And here's an expression to square them and find their sum:
<langsyntaxhighlight Jlang="j">sumdigsq=: +/"1@:*:@digits</langsyntaxhighlight>
 
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 ? 145 ? 42 ? 20 ? 4 ? 16 ? 37 ? 58 ? 89, so it only ends with 1 or one of the numbers in this loop. 42 is of course far more significant and the one I would choose!!--[[User:Nigel Galloway|Nigel Galloway]] ([[User talk:Nigel Galloway|talk]]) 10:12, 16 September 2014 (UTC)
:: You should move this comment (and my reply here) to the talk page. --[[User:Rdm|Rdm]] ([[User talk:Rdm|talk]]) 03:01, 26 September 2022 (UTC)
 
<langsyntaxhighlight Jlang="j"> sumdigsq^:(i.16) 15
15 26 40 16 37 58 89 145 42 20 4 16 37 58 89 145</langsyntaxhighlight>
 
Here, after the initial three values, the final digit repeats with a period of 8 (so it does not end).
 
<syntaxhighlight lang=J> 10 8$sumdigsq^:(i.80) 15
15 26 40 16 37 58 89 145
42 20 4 16 37 58 89 145
42 20 4 16 37 58 89 145
42 20 4 16 37 58 89 145
42 20 4 16 37 58 89 145
42 20 4 16 37 58 89 145
42 20 4 16 37 58 89 145
42 20 4 16 37 58 89 145
42 20 4 16 37 58 89 145
42 20 4 16 37 58 89 145</syntaxhighlight>
 
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:
 
<langsyntaxhighlight Jlang="j">itdigsq4=:4 = sumdigsq^:(0=e.&4)^:_"0</langsyntaxhighlight>
 
But we do not actually need to iterate. The largest value after the first iteration would be:
 
<langsyntaxhighlight Jlang="j"> sumdigsq 99999999
648</langsyntaxhighlight>
 
So we could write a routine which works for the intended range, and stops after the first iteration:
<langsyntaxhighlight Jlang="j">itdigsq1=:1 = sumdigsq^:(0=e.&4)^:_"0
digsq1e8=:(I.itdigsq1 i.649) e.~ sumdigsq</langsyntaxhighlight>
 
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,038 ⟶ 1,824:
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:
 
<langsyntaxhighlight Jlang="j"> +/+/@:-.@digsq1e8"1(1+i.100 1e6)
85744333</langsyntaxhighlight>
 
Of course, there are faster ways of obtaining that result. The fastest is probably this:
<langsyntaxhighlight Jlang="j"> 85744333
85744333</langsyntaxhighlight>
 
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.
 
=={{header|Julia}}==
{{works with|Julia|0.6}}
'''Brute force solution''':
<lang julia>function iterate(m::Integer)
while m != 1 && m != 89
s = 0
while m > 0 # compute sum of squares of digits
m, d = divrem(m, 10)
s += d ^ 2
end
m = s
end
return m
end
itercount(k::Integer) = count(x -> iterate(x) == 89, 1:k)</lang>
 
'''More clever solution''':
<lang julia>using Combinatorics
function itercountcombos(ndigits::Integer)
cnt = 0
f = factorial(ndigits)
# loop over all combinations of ndigits decimal digits:
for comb in combinations(1:(10+ndigits-1), ndigits)
s = 0
perms = 1
prevd = -1
rep = 1
for k = eachindex(comb) # sum digits ^ 2 and count permutations
d = comb[k] - k
s += d ^ 2
# accumulate number of permutations of repeated digits
if d == prevd
rep += 1
perms *= rep
else
prevd = d
rep = 1
end
end
if s > 0 && iterate(s) == 89
cnt += f ÷ perms # numbers we can get from digits
end
end
return cnt
end</lang>
 
'''Benchmarks'''
<lang julia>@time itercount(100_000_000)
@time itercountcombos(8)
@time itercountcombos(17)</lang>
{{out}}
<pre> 8.866063 seconds (4.32 k allocations: 232.908 KiB)
0.053470 seconds (101.05 k allocations: 8.729 MiB)
1.588977 seconds (12.50 M allocations: 1.536 GiB, 16.94% gc time)</pre>
 
=={{header|Java}}==
{{works with|Java|8}}
<langsyntaxhighlight lang="java">import java.util.stream.IntStream;
 
public class IteratedDigitsSquaring {
Line 1,127 ⟶ 1,858:
return n;
}
}</langsyntaxhighlight>
 
<pre>85744333</pre>
Line 1,139 ⟶ 1,870:
 
'''Part 1: Foundations'''
<langsyntaxhighlight lang="jq">def factorial: reduce range(2;.+1) as $i (1; . * $i);
 
# Pick n items (with replacement) from the input array,
Line 1,161 ⟶ 1,892:
else . + [[$item, 1]]
end
end ) ;</langsyntaxhighlight>
'''Part 2: The Generic Task'''
 
Count how many number chains beginning with n (where 0 < n < 10^D) end with a value 89.
<langsyntaxhighlight lang="jq">def terminus:
# sum of the squared digits
def ssdigits: tostring | explode | map(. - 48 | .*.) | add;
Line 1,192 ⟶ 1,923:
| if $cache[$ss] then . + ($digits|combinations($Dfactorial))
else .
end) ;</langsyntaxhighlight>
'''Part 3: D=8'''
<syntaxhighlight lang ="jq">task(8)</langsyntaxhighlight>
{{out}}
<langsyntaxhighlight lang="sh">$ jq -M -n -f Iterated_digits_squaring_using_pick.jq
85744333
 
Line 1,205 ⟶ 1,936:
# Using jq 1.4:
# user 0m3.942s
# sys 0m0.009s</langsyntaxhighlight>
 
=={{header|Julia}}==
{{works with|Julia|0.6}}
'''Brute force solution''':
<syntaxhighlight lang="julia">function iterate(m::Integer)
while m != 1 && m != 89
s = 0
while m > 0 # compute sum of squares of digits
m, d = divrem(m, 10)
s += d ^ 2
end
m = s
end
return m
end
itercount(k::Integer) = count(x -> iterate(x) == 89, 1:k)</syntaxhighlight>
 
'''More clever solution''':
<syntaxhighlight lang="julia">using Combinatorics
function itercountcombos(ndigits::Integer)
cnt = 0
f = factorial(ndigits)
# loop over all combinations of ndigits decimal digits:
for comb in combinations(1:(10+ndigits-1), ndigits)
s = 0
perms = 1
prevd = -1
rep = 1
for k = eachindex(comb) # sum digits ^ 2 and count permutations
d = comb[k] - k
s += d ^ 2
# accumulate number of permutations of repeated digits
if d == prevd
rep += 1
perms *= rep
else
prevd = d
rep = 1
end
end
if s > 0 && iterate(s) == 89
cnt += f ÷ perms # numbers we can get from digits
end
end
return cnt
end</syntaxhighlight>
 
'''Benchmarks'''
<syntaxhighlight lang="julia">@time itercount(100_000_000)
@time itercountcombos(8)
@time itercountcombos(17)</syntaxhighlight>
{{out}}
<pre> 8.866063 seconds (4.32 k allocations: 232.908 KiB)
0.053470 seconds (101.05 k allocations: 8.729 MiB)
1.588977 seconds (12.50 M allocations: 1.536 GiB, 16.94% gc time)</pre>
 
=={{header|Kotlin}}==
{{trans|FreeBASIC}}
<langsyntaxhighlight lang="scala">// version 1.0.6
 
fun endsWith89(n: Int): Boolean {
Line 1,244 ⟶ 2,030:
if (endsWith89(i)) count89 += sums[i]
println("There are $count89 numbers from 1 to 100 million ending with 89")
}</langsyntaxhighlight>
 
{{out}}
Line 1,252 ⟶ 2,038:
 
=={{header|Lua}}==
<langsyntaxhighlight lang="lua">squares = {}
 
for i = 0, 9 do
Line 1,298 ⟶ 2,084:
end
 
print(counter)</langsyntaxhighlight>
{{out}}
<pre>85744333</pre>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<langsyntaxhighlight Mathematicalang="mathematica">sumDigitsSquared[n_Integer] := Total[IntegerDigits[n]^2]
stopValues = Join[{1}, NestList[sumDigitsSquared, 89, 7]];
iterate[n_Integer] :=
Line 1,339 ⟶ 2,125:
b}, {_?(MemberQ[iteratesToOne, #] &), _}][[All, 2]]];
 
(10^numberOfDigits - 1) - onesCount</langsyntaxhighlight>
 
{{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.
 
<syntaxhighlight 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 table with values for 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)</syntaxhighlight>
 
{{out}}
<pre>For 8 digits: 85744333
For 50 digits: 869339034137667</pre>
 
=={{header|Oberon-2}}==
{{works with|oo2c Version 2}}
<langsyntaxhighlight lang="oberon2">
MODULE DigitsSquaring;
IMPORT
Line 1,379 ⟶ 2,220:
END DigitsSquaring.
 
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,388 ⟶ 2,229:
sys 0m0.001s
 
</pre>
 
=={{header|Objeck}}==
<syntaxhighlight lang="objeck">class Abbreviations {
function : Main(args : String[]) ~ Nil {
Count89s(1000000)->PrintLine();
Count89s(100000000)->PrintLine();
}
 
function : Count89s(limit : Int) ~ Int {
if(limit < 1) {
return 0;
};
 
result := 0;
ends := Int->New[Int->Min(limit, 9 * 9 * 9 + 2)];
for(i := 1; i < ends->Size(); i++;) {
ends[i] := i;
while(ends[i] <> 1 & ends[i] <> 89) {
ends[i] := SquareDigitSum(ends[i]);
};
if(ends[i] = 89) {
result++;
};
};
 
for(i := ends->Size(); i < limit; i++;) {
if(ends[SquareDigitSum(i)] = 89) {
result++;
};
};
return result;
}
 
function : SquareDigitSum(n : Int) ~ Int {
sum := 0;
while(n > 0) {
digit := n % 10;
sum += digit * digit;
n /= 10;
};
 
return sum;
}
}</syntaxhighlight>
 
Output:
<pre>
856,929
85,744,333
</pre>
 
Line 1,394 ⟶ 2,287:
Brute force implementation
 
<langsyntaxhighlight Oforthlang="oforth">: sq_digits(n)
while (n 1 <> n 89 <> and ) [
0 while(n) [ n 10 /mod ->n dup * + ]
Line 1,400 ⟶ 2,293:
] n ;
 
: iterDigits | i | 0 100000000 loop: i [ i sq_digits 89 &= + ] . ;</langsyntaxhighlight>
 
{{out}}
Line 1,408 ⟶ 2,301:
 
=={{header|PARI/GP}}==
<langsyntaxhighlight lang="parigp">ssd(n)=n=digits(n); sum(i=1, #n, n[i]^2);
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)</langsyntaxhighlight>
{{out}}
<pre>%1 = 85744333</pre>
Line 1,428 ⟶ 2,321:
 
Tested with freepascal.
<langsyntaxhighlight lang="pascal">program Euler92;
const
maxdigCnt = 14;
Line 1,564 ⟶ 2,457:
writeln('there are ',upperlimit-res,' 89s ');
end.
</langsyntaxhighlight>output i3 3.5 Ghz<pre>
10e18
//658 small counts out of 1000000000
Line 1,582 ⟶ 2,475:
 
=={{header|Perl}}==
{{trans|perl6Raku}}
 
<langsyntaxhighlight lang="perl">use warnings;
use strict;
 
Line 1,607 ⟶ 2,500:
}
print $cnt;</langsyntaxhighlight>
 
85744333
 
=={{header|Perl 6}}==
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.
 
<lang perl6>constant @sq = ^10 X** 2;
my $cnt = 0;
 
sub Euler92($n) {
$n == any(1,89) ?? $n !!
(state %){$n} //= Euler92( [+] @sq[$n.comb] )
}
 
for 1 .. 1_000_000 -> $n {
my $i = +$n.comb.sort.join;
++$cnt if Euler92($i) == 89;
}
say $cnt;</lang>
{{out}}
<pre>856929</pre>
All is not lost, however. Through the use of gradual typing, Perl 6 scales down as well as up, so this jit-friendly version is performant enough to brute force the larger calculation:
<lang perl6>my @cache;
@cache[1] = 1;
@cache[89] = 89;
 
sub Euler92(int $n) {
$n < 649 # 99,999,999 sums to 648, so no point remembering more
?? (@cache.AT-POS($n) //= ids($n))
!! ids($n)
}
 
sub ids(int $num --> int) {
my int $n = $num;
my int $ten = 10;
my int $sum = 0;
my int $t;
my int $c;
repeat until $n == 89 or $n == 1 {
$sum = 0;
repeat {
$t = $n div $ten;
$c = $n - $t * $ten;
$sum = $sum + $c * $c;
} while $n = $t;
$n = @cache.AT-POS($sum) // $sum;
}
$n;
}
 
my int $cnt = 0;
for 1 .. 100_000_000 -> int $n {
$cnt = $cnt + 1 if Euler92($n) == 89;
}
say $cnt;</lang>
{{out}}
<pre>85744333</pre>
This runs in under ten minutes. We can reduce this significantly by writing in the NQP (Not Quite Perl6) subset of the language:
<lang perl6>use nqp;
my $cache := nqp::list_i();
nqp::bindpos_i($cache, 650, 0);
nqp::bindpos_i($cache, 1, 1);
nqp::bindpos_i($cache, 89, 89);
 
sub Euler92(int $n) {
$n < 650
?? nqp::bindpos_i($cache,$n,ids($n))
!! ids($n)
}
 
sub ids(int $num --> int) {
my int $n = $num;
my int $ten = 10;
my int $sum = 0;
my int $t;
my int $c;
repeat until $n == 89 or $n == 1 {
$sum = 0;
repeat {
$t = nqp::div_i($n, $ten);
$c = $n - $t * $ten;
$sum = $sum + $c * $c;
} while $n = $t;
$n = nqp::atpos_i($cache,$sum) || $sum;
}
$n;
}
 
my int $cnt = 0;
for 1 .. 100_000_000 -> int $n {
$cnt = $cnt + 1 if Euler92($n) == 89;
}
say $cnt;</lang>
 
=={{header|Phix}}==
{{trans|C}}
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>constant MAXINT = iff(machine_bits()=32?9007199254740992
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
:9223372036854775807)
<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>
 
procedure main(integer limit)
<span style="color: #008080;">procedure</span> <span style="color: #000000;">main</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">limit</span><span style="color: #0000FF;">)</span>
sequence sums = repeat(0,limit*81+1)
<span style="color: #004080;">sequence</span> <span style="color: #000000;">sums</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">limit</span><span style="color: #0000FF;">*</span><span style="color: #000000;">81</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
sums[1] = 1
<span style="color: #000000;">sums</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
for n=1 to limit do
<span style="color: #008080;">for</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">limit</span> <span style="color: #008080;">do</span>
for i=n*81 to 1 by -1 do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">n</span><span style="color: #0000FF;">*</span><span style="color: #000000;">81</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
for j=1 to 9 do
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span>
integer s = j*j
<span style="color: #004080;">integer</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">*</span><span style="color: #000000;">j</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">i1</span><span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">i1ms</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i1</span><span style="color: #0000FF;">-</span><span style="color: #000000;">s</span>
if s>i then exit end if
<span style="color: #008080;">if</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">></span><span style="color: #000000;">i</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
sums[i+1] += sums[i+1-s]
<span style="color: #000000;">sums</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">sums</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i1ms</span><span style="color: #0000FF;">]</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
atom count89 = 0
<span style="color: #004080;">atom</span> <span style="color: #000000;">count89</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
for i=1 to n*81 do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">*</span><span style="color: #000000;">81</span> <span style="color: #008080;">do</span>
integer r, digit, w = i
<span style="color: #004080;">integer</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">digit</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">w</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">i1</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span>
while w!=1 do
<span style="color: #008080;">while</span> <span style="color: #000000;">w</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
r = 0
<span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
while w!=0 do
<span style="color: #008080;">while</span> <span style="color: #000000;">w</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">do</span>
digit = mod(w,10)
<span style="color: #000000;">digit</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">w</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span>
r += digit*digit
<span style="color: #000000;">r</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">digit</span><span style="color: #0000FF;">*</span><span style="color: #000000;">digit</span>
w = floor(w/10)
<span style="color: #000000;">w</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">w</span><span style="color: #0000FF;">/</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span>
end while
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
if r=89 then
<span style="color: #008080;">if</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">=</span><span style="color: #000000;">89</span> <span style="color: #008080;">then</span>
count89 += sums[i+1]
<span style="color: #000000;">count89</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">sums</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i1</span><span style="color: #0000FF;">]</span>
if count89>MAXINT then
<span style="color: #008080;">if</span> <span style="color: #000000;">count89</span><span style="color: #0000FF;">></span><span style="color: #000000;">MAXINT</span> <span style="color: #008080;">then</span>
printf(1,"counter overflow for 10^%d\n",n)
<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;">"counter overflow for 10^%d\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
return
end if <span style="color: #008080;">return</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
exit
end if <span style="color: #008080;">exit</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
w = r
<span style="color: #000000;">w</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r</span>
end while
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
printf(1,"There are %d numbers from 1 to 10^%d ending with 89\n",{count89,n})
<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;">"There are %d numbers from 1 to 10^%d ending with 89\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">count89</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">})</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end procedure
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
 
atom t0 = time()
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span>
main(20)
<span style="color: #000000;">main</span><span style="color: #0000FF;">(</span><span style="color: #000000;">20</span><span style="color: #0000FF;">)</span>
?time()-t0</lang>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span>
<!--</syntaxhighlight>-->
{{out}}
on 32 bit:
Line 1,781 ⟶ 2,584:
I realised I needed to do this in two stages.<br>
Phase 1. Make sure we can count.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>function comb(sequence res, from, integer n, at=1, sequence chosen={})
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
if length(chosen)=n then
<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>
sequence digits = repeat(0,10)
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">n</span> <span style="color: #008080;">then</span>
for i=1 to length(chosen) do
<span style="color: #004080;">sequence</span> <span style="color: #000000;">digits</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span>
digits[chosen[i]+1]+=1
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
end for
<span style="color: #004080;">integer</span> <span style="color: #000000;">idx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">chosen</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">1</span>
atom p = factorial(length(chosen))
<span style="color: #000000;">digits</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">]+=</span><span style="color: #000000;">1</span>
for i=1 to 10 do
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
if digits[i] then
<span style="color: #004080;">atom</span> <span style="color: #000000;">p</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">factorial</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">))</span>
p /= factorial(digits[i])
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">10</span> <span style="color: #008080;">do</span>
end if
<span style="color: #008080;">if</span> <span style="color: #000000;">digits</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
end for
<span style="color: #000000;">p</span> <span style="color: #0000FF;">/=</span> <span style="color: #7060A8;">factorial</span><span style="color: #0000FF;">(</span><span style="color: #000000;">digits</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
res = sq_add(res,{p,1})
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
else
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
for i=at to length(from) do
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sq_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">})</span>
res = comb(res,from,n,i,append(chosen,from[i]))
<span style="color: #008080;">else</span>
end for
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">at</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">set</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
end if
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">comb</span><span style="color: #0000FF;">(</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: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">),</span><span style="color: #000000;">set</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]))</span>
return res
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
 
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
constant nums = {0,1,2,3,4,5,6,7,8,9}
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
for i=1 to 8 do
?comb({0,0},nums,i)
<span style="color: #008080;">constant</span> <span style="color: #000000;">nums</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #000000;">8</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">}</span>
end for</lang>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">do</span>
<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>
<!--</syntaxhighlight>-->
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 1,821 ⟶ 2,628:
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.]
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>sequence is1
<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>
function comb(atom res, sequence from, integer n, at=1, sequence chosen={})
if length(chosen)=n then
<span style="color: #008080;">function</span> <span style="color: #000000;">comb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</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>
sequence digits = repeat(0,10)
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">n</span> <span style="color: #008080;">then</span>
atom sumsq = 0
<span style="color: #004080;">sequence</span> <span style="color: #000000;">digits</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span>
for i=1 to length(chosen) do
<span style="color: #004080;">atom</span> <span style="color: #000000;">sumsq</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
integer ci = chosen[i]
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
sumsq += ci*ci
<span style="color: #004080;">integer</span> <span style="color: #000000;">ci</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">chosen</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
digits[ci+1]+=1
<span style="color: #000000;">sumsq</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">ci</span><span style="color: #0000FF;">*</span><span style="color: #000000;">ci</span>
end for
<span style="color: #000000;">ci</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
if sumsq=0 or is1[sumsq] then
<span style="color: #000000;">digits</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ci</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
atom perms = factorial(length(chosen))
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
for i=1 to 10 do
<span style="color: #008080;">if</span> <span style="color: #000000;">sumsq</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">or</span> <span style="color: #000000;">is1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">sumsq</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
if digits[i] then
<span style="color: #004080;">atom</span> <span style="color: #000000;">perms</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">factorial</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">))</span>
perms /= factorial(digits[i])
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">10</span> <span style="color: #008080;">do</span>
end if
<span style="color: #008080;">if</span> <span style="color: #000000;">digits</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
end for
<span style="color: #000000;">perms</span> <span style="color: #0000FF;">/=</span> <span style="color: #7060A8;">factorial</span><span style="color: #0000FF;">(</span><span style="color: #000000;">digits</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span>
res += perms
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
else
<span style="color: #000000;">res</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">perms</span>
for i=at to length(from) do
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
res = comb(res,from,n,i,append(chosen,from[i]))
<span style="color: #008080;">else</span>
end for
<span style="color: #000000;">chosen</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">)&</span><span style="color: #000000;">0</span>
end if
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">at</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">set</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
return res
<span style="color: #000000;">chosen</span><span style="color: #0000FF;">[$]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">set</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
end function
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">comb</span><span style="color: #0000FF;">(</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: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">)</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
procedure setis1(integer n)
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
is1 = repeat(0,n*81)
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
for i=1 to length(is1) do
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
integer r, digit, w = i
while 1 do
<span style="color: #008080;">procedure</span> <span style="color: #000000;">setis1</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
r = 0
<span style="color: #000000;">is1</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">n</span><span style="color: #0000FF;">*</span><span style="color: #000000;">81</span><span style="color: #0000FF;">)</span>
while w!=0 do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">is1</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
digit = mod(w,10)
<span style="color: #004080;">integer</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">digit</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">w</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span>
r += digit*digit
<span style="color: #008080;">while</span> <span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
w = floor(w/10)
<span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
end while
<span style="color: #008080;">while</span> <span style="color: #000000;">w</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">do</span>
if r=89 then exit end if
<span style="color: #000000;">digit</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">w</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span>
if r=1 then
<span style="color: #000000;">r</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">digit</span><span style="color: #0000FF;">*</span><span style="color: #000000;">digit</span>
is1[i] = 1
<span style="color: #000000;">w</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">w</span><span style="color: #0000FF;">/</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span>
exit
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
end if
<span style="color: #008080;">if</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">=</span><span style="color: #000000;">89</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
w = r
<span style="color: #008080;">if</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
end while
<span style="color: #000000;">is1</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
end for
<span style="color: #008080;">exit</span>
end procedure
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
 
<span style="color: #000000;">w</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r</span>
constant nums = {0,1,2,3,4,5,6,7,8,9}
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
for i=1 to 16 do
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
atom t0 = time()
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
setis1(i)
printf(1,"There are %d numbers from 1 to 10^%d ending with 89 (%3.2fs)\n",{power(10,i)-comb(0,nums,i),i,time()-t0})
<span style="color: #008080;">constant</span> <span style="color: #000000;">nums</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6</span><span style="color: #0000FF;">,</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span><span style="color: #000000;">8</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">}</span>
end for</lang>
<span style="color: #004080;">atom</span> <span style="color: #000000;">t00</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">16</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">setis1</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)</span>
<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;">"There are %d numbers from 1 to 10^%d ending with 89 (%3.2fs)\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">10</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</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;">nums</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">),</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">})</span>
<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>
<!--</syntaxhighlight>-->
{{out}}
Sadly, while still very much faster than brute force, several times slower than the translated from C version.
Line 1,882 ⟶ 2,697:
There are 80 numbers from 1 to 10^2 ending with 89 (0.00s)
There are 857 numbers from 1 to 10^3 ending with 89 (0.00s)
There are 8558 numbers from 1 to 10^4 ending with 89 (0.00s02s)
There are 85623 numbers from 1 to 10^5 ending with 89 (0.02s00s)
There are 856929 numbers from 1 to 10^6 ending with 89 (0.00s02s)
There are 8581146 numbers from 1 to 10^7 ending with 89 (0.02s)
There are 85744333 numbers from 1 to 10^8 ending with 89 (0.02s03s)
There are 854325192 numbers from 1 to 10^9 ending with 89 (0.05s08s)
There are 8507390852 numbers from 1 to 10^10 ending with 89 (0.09s16s)
There are 84908800643 numbers from 1 to 10^11 ending with 89 (0.17s31s)
There are 850878696414 numbers from 1 to 10^12 ending with 89 (0.34s61s)
There are 8556721999130 numbers from 1 to 10^13 ending with 89 (01.58s16s)
There are 86229146720315 numbers from 1 to 10^14 ending with 89 (02.92s16s)
There are 869339034137667 numbers from 1 to 10^15 ending with 89 (13.66s77s)
There are 87547808827393378754780882739336 numbers from 1 to 10^16 ending with 89 (26.75s59s)
"15s"
</pre>
 
=={{header|PicoLisp}}==
Brute force with caching
<langsyntaxhighlight PicoLisplang="picolisp">(de *Idx1or89 (89 . 89) ((1 . 1)))
 
(de 1or89 (N)
Line 1,907 ⟶ 2,723:
(prog1
(1or89 N)
(idx '*Idx1or89 (cons N @) T) ) ) ) )</langsyntaxhighlight>
Test:
<langsyntaxhighlight PicoLisplang="picolisp">(let Ones 0
(for I 100000000
(and (=1 (1or89 I)) (inc 'Ones)) )
(println (- 100000000 Ones)) )</langsyntaxhighlight>
Output:
<pre>85744333</pre>
 
=={{header|PL/I}}==
<syntaxhighlight lang="pl/i">
<lang PL/I>
test: procedure options (main, reorder); /* 6 August 2015 */
 
Line 1,947 ⟶ 2,763:
 
end test;
</syntaxhighlight>
</lang>
Output:
<pre>
Line 1,956 ⟶ 2,772:
=={{header|PureBasic}}==
{{Trans|C}}
<langsyntaxhighlight lang="purebasic">OpenConsole()
Procedure is89(x)
Repeat
Line 1,993 ⟶ 2,809:
main()
Print("elapsed milliseconds= "+Str(ElapsedMilliseconds()-start))
Input()</langsyntaxhighlight>
{{out}}
<pre>1->10^1 : 7
Line 2,017 ⟶ 2,833:
elapsed milliseconds= 9</pre>
{{Trans|C++}}
<langsyntaxhighlight lang="purebasic">OpenConsole()
Procedure sum_square_digits(n)
num=n : sum=0
Line 2,047 ⟶ 2,863:
main()
Print("elapsed milliseconds: "+Str(ElapsedMilliseconds()-start))
Input()</langsyntaxhighlight>
{{out}}
<pre>85744333
Line 2,056 ⟶ 2,872:
====Translation of D====
{{trans|D}}
<langsyntaxhighlight lang="python">from math import ceil, log10, factorial
 
def next_step(x):
Line 2,111 ⟶ 2,927:
print result
 
main()</langsyntaxhighlight>
{{out}}
85744333
Line 2,117 ⟶ 2,933:
====Translation of Ruby====
{{trans|Ruby}}
<syntaxhighlight lang="python">
<lang ruby>
from itertools import combinations_with_replacement
from array import array
Line 2,160 ⟶ 2,976:
print "\nD==" + str(D) + "\n " + str(z) + " numbers produce 1 and " + str(10**D-z) + " numbers produce 89"
print "Time ~= " + str(ee) + " secs"
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,181 ⟶ 2,997:
 
===Python: Simple caching===
<langsyntaxhighlight lang="python">>>> from functools import lru_cache
>>> @lru_cache(maxsize=1024)
def ids(n):
Line 2,194 ⟶ 3,010:
>>> sum(ids(x) == 89 for x in range(1, 100000000))
85744333
>>> </langsyntaxhighlight>
 
This took a much longer time, in the order of hours.
Line 2,200 ⟶ 3,016:
===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.
<langsyntaxhighlight lang="python">>>> from functools import lru_cache
>>> @lru_cache(maxsize=1024)
def _ids(nt):
Line 2,218 ⟶ 3,034:
>>> _ids.cache_info()
CacheInfo(hits=99991418, misses=5867462, maxsize=1024, currsize=1024)
>>> </langsyntaxhighlight>
 
This took tens of minutes to run.
Line 2,224 ⟶ 3,040:
===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.
<langsyntaxhighlight lang="python">from __future__ import print_function
from itertools import count
 
Line 2,243 ⟶ 3,059:
 
x = sum(a[i] for i in range(len(a)) if is89[i])
print("10^%d" % n, x)</langsyntaxhighlight>
 
=={{header|QBasic}}==
{{works with|QBasic}}
{{works with|QuickBasic}}
{{trans|BBC BASIC}}
<syntaxhighlight lang="qbasic">REM Version 1: Brute force
 
T = TIMER
n1 = 0
FOR i = 1 TO 10000000
j = i
DO
k = 0
DO
k = INT(k + (j MOD 10) ^ 2)
j = INT(j / 10)
LOOP WHILE j <> 0
j = k
LOOP UNTIL j = 89 OR j = 1
IF j > 1 THEN n1 = n1 + 1
NEXT i
PRINT USING "Version 1: ####### in ##.### seconds."; n1; (TIMER - T)
END</syntaxhighlight>
 
 
=={{header|Quackery}}==
 
<syntaxhighlight lang="quackery">[ abs 0 swap
[ base share /mod
dup *
rot + swap
dup 0 = until ]
drop ] is digitsquaresum ( n --> n )
 
[ dup 1 != while
dup 89 != while
digitsquaresum
again ] is chainends ( n --> n )
0 1000000 times
[ i^ 1+ chainends
89 = + ]
echo</syntaxhighlight>
 
{{out}}
 
<pre>856929</pre>
 
=={{header|Racket}}==
Line 2,249 ⟶ 3,112:
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.
 
<langsyntaxhighlight lang="racket">#lang racket
;; Tim-brown 2014-09-11
 
Line 2,344 ⟶ 3,207:
(length (all-digit-lists 3)) => 220
(count-89s-in-100... 1000000) => 856929]
}</langsyntaxhighlight>
 
{{out}}
Line 2,365 ⟶ 3,228:
 
Ok, so maybe 131 seconds is not so flattering -- but I have not memoised or anything fancy like that, because even doing that isn't going to come anywhere near competing with 44ms.
 
=={{header|Raku}}==
(formerly Perl 6)
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.
 
<syntaxhighlight lang="raku" line>constant @sq = ^10 X** 2;
my $cnt = 0;
 
sub Euler92($n) {
$n == any(1,89) ?? $n !!
(state %){$n} //= Euler92( [+] @sq[$n.comb] )
}
 
for 1 .. 1_000_000 -> $n {
my $i = +$n.comb.sort.join;
++$cnt if Euler92($i) == 89;
}
say $cnt;</syntaxhighlight>
{{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:
<syntaxhighlight lang="raku" line>my @cache;
@cache[1] = 1;
@cache[89] = 89;
 
sub Euler92(int $n) {
$n < 649 # 99,999,999 sums to 648, so no point remembering more
?? (@cache.AT-POS($n) //= ids($n))
!! ids($n)
}
 
sub ids(int $num --> int) {
my int $n = $num;
my int $ten = 10;
my int $sum = 0;
my int $t;
my int $c;
repeat until $n == 89 or $n == 1 {
$sum = 0;
repeat {
$t = $n div $ten;
$c = $n - $t * $ten;
$sum = $sum + $c * $c;
} while $n = $t;
$n = @cache.AT-POS($sum) // $sum;
}
$n;
}
 
my int $cnt = 0;
for 1 .. 100_000_000 -> int $n {
$cnt = $cnt + 1 if Euler92($n) == 89;
}
say $cnt;</syntaxhighlight>
{{out}}
<pre>85744333</pre>
Which is better, but is still pretty slow.
 
The biggest gains are often from choosing the right algorithm.
 
<syntaxhighlight lang="raku" line>sub endsWithOne($n --> Bool) {
my $digit;
my $sum = 0;
my $nn = $n;
loop {
while $nn > 0 {
$digit = $nn % 10;
$sum += $digit²;
$nn = $nn div 10;
}
return True if $sum == 1;
return False if $sum == 89;
$nn = $sum;
$sum = 0;
}
}
 
my $k = 8; # 10**8
my @sums is default(0) = 1,0;
my $s;
for 1 .. $k -> $n {
for $n*81 … 1 -> $i {
for 1 .. 9 -> $j {
$s = $j²;
last if $s > $i;
@sums[$i] += @sums[$i - $s];
}
}
}
 
my $ends-with-one = sum flat @sums[(1 .. $k*81).grep: { endsWithOne($_) }], +endsWithOne(10**$k);
 
say 10**$k - $ends-with-one;</syntaxhighlight>
 
{{out}}
<pre>85744333</pre>
 
=={{header|REXX}}==
{Both REXX versions don't depend on a specific end─numberend-number.}
===with memoization===
<langsyntaxhighlight lang="rexx">/*REXX program performs the squaring of iterated digits (until the sum equals 1 or 89).*/
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 short─cutshort-cut for the squares. */
a.=.; #.=!. /*intermediate counts of some numbers. */
do j=1 for n; x=j /* [?] process the numbers in the range*/
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 ··· */ /* [?] S≡isS=is sum of the squared digits.*/
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*/ /* [?] keep looping 'til S= 1 or 89.*/
do f=1 for q; _=a.f; a._=s /*use the auxiliary arrays (for lookup)*/
end /*f*/
Line 2,390 ⟶ 3,350:
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. */</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default input:}}
<br>(ten million)
Line 2,400 ⟶ 3,360:
===process in chunks===
This version is about &nbsp; <big> 2½ </big> &nbsp; times faster than the previous REXX version.
<langsyntaxhighlight lang="rexx">/*REXX program performs the squaring of iterated digits (until the sum equals 1 or 89).*/
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 short─cutshort-cut for the squares. */
$.=.; $.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) /* [?] process each number in a range.*/
#.s=#.s + 1 /*bump the counter for 1's or 89's. */
end /*j*/
Line 2,414 ⟶ 3,374:
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 4─byte4-byte chunk of the number.*/
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 ···*/ /* [?] A = is the sum of squared digs*/
@.oy=a /*mark original Y as being summed. */
end
else a=@.y /*use the pre─summedpre-summed digits of Y. */
p=p + a /*add all the parts of number together.*/
end /*m*/
Line 2,435 ⟶ 3,395:
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 ···*/ /* [?] S = is sum of the squared digs.*/
y=s /*substitute the sum for a "new" X. */
end /*until s ···*/ /* [?] keep looping 'til S=1 or 89.*/
$.p=s /*use this for memoization for the sum.*/
return s</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the input of: &nbsp; <tt> 100000000 </tt>}}
<br>(one hundred million)
Line 2,448 ⟶ 3,408:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
nr = 1000
num = 0
Line 2,459 ⟶ 3,419:
next
see "Total under 1000 is : " + num + nl
</syntaxhighlight>
</lang>
Output:
<pre>
Line 2,503 ⟶ 3,463:
Total under 1000 is : 41
</pre>
 
=={{header|RPL}}==
{{trans|C}}
The <code>IS89?</code> subroutine handles unsigned integers rather than floating point numbers: it is a little bit longer, but rounding errors are then avoided.
{{works with|Halcyon Calc|4.2.9}}
{| class="wikitable" ≪
! RPL code
! Comment
|-
|
≪ { # 1d # 89d } → goal
≪ R→B '''DO'''
0 SWAP
'''WHILE''' DUP # 0d ≠ '''REPEAT'''
DUP 10 / SWAP OVER 10 * -
DUP * ROT + SWAP
'''END''' DROP
'''UNTIL''' goal OVER POS '''END'''
# 89d ==
≫ ≫ '<span style="color:blue">IS89?</span>' STO
≪ → ndig
≪ { } ndig 81 * 1 + + 0 CON 1 1 PUT '<span style="color:green">SUMS</span>' STO
1 ndig '''FOR''' n
n 81 * 1 '''FOR''' ii
1 9 '''FOR''' j
j SQ
'''IF''' DUP ii > '''THEN''' DROP 9 'j' STO
'''ELSE'''
<span style="color:green">SUMS</span> ii 1 + GET LAST 4 ROLL - GET +
'<span style="color:green">SUMS</span>' ii 1 + ROT PUT
'''END'''
'''NEXT''' -1 '''STEP NEXT'''
0
2 <span style="color:green">SUMS</span> SIZE 1 GET '''FOR''' j
'''IF''' j 1 - <span style="color:blue">IS89?</span> '''THEN''' SUMS j GET + '''END NEXT'''
≫ ≫ '<span style="color:blue">CNT89</span>' STO
|
<span style="color:blue">IS89?</span> ''( x → boolean )''
convert to integer and loop
s = 0
while x ≠ 0
get last digit
square it and add it to s
clean stack
until x = 1 or x = 89
return boolean
<span style="color:blue">CNT89</span> ''( nb_digits → count )''
sums[32*81 + 1] = {1, 0};
for (int n = 1; ; n++) {
for (int i = n*81; i; i--) {
for (int j = 1; j < 10; j++) {
int s = j*j;
if (s > i) break;
sums[i+1] += sums[i-s+1];
count89 = 0;
for (int j = 1; j < n*81 + 1; j++) {
if (!js89(i)) continue; count89 += sums[j+1];
}
|}
8 <span style="color:blue">CNT89</span>
{{out}}
<pre>
1: 85744333
</pre>
Runs in 49 seconds on a iPhone Xr. A basic HP-28 needs 930 seconds for <code>3 CNT89</code>, giving 85, whilst the emulator needs only 5 seconds, meaning that the 8 digits would probably need 2 h 30 on the HP-28.
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby"># Count how many number chains for Natural Numbers < 10**d end with a value of 1.
def iterated_square_digit(d)
f = Array.new(d+1){|n| (1..n).inject(1, :*)} #Some small factorials
g = -> (n) { res = 0n.digits.sum{|d| d*d}
whileres==89 ? n>0 : res }
n, mod = n.divmod(10)
res += mod**2
end
res==89 ? 0 : res
}
#An array: table[n]==0 means that n translates to 89 and 1 means that n translates to 1
Line 2,534 ⟶ 3,561:
iterated_square_digit(d)
puts " #{Time.now - t0} sec"
end</langsyntaxhighlight>
 
{{out}}
Line 2,554 ⟶ 3,581:
24.337392 sec
</pre>
 
 
=={{header|Rust}}==
Line 2,562 ⟶ 3,588:
 
'''Naive Recursion'''
<langsyntaxhighlight lang="rust">fn digit_square_sum(mut num: usize) -> usize {
let mut sum = 0;
while num != 0 {
Line 2,581 ⟶ 3,607:
let count = (1..100_000_000).filter(|&n| last_in_chain(n) == 89).count();
println!("{}", count);
}</langsyntaxhighlight>
{{out}}
<pre>85744333</pre>
Line 2,587 ⟶ 3,613:
 
'''With precomputation'''
<langsyntaxhighlight lang="rust">fn dig_sq_sum(mut num : usize ) -> usize {
let mut sum = 0;
while num != 0 {
Line 2,608 ⟶ 3,634:
let count = (1..100_000_000).filter(|&n| prec[dig_sq_sum(n)] == 89).count();
println!("{}", count);
}</langsyntaxhighlight>
Runtime: 1.7s on a 2500k @ 4Ghz
{{out}}
Line 2,616 ⟶ 3,642:
===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.
<langsyntaxhighlight Scalalang="scala">import scala.annotation.tailrec
 
object Euler92 extends App {
Line 2,658 ⟶ 3,684:
println(s"Runtime recursive loop. [total ${compat.Platform.currentTime - executionStart0} ms]")
 
}</langsyntaxhighlight>
 
=={{header|Sidef}}==
<syntaxhighlight lang="ruby">func digit_square_sum_iter(n) is cached {
 
if ((n == 1) || (n == 89)) {
return n
}
 
__FUNC__(n.digits.sum { .sqr })
}
 
say (1..1e6 -> count_by { digit_square_sum_iter(_) == 89 })</syntaxhighlight>
{{out}}
<pre>
856929
</pre>
 
=={{header|Swift}}==
Line 2,666 ⟶ 3,708:
With nth power support.
 
<langsyntaxhighlight lang="swift">import BigInt
 
func is89(_ n: Int) -> Bool {
Line 2,718 ⟶ 3,760:
}
 
iterSquare(upToPower: 8)</langsyntaxhighlight>
 
{{out}}
Line 2,733 ⟶ 3,775:
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===
<langsyntaxhighlight lang="tcl">proc ids n {
while {$n != 1 && $n != 89} {
set n [tcl::mathop::+ {*}[lmap x [split $n ""] {expr {$x**2}}]]
Line 2,742 ⟶ 3,784:
incr count [expr {[ids $i] == 89}]
}
puts $count</langsyntaxhighlight>
===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).
<langsyntaxhighlight lang="tcl">proc ids n {
while {$n != 1 && $n != 89} {
for {set m 0} {$n} {set n [expr {$n / 10}]} {
Line 2,757 ⟶ 3,799:
incr count [expr {[ids $i] == 89}]
}
puts $count</langsyntaxhighlight>
===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)
<langsyntaxhighlight lang="tcl"># Basic implementation
proc ids n {
while {$n != 1 && $n != 89} {
Line 2,793 ⟶ 3,835:
}
puts $count
}}</langsyntaxhighlight>
 
=={{header|VBScript}}==
<syntaxhighlight lang="vb">
<lang vb>
start_time = Now
cnt = 0
Line 2,817 ⟶ 3,859:
WScript.Echo "Elapse Time: " & DateDiff("s",start_time,end_time) &_
vbCrLf & "Count: " & cnt
</syntaxhighlight>
</lang>
 
{{Out}}
Line 2,825 ⟶ 3,867:
Count: 85744333
</pre>
 
=={{header|Wren}}==
{{trans|FreeBASIC}}
<syntaxhighlight lang="wren">var endsWith89 = Fn.new { |n|
var digit = 0
var sum = 0
while (true) {
while (n > 0) {
digit = n % 10
sum = sum + digit*digit
n = (n/10).floor
}
if (sum == 89) return true
if (sum == 1) return false
n = sum
sum = 0
}
}
 
var start = System.clock
var sums = List.filled(8*81 + 1, 0)
sums[0] = 1
sums[1] = 0
var s = 0
for (n in 1..8) {
for (i in n*81..1) {
for (j in 1..9) {
s = j * j
if (s > i) break
sums[i] = sums[i] + sums[i-s]
}
}
if (n == 8) {
var count89 = 0
for (i in 1..n*81) {
if (endsWith89.call(i)) count89 = count89 + sums[i]
}
System.print("There are %(count89) numbers from 1 to 100 million ending with 89.")
}
}
System.print("Took %(((System.clock - start)*1000).round) milliseconds.")</syntaxhighlight>
 
{{out}}
Timing for Intel Core i7-8565U machine running Ubuntu 18.04.
<pre>
There are 85744333 numbers from 1 to 100 million ending with 89.
Took 4 milliseconds.
</pre>
 
=={{header|X86 Assembly}}==
{{works with|nasm}}
<syntaxhighlight lang="asm">
section .data
count dd 0
section .text
global _main
_main:
mov ecx, 1
looping:
mov eax, ecx ;pass parameter in eax
push ecx
call doMath
pop ecx
add [count], eax ;doMath returns 0 or 1 in eax
inc ecx
cmp ecx, 100000001
jl looping
mov eax, count ;returns memory address of count
ret
addSquaredDigits:
push ebx
mov ebx, 0
mov esi, 10
looping2:
xor edx, edx ;clear edx for division
div esi ;div by 10 to get last digit in edx
mov ecx, eax ;save parameter
mov eax, edx ; get last digit
mul eax ;square last digit
add ebx, eax ;add the square to the result
jecxz aSDend ;if the parameter is 0 we have all digits
mov eax, ecx ;restore parameter before looping
jmp looping2
aSDend:
mov eax, ebx ;move result to return register
pop ebx
ret
doMath:
looping3:
call addSquaredDigits ;do until eax is 89 or 1
cmp eax, 89
je ret1
cmp eax, 1
je ret0
jmp looping3
ret1: ;if eax == 89 we return 1 -> inc count
mov eax, 1
ret
ret0: ;if eax == 1 we return 0 -> don't inc count
mov eax, 0
ret
</syntaxhighlight>
 
=={{header|XPL0}}==
Simple minded brute force takes 30 seconds on Pi4.
<syntaxhighlight lang "XPL0">int C, N, M, S;
[C:= 0;
for N:= 1 to 100_000_000-1 do
[M:= N;
loop [S:= 0;
repeat M:= M/10;
S:= S + rem(0)*rem(0);
until M = 0;
if S = 89 then
[C:= C+1; quit];
if S = 1 then quit;
M:= S;
];
];
IntOut(0, C);
]</syntaxhighlight>
{{out}}
<pre>
85744333</pre>
 
=={{header|zkl}}==
Line 2,831 ⟶ 4,000:
{{trans|D}}
{{trans|http://www.mathblog.dk/project-euler-92-square-digits-number-chain/}}
<langsyntaxhighlight lang="zkl">fcn check(number){ // a list of digits: 13 is L(0,0,0,0,0,0,1,3)
candidate:=number.reduce(fcn(sum,n){ sum*10 + n },0); // digits to int
 
Line 2,862 ⟶ 4,031:
}
}
println(result);</langsyntaxhighlight>
{{out}}
<pre>85744333</pre>
Line 2,869 ⟶ 4,038:
{{trans|BBC_BASIC}}
Very, very slow. Use a ZX Spectrum emulator and run with maximum speed option enabled.
<langsyntaxhighlight lang="zxbasic">10 LET n=0
20 FOR i=1 TO 1000
30 LET j=i
Line 2,882 ⟶ 4,051:
110 NEXT i
120 PRINT "Version 1: ";n
200 DEF FN m(a,b)=a-INT (a/b)*b: REM modulo</langsyntaxhighlight>
{{out}}
<pre>Version 1: 857</pre>
2,120

edits