Narcissistic decimal number

From Rosetta Code
Revision as of 08:32, 7 March 2014 by rosettacode>Gerard Schildberger (→‎{{header|REXX}}: adjust numeric digits to handle the largest narcissistic number.)
Task
Narcissistic decimal number
You are encouraged to solve this task according to the task description, using any language you may know.

A Narcissistic decimal number is a positive decimal number, in which if there are digits in the number then the sum of all the individual digits of the number raised to the power is equal to .

For example, if is 153 then , the number of digits is 3 and we have and so 153 is a narcissistic decimal number.

The task is to generate and show here, the first 25 narcissistic numbers.

C

<lang c>#include <stdio.h>

typedef long long xint;

  1. define MAX_LEN 16

xint dpow[MAX_LEN + 1][11];

void init(void) { int i, p; for (p = 0; p <= MAX_LEN; p++) for (i = 0; i <= 10; i++) dpow[p][i] = p ? dpow[p-1][i] * i : 1; }

void narc(int power, int pos, xint value, xint dsum) { xint i, ds, v, ten;

if (!pos) { if (value == dsum) printf(" %lld", value); return; }

ten = dpow[pos - 1][10]; for (i = (pos == power); i < 10; i++) { ds = dsum + dpow[power][i]; v = value + i * ten;

if (ds >= v + ten) break;

if (v <= ds + dpow[power][9] * (pos - 1)) narc(power, pos - 1, v, ds); } }

int main(void) { int i; init();

for (i = 1; i <= 16; i++) { printf("length %d:", i); narc(i, i, 0, 0); putchar('\n'); }

return 0; }</lang>

Output:
length 1: 1 2 3 4 5 6 7 8 9
length 2:
length 3: 153 370 371 407
length 4: 1634 8208 9474
length 5: 54748 92727 93084
length 6: 548834
length 7: 1741725 4210818 9800817 9926315
length 8: 24678050 24678051 88593477
length 9: 146511208 472335975 534494836 912985153
^C

Perl 6

Here is a straightforward, naive implementation. It works but takes ages. <lang perl6>sub is-narcissistic(Int $n) { $n == [+] $n.comb »**» $n.chars }

for 0 .. * {

   if .&is-narcissistic {

.say; last if ++state$ >= 25;

   }

}</lang>

Output:
0
1
2
3
4
5
6
7
8
9
153
370
371
407
Ctrl-C

Here the program was interrupted but if you're patient enough you'll see all the 25 numbers.

Python

This solution pre-computes the powers once.

<lang python>from __future__ import print_function from itertools import count, islice

def narcissists():

   for digits in count(0):
       digitpowers = [i**digits for i in range(10)]
       for n in range(int(10**(digits-1)), 10**digits):
           div, digitpsum = n, 0
           while div:
               div, mod = divmod(div, 10)
               digitpsum += digitpowers[mod]
           if n == digitpsum:
               yield n

for i, n in enumerate(islice(narcissists(), 25), 1):

   print(n, end=' ')
   if i % 5 == 0: print() 

print()</lang>

Output:
0 1 2 3 4 
5 6 7 8 9 
153 370 371 407 1634 
8208 9474 54748 92727 93084 
548834 1741725 4210818 9800817 9926315

REXX

<lang rexx>/*REXX program to generate and display a number of narcissistic numbers.*/ numeric digits 39 /*be able to handle the largest #*/ parse arg N .; if N== then N=25 /*get number of narcissistic #'s.*/ N=min(N,89) /*there are 89 narcissistic #s.*/

  1. =0 /*number of narcissistic # so far*/
    do j=1  until #==N;  L=length(j)  /*get the length of the J number.*/
    s=left(j,1)**L                    /*sum of the J digits to L power.*/
                                      /* [↑]  calculate partial sum.   */
             do k=2  for L-1          /*perform for each digit in  J.  */
             s=s+substr(j,k,1)**L     /*add digit raised to pow to sum.*/
             if s>j  then iterate j   /*perform a short-circuit test.  */
             end   /*k*/              /* [↑]  calculate the rest of sum*/
                                      /* [↓]  perform final "sum" test.*/
    if s\==j  then iterate            /*does sum equal to  J?   No ∙∙∙ */
    #=#+1                             /*bump the narcissistic num count*/
    say right(#,9) ' narcissistic:' j /*display index & narcissistic #.*/
    end   /*j*/                       /* [↑]    this list starts at 1. */
                                      /*stick a fork in it, we're done.*/</lang>

output   when using the default input:

        1  narcissistic: 1
        2  narcissistic: 2
        3  narcissistic: 3
        4  narcissistic: 4
        5  narcissistic: 5
        6  narcissistic: 6
        7  narcissistic: 7
        8  narcissistic: 8
        9  narcissistic: 9
       10  narcissistic: 153
       11  narcissistic: 370
       12  narcissistic: 371
       13  narcissistic: 407
       14  narcissistic: 1634
       15  narcissistic: 8208
       16  narcissistic: 9474
       17  narcissistic: 54748
       18  narcissistic: 92727
       19  narcissistic: 93084
       20  narcissistic: 548834
       21  narcissistic: 1741725
       22  narcissistic: 4210818
       23  narcissistic: 9800817
       24  narcissistic: 9926315
       25  narcissistic: 24678050