Disarium numbers: Difference between revisions

From Rosetta Code
Content added Content deleted
m (typo)
(→‎{{header|Wren}}: Added a note to preamble about caching digit powers.)
Line 80: Line 80:
{{libheader|Wren-math}}
{{libheader|Wren-math}}
Well, for once, we can brute force the first 19 Disarium numbers without resorting to BigInt or GMP. Surprisingly, much quicker than Raku at 3.35 seconds.
Well, for once, we can brute force the first 19 Disarium numbers without resorting to BigInt or GMP. Surprisingly, much quicker than Raku at 3.35 seconds.

As a possible optimization, I tried caching all possible digit powers but there was no perceptible difference in running time for numbers up to 7 digits long.


Taking a rain check on the 20th number which is 20 digits long (too big for Wren's 53 bit integers) to see whether more efficient methods emerge.
Taking a rain check on the 20th number which is 20 digits long (too big for Wren's 53 bit integers) to see whether more efficient methods emerge.

Revision as of 13:54, 13 February 2022

Disarium numbers is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

A Disarium number is an integer where the sum of each digit raised to the power of its position in the number, is equal to the number.


E.G.

135 is a Disarium number:

11 + 32 + 53 == 1 + 9 + 125 == 135

There are a finite number of Disarium numbers.


Task
  • Find and display the first 18 Disarium numbers.


Stretch
  • Find and display all 20 Disarium numbers.


See also



Factor

Works with: Factor version 0.99 2021-06-02

<lang factor>USING: io kernel lists lists.lazy math.ranges math.text.utils math.vectors prettyprint sequences ;

disarium? ( n -- ? )
   dup 1 digit-groups dup length 1 [a,b] v^ sum = ;
disarium ( -- list ) 0 lfrom [ disarium? ] lfilter ;

19 disarium ltake [ pprint bl ] leach nl</lang>

Output:
0 1 2 3 4 5 6 7 8 9 89 135 175 518 598 1306 1676 2427 2646798 

Julia

<lang julia>isdisarium(n) = sum(last(p)^first(p) for p in enumerate(reverse(digits(n)))) == n

function disariums(numberwanted)

   n, ret = 0, Int[]
   while length(ret) < numberwanted
       isdisarium(n) && push!(ret, n)
       n += 1
   end
   return ret

end

println(disariums(19)) @time disariums(19)

</lang>

Output:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 89, 135, 175, 518, 598, 1306, 1676, 2427, 2646798]
  0.555962 seconds (5.29 M allocations: 562.335 MiB, 10.79% gc time)

Raku

Not an efficient algorithm. First 18 in less than 1/4 second. 19th in around 45 seconds. Pretty much unusable for the 20th. <lang perl6>my $disarium = (^∞).hyper.map: { $_ if $_ == sum .polymod(10 xx *).reverse Z** 1..* };

put $disarium[^18]; put $disarium[18];</lang>

Output:
0 1 2 3 4 5 6 7 8 9 89 135 175 518 598 1306 1676 2427
2646798

Wren

Library: Wren-math

Well, for once, we can brute force the first 19 Disarium numbers without resorting to BigInt or GMP. Surprisingly, much quicker than Raku at 3.35 seconds.

As a possible optimization, I tried caching all possible digit powers but there was no perceptible difference in running time for numbers up to 7 digits long.

Taking a rain check on the 20th number which is 20 digits long (too big for Wren's 53 bit integers) to see whether more efficient methods emerge. <lang ecmascript>import "./math" for Int

var limit = 19 var count = 0 var disarium = [] var n = 0 while (count < limit) {

   var sum = 0
   var digits = Int.digits(n)
   for (i in 0...digits.count) sum = sum + digits[i].pow(i+1)
   if (sum == n) {
       disarium.add(n)
       count = count + 1
   }
   n = n + 1

} System.print("The first 19 Disarium numbers are:") System.print(disarium)</lang>

Output:
The first 19 Disarium numbers are:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 89, 135, 175, 518, 598, 1306, 1676, 2427, 2646798]