Iterated digits squaring: Difference between revisions

lang -> syntaxhighlight
m (→‎{{header|Oberon-2}}: Added missing '}' at end of 'works with' template which was causing a number of entries to be hidden.)
(lang -> syntaxhighlight)
Line 7:
An example in Python:
 
<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 32:
{{trans|Python}}
 
<langsyntaxhighlight lang=11l>F next_step(=x)
V result = 0
L x > 0
Line 82:
result += check(number)
 
print(result)</langsyntaxhighlight>
 
{{out}}
Line 90:
 
=={{header|Ada}}==
<langsyntaxhighlight lang=Ada>with Ada.Text_IO;
 
procedure Digits_Squaring is
Line 129:
end loop;
Put_Line ("In range 1 .. 99_999_999: " & Count'Image);
end Digits_Squaring;</langsyntaxhighlight>
 
{{out}}
Line 137:
=={{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 185:
OD;
 
print( ( "Number of values whose squared digit sum is 89: ", whole( count 89, -10 ), newline ) )</langsyntaxhighlight>
{{out}}
<pre>
Line 193:
=={{header|Arturo}}==
{{trans|Nim}}
<langsyntaxhighlight lang=rebol>gen: function [n][
result: n
while [not? in? result [1 89]][
Line 233:
"Number chains for integers <100000000 that end with an 89 value:"
chainsEndingWith89 8
]</langsyntaxhighlight>
 
{{out}}
Line 241:
=={{header|AWK}}==
We use a brute-force approach with buffering for better performance. Numbers are assumed to be double precision floats, which is true for most implementations. It runs in about 320 s on an Intel i5.
<langsyntaxhighlight lang=AWK># Usage: GAWK -f ITERATED_DIGITS_SQUARING.AWK
BEGIN {
# Setup buffer for results up to 9*9*8
Line 268:
}
return r
}</langsyntaxhighlight>
{{out}}
<pre>
Line 285:
{{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 342:
PRINT "Version 3: ";N% " in ";(TIME-T%)/100 " seconds."
 
END</langsyntaxhighlight>
{{out}}
<pre>
Line 353:
This is just a brute force solution, so it's not very fast. A decent interpreter will probably take a minute or two for a 1,000,000 iterations. If you want to test with 100,000,000 iterations, change the <tt>::**</tt> (100³) near the end of the first line to <tt>:*:*</tt> (100²<sup>²</sup>). With that many iterations, though, you'll almost certainly want to be using a compiler, otherwise you'll be waiting a long time for the result.
 
<langsyntaxhighlight lang=befunge>1-1\10v!:/+55\<>::**>>-!|
v0:\+<_:55+%:*^^"d":+1$<:
>\`!#^ _$:"Y"-#v_$\1+\:^0
>01-\0^ @,+55.<>:1>-!>#^_
>,,,$." >=",,,^ >>".1">#<</langsyntaxhighlight>
 
{{out}}
Line 369:
A simple solution is to compute all square-digit sums in the desired range as an addition table, then repeatedly select from this list using itself as an index so that all values that end at 1 converge (those that reach 89 will find some point in the cycle, but not always the same one).
 
<langsyntaxhighlight lang=bqn> +´1↓1≠1?1? ⊏˜⍟?˜?(⌈2⋆⁼≠?2???) ?+?´6⥊6?<ט↕10ט?10
856929</langsyntaxhighlight>
 
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⋆𝕩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.
 
<langsyntaxhighlight lang=bqn>DigSq ? {
d ? ט ↕10?10 # Digit values
m ? 1+81×2⌈𝕩81×2??? # One plus maximum digit sum
c ? (+´ d ⥊⟜0⊸??0?»¨ <)⍟𝕩??? m↑⥊1m??1 # Count of numbers having each sum
s ? m ? ? d +⌜⍟??(⌈10⋆⁼m?10??m) 0 # Sum for each sum
e ? 1≠⊏˜⍟1??˜?(⌈2⋆⁼≠?2???)s # Which sums end at 89
¯1 +´ c×e # Total up; subtract 1 to exclude 0
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang=bqn> >⋈⟜DigSq??DigSq¨ 1+↕16?16
┌─+-
? 1 7
2 80
3 857
Line 401:
15 869339034137667
16 8754780882739336
+</langsyntaxhighlight>
 
=={{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 451:
 
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>
Line 476:
</pre>
Fast C implementation (<1 second my machine), which performs iterated digits squaring only once for each unique 8 digit combination. The cases 0 and 100,000,000 are ignored since they don't sum to 89:
<syntaxhighlight lang=c>
<lang c>
#include <stdio.h>
 
Line 559:
return 0;
}
</syntaxhighlight>
</lang>
{{out}}
<pre>85744333</pre>
Line 566:
The largest sum possible for any number is 9*9*9, so the first 730 numbers are calculated and stored in an array.<br/>
The rest is then looked up. A limit of 100 million takes about 6 seconds. int.MaxValue takes about 2 and a half minutes.
<langsyntaxhighlight lang=csharp>using System;
public static class IteratedDigitsSquaring
{
Line 599:
}
 
}</langsyntaxhighlight>
{{out}}
<pre>
Line 610:
{{Libheader|System.Numerics}}
Translation of the first C version, with BigIntegers. This can get pretty far in six seconds, even on Tio.run.
<langsyntaxhighlight lang=csharp>using System;
using System.Numerics;
 
Line 647:
Console.WriteLine("{0} seconds elapsed.", (DateTime.Now - st).TotalSeconds);
}
}</langsyntaxhighlight>
{{out}}
<pre style="height:30ex;overflow:scroll">1->10^1 : 7
Line 883:
=={{header|C++}}==
Slow (~10 seconds on my machine) brute force C++ implementation:
<langsyntaxhighlight lang=cpp>
#include <iostream>
 
Line 921:
return 0;
}
</syntaxhighlight>
</lang>
{{out}}
<pre>85744333</pre>
 
=={{header|Ceylon}}==
<langsyntaxhighlight lang=ceylon>shared void run() {
function digitsSquaredSum(variable Integer n) {
Line 953:
}
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 994:
 
(time (println (direct-method 8)))
</syntaxhighlight>
</lang>
{{Output}}
<pre>
Line 1,001:
</pre>
===Using Combinations===
<syntaxhighlight>
<lang>
(def DIGITS (range 0 10))
 
Line 1,049:
(println (itertools-comb 8))
;; Time obtained using benchmark library (i.e. (bench (itertools-comb 8)) )
</syntaxhighlight>
</lang>
{{{Output}}
<pre>
Line 1,058:
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang=lisp>
(defun square (number)
(expt number 2))
Line 1,091:
(incf count))
:finally (return count)))
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,108:
=={{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 1,125:
void main() {
iota(1, 100_000_000).filter!(x => x.iterate == 89).count.writeln;
}</langsyntaxhighlight>
{{out}}
<pre>85744333</pre>
Line 1,131:
 
A fast imperative brute-force solution:
<langsyntaxhighlight lang=d>void main() nothrow @nogc {
import core.stdc.stdio: printf;
 
Line 1,171:
 
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 1,249:
 
printf("%u\n", result);
}</langsyntaxhighlight>
The output is the same.
The run-time is about 0.04 seconds or less.
Line 1,257:
A purely functional version, from the Haskell code. It includes two functions currently missing in Phobos used in the Haskell code.
{{trans|Haskell}}
<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 1,316:
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|ERRE}}==
<langsyntaxhighlight lang=ERRE>
PROGRAM ITERATION
 
Line 1,339:
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.
<langsyntaxhighlight>USING: kernel math math.ranges math.text.utils memoize
prettyprint sequences tools.time ;
IN: rosetta-code.iterated-digits-squaring
Line 1,360:
] loop
drop .
] time</langsyntaxhighlight>
{{out}}
<pre>
Line 1,367:
</pre>
=={{header|Forth}}==
<langsyntaxhighlight lang=forth>
Tested for VFX Forth and GForth in Linux
\ To explain the algorithm: Each iteration is performed in set-count-sumsq below.
Line 1,491:
I 5 .r 2 SPACES I count-89s . CR
LOOP ;
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,517:
 
=={{header|FreeBASIC}}==
<langsyntaxhighlight lang=freebasic>' FB 1.05.0 Win64
 
' similar to C Language (first approach)
Line 1,563:
Print
Print "Press any key to quit"
Sleep</langsyntaxhighlight>
 
{{out}}
Line 1,572:
 
=={{header|Frink}}==
<langsyntaxhighlight lang=frink>
total = 0
d = new dict
Line 1,603:
 
println[total]
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,610:
</pre>
 
=={{header|FōrmulæFormulæ}}==
 
FōrmulæFormulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation &mdash;i.e. XML, JSON&mdash; they are intended for storage and transfer purposes more than visualization and edition.
 
Programs in FōrmulæFormulæ are created/edited online in its [https://formulae.org website], However they run on execution servers. By default remote servers are used, but they are limited in memory and processing power, since they are intended for demonstration and casual use. A local server can be downloaded and installed, it has no limitations (it runs in your own computer). Because of that, example programs can be fully visualized and edited, but some of them will not run if they require a moderate or heavy computation/memory resources, and no local server is being used.
 
In '''[https://formulae.org/?example=Iterated_digits_squaring this]''' page you can see the program(s) related to this task and their results.
Line 1,621:
It's basic. Runs in about 30 seconds on an old laptop.
 
<langsyntaxhighlight lang=go>package main
 
import (
Line 1,650:
}
fmt.Println(u89)
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,658:
=={{header|Haskell}}==
Basic solution that contains just a little more than the essence of this computation. This runs in less than eight minutes:
<langsyntaxhighlight lang=haskell>import Data.List (unfoldr)
import Data.Tuple (swap)
 
Line 1,670:
 
main = do
print $ length $ filter ((== 89) . iter) [1 .. 99999999]</langsyntaxhighlight>
{{out}}
<pre>85744333</pre>
Line 1,678:
Here's an expression to turn a number into digits:
 
<langsyntaxhighlight lang=J>digits=: 10&#.inv</langsyntaxhighlight>
 
And here's an expression to square them and find their sum:
<langsyntaxhighlight lang=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)
 
<langsyntaxhighlight lang=J> sumdigsq^:(i.16) 15
15 26 40 16 37 58 89 145 42 20 4 16 37 58 89 145</langsyntaxhighlight>
 
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 lang=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 lang=J> sumdigsq 99999999
648</langsyntaxhighlight>
 
So we could write a routine which works for the intended range, and stops after the first iteration:
<langsyntaxhighlight lang=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,706:
And this is sufficient to find our result. We don't want to compute the entire batch of values in one pass, however, so let's break this up into 100 batches of one million each:
 
<langsyntaxhighlight lang=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 lang=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.
Line 1,717:
=={{header|Java}}==
{{works with|Java|8}}
<langsyntaxhighlight lang=java>import java.util.stream.IntStream;
 
public class IteratedDigitsSquaring {
Line 1,740:
return n;
}
}</langsyntaxhighlight>
 
<pre>85744333</pre>
Line 1,752:
 
'''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,774:
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,805:
| 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,818:
# Using jq 1.4:
# user 0m3.942s
# sys 0m0.009s</langsyntaxhighlight>
 
=={{header|Julia}}==
{{works with|Julia|0.6}}
'''Brute force solution''':
<langsyntaxhighlight lang=julia>function iterate(m::Integer)
while m != 1 && m != 89
s = 0
Line 1,834:
return m
end
itercount(k::Integer) = count(x -> iterate(x) == 89, 1:k)</langsyntaxhighlight>
 
'''More clever solution''':
<langsyntaxhighlight lang=julia>using Combinatorics
function itercountcombos(ndigits::Integer)
cnt = 0
Line 1,864:
end
return cnt
end</langsyntaxhighlight>
 
'''Benchmarks'''
<langsyntaxhighlight lang=julia>@time itercount(100_000_000)
@time itercountcombos(8)
@time itercountcombos(17)</langsyntaxhighlight>
{{out}}
<pre> 8.866063 seconds (4.32 k allocations: 232.908 KiB)
Line 1,877:
=={{header|Kotlin}}==
{{trans|FreeBASIC}}
<langsyntaxhighlight lang=scala>// version 1.0.6
 
fun endsWith89(n: Int): Boolean {
Line 1,912:
if (endsWith89(i)) count89 += sums[i]
println("There are $count89 numbers from 1 to 100 million ending with 89")
}</langsyntaxhighlight>
 
{{out}}
Line 1,920:
 
=={{header|Lua}}==
<langsyntaxhighlight lang=lua>squares = {}
 
for i = 0, 9 do
Line 1,966:
end
 
print(counter)</langsyntaxhighlight>
{{out}}
<pre>85744333</pre>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<langsyntaxhighlight lang=Mathematica>sumDigitsSquared[n_Integer] := Total[IntegerDigits[n]^2]
stopValues = Join[{1}, NestList[sumDigitsSquared, 89, 7]];
iterate[n_Integer] :=
Line 2,007:
b}, {_?(MemberQ[iteratesToOne, #] &), _}][[All, 2]]];
 
(10^numberOfDigits - 1) - onesCount</langsyntaxhighlight>
 
{{out}}<pre>85744333</pre>
Line 2,016:
We provide the result for 8 digits and also for 50 digits. The result is obtained in 7 ms.
 
<langsyntaxhighlight lang=Nim>import tables
 
iterator digits(n: int): int =
Line 2,060:
 
echo "For 8 digits: ", chainsEndingWith89(8)
echo "For 50 digits: ", chainsEndingWith89(15)</langsyntaxhighlight>
 
{{out}}
Line 2,068:
=={{header|Oberon-2}}==
{{works with|oo2c Version 2}}
<langsyntaxhighlight lang=oberon2>
MODULE DigitsSquaring;
IMPORT
Line 2,102:
END DigitsSquaring.
 
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,114:
 
=={{header|Objeck}}==
<langsyntaxhighlight lang=objeck>class Abbreviations {
function : Main(args : String[]) ~ Nil {
Count89s(1000000)->PrintLine();
Line 2,157:
return sum;
}
}</langsyntaxhighlight>
 
Output:
Line 2,169:
Brute force implementation
 
<langsyntaxhighlight lang=Oforth>: sq_digits(n)
while (n 1 <> n 89 <> and ) [
0 while(n) [ n 10 /mod ->n dup * + ]
Line 2,175:
] n ;
 
: iterDigits | i | 0 100000000 loop: i [ i sq_digits 89 &= + ] . ;</langsyntaxhighlight>
 
{{out}}
Line 2,183:
 
=={{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 2,203:
 
Tested with freepascal.
<langsyntaxhighlight lang=pascal>program Euler92;
const
maxdigCnt = 14;
Line 2,339:
writeln('there are ',upperlimit-res,' 89s ');
end.
</langsyntaxhighlight>output i3 3.5 Ghz<pre>
10e18
//658 small counts out of 1000000000
Line 2,359:
{{trans|Raku}}
 
<langsyntaxhighlight lang=perl>use warnings;
use strict;
 
Line 2,382:
}
print $cnt;</langsyntaxhighlight>
 
85744333
Line 2,388:
=={{header|Phix}}==
{{trans|C}}
<!--<langsyntaxhighlight lang=Phix>(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">MAXINT</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">machine_bits</span><span style="color: #0000FF;">()=</span><span style="color: #000000;">32</span><span style="color: #0000FF;">?</span><span style="color: #000000;">53</span><span style="color: #0000FF;">:</span><span style="color: #000000;">64</span><span style="color: #0000FF;">))</span>
Line 2,431:
<span style="color: #000000;">main</span><span style="color: #0000FF;">(</span><span style="color: #000000;">20</span><span style="color: #0000FF;">)</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span>
<!--</langsyntaxhighlight>-->
{{out}}
on 32 bit:
Line 2,466:
I realised I needed to do this in two stages.<br>
Phase 1. Make sure we can count.
<!--<langsyntaxhighlight lang=Phix>(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">comb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">set</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">at</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">chosen</span><span style="color: #0000FF;">={})</span>
Line 2,494:
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%V\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">comb</span><span style="color: #0000FF;">({</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">},</span><span style="color: #000000;">nums</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">)})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</langsyntaxhighlight>-->
Starting with the combinations method from http://rosettacode.org/wiki/Combinations_with_repetitions#Phix converted to a function, make sure we
are covering all the numbers correctly by checking that we have indeed found power(10,n) of them, and show we are looking at significantly fewer combinations.
Line 2,510:
Phase 2. Add in the rest of the logic, as suggested count 1's in preference to 89's and subtract from 10^n to get the answer.<br>
[PS There is an eerie similarity between this and the 2nd C version, but I swear it is not a copy, and I noticed that later.]
<!--<langsyntaxhighlight lang=Phix>(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">is1</span>
Line 2,572:
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #0000FF;">?</span><span style="color: #7060A8;">elapsed</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t00</span><span style="color: #0000FF;">)</span>
<!--</langsyntaxhighlight>-->
{{out}}
Sadly, while still very much faster than brute force, several times slower than the translated from C version.
Line 2,597:
=={{header|PicoLisp}}==
Brute force with caching
<langsyntaxhighlight lang=PicoLisp>(de *Idx1or89 (89 . 89) ((1 . 1)))
 
(de 1or89 (N)
Line 2,605:
(prog1
(1or89 N)
(idx '*Idx1or89 (cons N @) T) ) ) ) )</langsyntaxhighlight>
Test:
<langsyntaxhighlight lang=PicoLisp>(let Ones 0
(for I 100000000
(and (=1 (1or89 I)) (inc 'Ones)) )
(println (- 100000000 Ones)) )</langsyntaxhighlight>
Output:
<pre>85744333</pre>
 
=={{header|PL/I}}==
<langsyntaxhighlight lang=PL/I>
test: procedure options (main, reorder); /* 6 August 2015 */
 
Line 2,645:
 
end test;
</syntaxhighlight>
</lang>
Output:
<pre>
Line 2,654:
=={{header|PureBasic}}==
{{Trans|C}}
<langsyntaxhighlight lang=purebasic>OpenConsole()
Procedure is89(x)
Repeat
Line 2,691:
main()
Print("elapsed milliseconds= "+Str(ElapsedMilliseconds()-start))
Input()</langsyntaxhighlight>
{{out}}
<pre>1->10^1 : 7
Line 2,715:
elapsed milliseconds= 9</pre>
{{Trans|C++}}
<langsyntaxhighlight lang=purebasic>OpenConsole()
Procedure sum_square_digits(n)
num=n : sum=0
Line 2,745:
main()
Print("elapsed milliseconds: "+Str(ElapsedMilliseconds()-start))
Input()</langsyntaxhighlight>
{{out}}
<pre>85744333
Line 2,754:
====Translation of D====
{{trans|D}}
<langsyntaxhighlight lang=python>from math import ceil, log10, factorial
 
def next_step(x):
Line 2,809:
print result
 
main()</langsyntaxhighlight>
{{out}}
85744333
Line 2,815:
====Translation of Ruby====
{{trans|Ruby}}
<langsyntaxhighlight lang=python>
from itertools import combinations_with_replacement
from array import array
Line 2,858:
print "\nD==" + str(D) + "\n " + str(z) + " numbers produce 1 and " + str(10**D-z) + " numbers produce 89"
print "Time ~= " + str(ee) + " secs"
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,879:
 
===Python: Simple caching===
<langsyntaxhighlight lang=python>>>> from functools import lru_cache
>>> @lru_cache(maxsize=1024)
def ids(n):
Line 2,892:
>>> 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,898:
===Python: Enhanced caching===
Notes that the order of digits in a number does not affect the final result so caches the digits of the number in sorted order for more hits.
<langsyntaxhighlight lang=python>>>> from functools import lru_cache
>>> @lru_cache(maxsize=1024)
def _ids(nt):
Line 2,916:
>>> _ids.cache_info()
CacheInfo(hits=99991418, misses=5867462, maxsize=1024, currsize=1024)
>>> </langsyntaxhighlight>
 
This took tens of minutes to run.
Line 2,922:
===Count digit sums===
If we always count up to powers of 10, it's faster to just record how many different numbers have the same digit square sum. The <code>check89()</code> function is pretty simple-minded, because it doesn't need to be fancy here.
<langsyntaxhighlight lang=python>from __future__ import print_function
from itertools import count
 
Line 2,941:
 
x = sum(a[i] for i in range(len(a)) if is89[i])
print("10^%d" % n, x)</langsyntaxhighlight>
 
=={{header|QBasic}}==
Line 2,947:
{{works with|QuickBasic}}
{{trans|BBC BASIC}}
<langsyntaxhighlight lang=QBasic>REM Version 1: Brute force
 
T = TIMER
Line 2,964:
NEXT i
PRINT USING "Version 1: ####### in ##.### seconds."; n1; (TIMER - T)
END</langsyntaxhighlight>
 
 
=={{header|Quackery}}==
 
<langsyntaxhighlight lang=Quackery>[ abs 0 swap
[ base share /mod
dup *
Line 2,984:
[ i^ 1+ chainends
89 = + ]
echo</langsyntaxhighlight>
 
{{out}}
Line 2,994:
This contains two versions (in one go). The naive version which can (and should, probably) be used for investigating a single number. The second version can count the IDSes leading to 89 for powers of 10.
 
<langsyntaxhighlight lang=racket>#lang racket
;; Tim-brown 2014-09-11
 
Line 3,089:
(length (all-digit-lists 3)) => 220
(count-89s-in-100... 1000000) => 856929]
}</langsyntaxhighlight>
 
{{out}}
Line 3,115:
This fairly abstract version does caching and filtering to reduce the number of values it needs to check and moves calculations out of the hot loop, but is still interminably slow... even for just up to 1,000,000.
 
<langsyntaxhighlight lang=perl6>constant @sq = ^10 X** 2;
my $cnt = 0;
 
Line 3,128:
}
say $cnt;</langsyntaxhighlight>
{{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:
<langsyntaxhighlight lang=perl6>my @cache;
@cache[1] = 1;
@cache[89] = 89;
Line 3,164:
$cnt = $cnt + 1 if Euler92($n) == 89;
}
say $cnt;</langsyntaxhighlight>
{{out}}
<pre>85744333</pre>
Line 3,171:
The biggest gains are often from choosing the right algorithm.
 
<langsyntaxhighlight lang=perl6>sub endsWithOne($n --> Bool) {
my $digit;
my $sum = 0;
Line 3,203:
my $ends-with-one = sum flat @sums[(1 .. $k*81).grep: { endsWithOne($_) }], +endsWithOne(10**$k);
 
say 10**$k - $ends-with-one;</langsyntaxhighlight>
 
{{out}}
Line 3,209:
 
=={{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 3,232:
do k=1 by 88 for 2; @k=right('"'k'"', 5) /*display two results; define a literal*/
say 'count of' @k " chains for all natural numbers up to " n ' is:' #.k
end /*k*/ /*stick a fork in it, we're all done. */</langsyntaxhighlight>
{{out|output|text=&nbsp; when using the default input:}}
<br>(ten million)
Line 3,242:
===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 3,256:
end /*k*/ /*stick a fork in it, we're all done. */
exit /*stick a fork in it, we're all done. */
/*--------------------------------------------------------------------------------------*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
sumDs: parse arg z; chunk=3 /*obtain the number (for adding digits)*/
p=0 /*set partial sum of the decimal digits*/
do m=1 by chunk to length(z) /*process the number, in chunks of four*/
y=substr(z, m, chunk) /*extract a 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 3,277:
do until y=='' /*process each decimal digits in X.*/
parse var y _ +1 y; s=s + !._ /*get a dec. digit; sum the fast square*/
end /*until y ···*/ /* [?] 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 3,290:
 
=={{header|Ring}}==
<langsyntaxhighlight lang=ring>
nr = 1000
num = 0
Line 3,301:
next
see "Total under 1000 is : " + num + nl
</syntaxhighlight>
</lang>
Output:
<pre>
Line 3,347:
 
=={{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
Line 3,371:
iterated_square_digit(d)
puts " #{Time.now - t0} sec"
end</langsyntaxhighlight>
 
{{out}}
Line 3,398:
 
'''Naive Recursion'''
<langsyntaxhighlight lang=rust>fn digit_square_sum(mut num: usize) -> usize {
let mut sum = 0;
while num != 0 {
Line 3,417:
let count = (1..100_000_000).filter(|&n| last_in_chain(n) == 89).count();
println!("{}", count);
}</langsyntaxhighlight>
{{out}}
<pre>85744333</pre>
Line 3,423:
 
'''With precomputation'''
<langsyntaxhighlight lang=rust>fn dig_sq_sum(mut num : usize ) -> usize {
let mut sum = 0;
while num != 0 {
Line 3,444:
let count = (1..100_000_000).filter(|&n| prec[dig_sq_sum(n)] == 89).count();
println!("{}", count);
}</langsyntaxhighlight>
Runtime: 1.7s on a 2500k @ 4Ghz
{{out}}
Line 3,452:
===Naïve Version, conventional iteration and (tail) recursive in one===
{{Out}}Best seen running in your browser either by [https://scalafiddle.io/sf/3XRtgEE/0 ScalaFiddle (ES aka JavaScript, non JVM)] or [https://scastie.scala-lang.org/6HeszTpxTXOqvrytzShUzg Scastie (remote JVM)] to compare the run times.
<langsyntaxhighlight lang=Scala>import scala.annotation.tailrec
 
object Euler92 extends App {
Line 3,494:
println(s"Runtime recursive loop. [total ${compat.Platform.currentTime - executionStart0} ms]")
 
}</langsyntaxhighlight>
 
=={{header|Sidef}}==
<langsyntaxhighlight lang=ruby>func digit_square_sum_iter(n) is cached {
 
if ((n == 1) || (n == 89)) {
Line 3,506:
}
 
say (1..1e6 -> count_by { digit_square_sum_iter(_) == 89 })</langsyntaxhighlight>
{{out}}
<pre>
Line 3,518:
With nth power support.
 
<langsyntaxhighlight lang=swift>import BigInt
 
func is89(_ n: Int) -> Bool {
Line 3,570:
}
 
iterSquare(upToPower: 8)</langsyntaxhighlight>
 
{{out}}
Line 3,585:
All three versions below produce identical output (<tt>85744333</tt>), but the third is fastest and the first is the slowest, both by substantial margins.
===''Very'' Naïve Version===
<langsyntaxhighlight lang=tcl>proc ids n {
while {$n != 1 && $n != 89} {
set n [tcl::mathop::+ {*}[lmap x [split $n ""] {expr {$x**2}}]]
Line 3,594:
incr count [expr {[ids $i] == 89}]
}
puts $count</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 3,609:
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 3,645:
}
puts $count
}}</langsyntaxhighlight>
 
=={{header|VBScript}}==
<syntaxhighlight lang=vb>
<lang vb>
start_time = Now
cnt = 0
Line 3,669:
WScript.Echo "Elapse Time: " & DateDiff("s",start_time,end_time) &_
vbCrLf & "Count: " & cnt
</syntaxhighlight>
</lang>
 
{{Out}}
Line 3,680:
=={{header|Wren}}==
{{trans|FreeBASIC}}
<langsyntaxhighlight lang=ecmascript>var endsWith89 = Fn.new { |n|
var digit = 0
var sum = 0
Line 3,717:
}
}
System.print("Took %(((System.clock - start)*1000).round) milliseconds.")</langsyntaxhighlight>
 
{{out}}
Line 3,728:
=={{header|X86 Assembly}}==
{{works with|nasm}}
<langsyntaxhighlight lang=asm>
section .data
count dd 0
Line 3,781:
mov eax, 0
ret
</syntaxhighlight>
</lang>
 
=={{header|zkl}}==
Line 3,788:
{{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 3,819:
}
}
println(result);</langsyntaxhighlight>
{{out}}
<pre>85744333</pre>
Line 3,826:
{{trans|BBC_BASIC}}
Very, very slow. Use a ZX Spectrum emulator and run with maximum speed option enabled.
<langsyntaxhighlight lang=zxbasic>10 LET n=0
20 FOR i=1 TO 1000
30 LET j=i
Line 3,839:
110 NEXT i
120 PRINT "Version 1: ";n
200 DEF FN m(a,b)=a-INT (a/b)*b: REM modulo</langsyntaxhighlight>
{{out}}
<pre>Version 1: 857</pre>
6,962

edits