Disarium numbers: Difference between revisions

From Rosetta Code
Content added Content deleted
(Disarium numbers en Python)
(Disarium numbers en FreeBASIC)
Line 45: Line 45:
<pre>
<pre>
0 1 2 3 4 5 6 7 8 9 89 135 175 518 598 1306 1676 2427 2646798
0 1 2 3 4 5 6 7 8 9 89 135 175 518 598 1306 1676 2427 2646798
</pre>

=={{header|FreeBASIC}}==
<lang freebasic>#define limite 19

Function isDisarium(n As Integer) As Boolean
Dim As Integer digitos = Len(Str(n))
Dim As Integer suma = 0, x = n
While x <> 0
suma += (x Mod 10) ^ digitos
digitos -= 1
x \= 10
Wend
Return Iif(suma = n, True, False)
End Function

Dim As Integer cont = 0, n = 0, i
Print "The first"; limite; " Disarium numbers are:"
Do While cont < limite
If isDisarium(n) Then
Print n; " ";
cont += 1
End If
n += 1
Loop
Sleep</lang>
{{out}}
<pre>
Igual que la entrada de Python.
</pre>
</pre>


Line 116: Line 145:
x = n
x = n
while x != 0:
while x != 0:
r = x % 10
suma += (x % 10) ** digitos
suma += r ** digitos
digitos -= 1
digitos -= 1
x //= 10
x //= 10

Revision as of 23:47, 14 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 

FreeBASIC

<lang freebasic>#define limite 19

Function isDisarium(n As Integer) As Boolean

   Dim As Integer digitos = Len(Str(n))
   Dim As Integer suma = 0, x = n
   While x <> 0
       suma += (x Mod 10) ^ digitos
       digitos -= 1
       x \= 10
   Wend
   Return Iif(suma = n, True, False)

End Function

Dim As Integer cont = 0, n = 0, i Print "The first"; limite; " Disarium numbers are:" Do While cont < limite

   If isDisarium(n) Then
       Print n; " ";
       cont += 1
   End If
   n += 1

Loop Sleep</lang>

Output:
Igual que la entrada de Python.

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)

Perl

<lang perl>use strict; use warnings;

my ($n,@D) = (0, 0); while (++$n) {

   my($m,$sum);
   map { $sum += $_ ** ++$m } split , $n;
   push @D, $n if $n == $sum;
   last if 19 == @D;

} print "@D\n";</lang>

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

Phix

with javascript_semantics
constant limit = 19
integer count = 0, n = 0
printf(1,"The first 19 Disarium numbers are:\n")
while count<limit do
    atom dsum = 0
    string digits = sprintf("%d",n)
    for i=1 to length(digits) do
         dsum += power(digits[i]-'0',i)
    end for
    if dsum=n then
        printf(1," %d",n)
        count += 1
    end if
    n += 1
end while
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


Python

<lang python>#!/usr/bin/python

def isDisarium(n):

   digitos = len(str(n))
   suma = 0
   x = n
   while x != 0:
       suma += (x % 10) ** digitos
       digitos -= 1
       x //= 10
   if suma == n:
       return True
   else:
       return False

if __name__ == '__main__':

   limite = 19
   cont = 0
   n = 0
   print("The first",limite,"Disarium numbers are:")
   while cont < limite:
       if isDisarium(n):
           print(n, end = " ")
           cont += 1
       n += 1</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


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]