57
\$\begingroup\$

A Narcissistic Number is a number which is the sum of its own digits, each raised to the power of the number of digits.

For example, take \$153\$ (3 digits):

\$1^3 + 5^3 + 3^3 = 153\$

\$1634\$:

\$1^4 + 6^4 + 3^4 + 4^4 = 1634 = 1 + 1296 + 81 + 256 = 1634\$

The Challenge:

Your code must take input from the user and output True or False depending upon whether the given number is a Narcissistic Number.

Error checking for text strings or other invalid inputs is not required. 1 or 0 for the output is acceptable. Code that simply generates a list of Narcissistic Numbers, or checks the user input against a hardcoded list, does not qualify.

OEIS A005188

\$\endgroup\$
1
  • 4
    \$\begingroup\$ Is it ok if I output True if it's such a number, but anything else (in this case the number itself) if not? \$\endgroup\$
    – devRicher
    Commented Jan 6, 2017 at 21:51

79 Answers 79

39
\$\begingroup\$

APL (15)

∆≡⍕+/(⍎¨∆)*⍴∆←⍞

Outputs 1 if true and 0 if false.

Explanation:

  • ∆←⍞: read a line (as characters), store in
  • (⍎¨∆)*⍴∆: evaluate each character in and raise it to the power ⍴∆
  • ∆≡⍕+/: see if the input equals the string representation of the sum of these
\$\endgroup\$
2
  • 9
    \$\begingroup\$ what did i just read \$\endgroup\$
    – Jacob
    Commented Feb 18, 2014 at 20:13
  • 4
    \$\begingroup\$ @LagWagon God's language \$\endgroup\$
    – tomsmeding
    Commented Jul 8, 2014 at 8:00
21
\$\begingroup\$

GolfScript, 16 characters

~.`:s{48-s,?-}/!

Input must be given on STDIN, output is 0 or 1 indicating non-narcissistic / narcissistic number.

Explanation of the code:

~              # Evaluate the input to get a number
.              # Accumulator (initially the number itself)
`:s            # Convert number to string and assign to variable s
{              # Loop over characters of the string
  48-          # Reduce character value by 48
  s,           # Push length of input number
  ?            # Power
  -            # Subtract result from accumulator
}/
!              # Not! (i.e. iff accumulator was zero it was a narcissistic number)
\$\endgroup\$
1
  • \$\begingroup\$ I did a double-take on `` ~.` `` but it seems impossible to improve. Nice one. \$\endgroup\$ Commented Nov 20, 2013 at 17:28
15
\$\begingroup\$

Mathematica, 43 chars

Tr[#^Length@#&@IntegerDigits@#]==#&@Input[]
\$\endgroup\$
14
\$\begingroup\$

Perl, 38 characters

perl -lpe '$@=y///c;$s+=$_**$@for/./g;$_=$_==$s'

A pretty straightforward implementation.

Here's a slightly different version that fits in 35 characters:

perl -lpe '$@=y///c;$s+=$_**$@for/./g;$_-=$s'

This version outputs a false value if the input is narcissistic, otherwise it outputs a (Perl-accepted) true value. One might argue that this backwards version falls within the limits of the challenge description, but upon reflection I decided not to. I'm not that desperate to improve my score. Yet.

\$\endgroup\$
4
  • \$\begingroup\$ “Error checking for text strings or other invalid inputs is not required.” – So why not suppose the input will be valid number, without trailing newline? echo -n 153 | perl -pe '…' will work without -l. \$\endgroup\$
    – manatwork
    Commented Nov 14, 2013 at 12:26
  • \$\begingroup\$ I think so long as you define what your true and false outputs are, it should be legal \$\endgroup\$
    – Cruncher
    Commented Nov 14, 2013 at 16:48
  • \$\begingroup\$ Strictly speaking, the wording of the challenge text does leave a bit of ambiguity as to what True/False or 0/1 should mean, so I'll let this one pass. A different script of equal length that returns true for narcissistic values would have the advantage, though. \$\endgroup\$
    – Iszi
    Commented Nov 14, 2013 at 20:47
  • \$\begingroup\$ Same idea but shorter: perl -pe'map$s+=$_**@y,@y=/./g;$_=$_==$s' \$\endgroup\$
    – msh210
    Commented Jun 19, 2016 at 7:48
13
\$\begingroup\$

J, 23 chars

(".=+/@("."0^#))(1!:1)1

(1!:1)1 is keyboard input (returning a string).

". converts input to a number; "0 specifies a rank (dimension) of 0, in other words, taking each character and converting it to a number.

^ is the power function and # is the length function, thus taking each digit to the power of the length of the string (equivalently, the number of digits).

+/ is just sum, and = is comparing the sum and number.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ "Your code must take input from the user and output True or False depending upon whether the given number is a Narcissistic Number." (emphasis mine) \$\endgroup\$ Commented Nov 14, 2013 at 4:45
  • \$\begingroup\$ @JanDvorak My bad -- added keyboard input. \$\endgroup\$
    – rationalis
    Commented Nov 14, 2013 at 6:08
13
\$\begingroup\$

Ruby, 34+5=39

With command-line flags

ruby -nlaF|

Run

p eval [$F,0]*"**#{~/$/}+"+"==#$_"

Outputs true or false.

\$\endgroup\$
1
  • 3
    \$\begingroup\$ This may be the most Ruby flags I've ever seen in a legitimate code golf :P \$\endgroup\$
    – Doorknob
    Commented Nov 21, 2013 at 21:24
11
\$\begingroup\$

R, 71 69 66 56 48

Reduced by 8 bytes thanks to @Giuseppe! The idea was to perform the integer division before the modulo operation.

i=nchar(a<-scan()):0;a==sum((a%/%10^i%%10)^i[1])

(3-year) old version with corresponding explanation:

i=nchar(a<-scan()):1;a==sum(((a%%10^i)%/%10^(i-1))^i[1])

a<-scan() takes a number (integer, real,...) as input (say 153 for the example).
i becomes a vector containing 3 to 1 (the number of characters of a being 3).
%% is vectorized so a%%10^i means a modulo 1000, 100 and 10: it therefore gives 153, 53, 3.
(a%%10^i)%/%10^(i-1) is the integer division of that vector by 100, 10, 1: therefore, 1, 5, 3.
We elevate that with the first element of i which is the number of characters (here digits) of a, i. e. 3, thus giving a vector containing 1, 125, 27 that we sum and compares to a.

\$\endgroup\$
3
  • \$\begingroup\$ Does the integer division always round down? Otherwise, you could run into problems with e.g. 370 (a narcissistic number) turning into 4,7,0 (which would return false) or 270 (non-narcissistic) turning into 3,7,0 (returning true). \$\endgroup\$
    – Iszi
    Commented Nov 14, 2013 at 20:40
  • \$\begingroup\$ Integer division doesn't round... The integer division of 370 by 100 is 3 with the remainder of 70 and not 3.70. \$\endgroup\$
    – plannapus
    Commented Nov 15, 2013 at 7:40
  • 1
    \$\begingroup\$ 48 bytes...somebody bumped this to the homepage! \$\endgroup\$
    – Giuseppe
    Commented Sep 1, 2017 at 19:55
9
\$\begingroup\$

Python 3, 56 bytes

Not very obfuscated, but a simple solution.

s = input()
print(int(s)==sum(int(c)**len(s)for c in s))
\$\endgroup\$
11
  • 1
    \$\begingroup\$ The [ and ] are unnecessary, and you can drop the space in front of for too, so: sum(int(c)**len(s)for c in s) \$\endgroup\$
    – marinus
    Commented Nov 14, 2013 at 7:12
  • \$\begingroup\$ That's awesome! Thanks for the tip. \$\endgroup\$
    – danmcardle
    Commented Nov 14, 2013 at 12:05
  • 1
    \$\begingroup\$ You can save two characters by removing the spaces in s = input() and another one by moving this to 2.7 where print isn't a function. \$\endgroup\$
    – Ben
    Commented Nov 16, 2013 at 17:31
  • \$\begingroup\$ Good point, edited. \$\endgroup\$
    – danmcardle
    Commented Nov 17, 2013 at 5:32
  • \$\begingroup\$ I think you should point out that adding braces to print (hence one character more) would make this a valid Python 2.x and Python 3.x solution. \$\endgroup\$ Commented Nov 18, 2013 at 18:24
8
\$\begingroup\$

PHP, 80 74 66 chars

Very straightforward PHP solution:

<?for(;$i<$l=strlen($a=$argv[1]);)$s+=pow($a[$i++],$l);echo$s==$a;

It assumes error_reporting doesn't include notices, otherwise quite a few extra characters will be needed to initialize $s=0; and $i=0.

Thx @manatwork for shortening many chars.

\$\endgroup\$
4
  • \$\begingroup\$ Don't assign $a and $l in separate statements. <?for($i=0;$i<$l=strlen($a=$argv[1]);$i++){$s+=pow($a[$i],$l);}echo$s==$a; is shorter. \$\endgroup\$
    – manatwork
    Commented Nov 14, 2013 at 14:58
  • \$\begingroup\$ As you already have a statement which generate a notice, just add another: remove the loop control variable initialization. Incrementing the loop control variable also not need to be a standalone statement. And the braces are definitely not needed: <?for(;$i<$l=strlen($a=$argv[1]);)$s+=pow($a[$i++],$l);echo$s==$a;. \$\endgroup\$
    – manatwork
    Commented Nov 14, 2013 at 15:09
  • \$\begingroup\$ @manatwork: Thank you for the warm welcome to codegolf :) \$\endgroup\$
    – Vlad Preda
    Commented Nov 14, 2013 at 15:13
  • \$\begingroup\$ Can be golfed to this for(;$i<$l=strlen($a=$argn);)$s+=$a[$i++]**$l;echo$s==$a; \$\endgroup\$ Commented May 17, 2017 at 16:51
8
\$\begingroup\$

Dc: 48 characters

[1pq]Sr?d0rdZSz[d10/r10%lz^rSh+Lhd0!=c]dScx+=r0p

Sample run:

bash-4.1$ dc -e '[1pq]Sr?d0rdZSz[d10/r10%lz^rSh+Lhd0!=c]dScx+=r0p' <<< '153'
1

bash-4.1$ dc -e '[1pq]Sr?d0rdZSz[d10/r10%lz^rSh+Lhd0!=c]dScx+=r0p' <<< '1634'
1

bash-4.1$ dc -e '[1pq]Sr?d0rdZSz[d10/r10%lz^rSh+Lhd0!=c]dScx+=r0p' <<< '2013'
0
\$\endgroup\$
1
  • \$\begingroup\$ Never actually used dc, save for frantic typos in attempt to write cd \$\endgroup\$
    – Stan Strum
    Commented Jan 5, 2018 at 1:54
8
\$\begingroup\$

K, 24 23

{x=+/xexp["I"$'a]@#a:$x}

Shaved 1 char with reordering

{x=+/{x xexp#x}"I"$'$x}
\$\endgroup\$
8
\$\begingroup\$

R, 53 bytes

sum(scan(t=gsub("(.)","\\1 ",x<-scan()))^nchar(x))==x

The gsub regex inserts spaces in between characters, so that the scan function will be able to read the number into a vector of digits.

\$\endgroup\$
1
  • \$\begingroup\$ +1 i would have never thought of doing that, it's brilliant. \$\endgroup\$
    – plannapus
    Commented Nov 15, 2013 at 16:26
6
\$\begingroup\$

Kona, 18

...

{x=+/(0$'u)^#u:$x}
\$\endgroup\$
6
\$\begingroup\$

Powershell, 75 63 62 60 58

Edit: Updated per @Iszi's comment (note: this counts on $x not existing)

Edit: Added @Danko's changes.

[char[]]($x=$n=read-host)|%{$x-="$_*"*$n.length+1|iex};!$x

58 56 chars

If input is limited to 10 digits (includes all int32)

($x=$n=read-host)[0..9]|%{$x-="$_*"*$n.length+1|iex};!$x
\$\endgroup\$
16
  • \$\begingroup\$ I was wondering if someone was going to do PowerShell before I did. \$\endgroup\$
    – Iszi
    Commented Nov 14, 2013 at 20:55
  • \$\begingroup\$ Save 12 characters by adding another variable $x and using += to do your summing instead of measure -sum then test $x-eq$n. \$\endgroup\$
    – Iszi
    Commented Nov 14, 2013 at 21:03
  • 1
    \$\begingroup\$ 61 chars: ($x=$n=read-host)-split''|%{$x-=[math]::pow($_,$n.length)};!$x \$\endgroup\$ Commented Nov 15, 2013 at 9:04
  • 1
    \$\begingroup\$ @DankoDurbić, Nice! Type coercion often comes in handy with PoSh code golfing. I only get 62 though when I run '($x=$n=read-host)-split""|%{$x-=[math]::pow($_,$n.length)};!$x'.length \$\endgroup\$
    – Rynant
    Commented Nov 15, 2013 at 15:06
  • 1
    \$\begingroup\$ @Rynant Good point. I ran your length check in PowerShell and came up with 62 as well. When running a length check similarly against the actual script, it comes up 61. This is probably because of how PowerShell handles the '' which you replaced with ''. I took the original script into Excel to double-check with =LEN("($x=$n=read-host)-split''|%{$x-=[math]::pow($_,$n.length)};!$x") and got 62 also. Of course, we could always count it manually - but who really does that? \$\endgroup\$
    – Iszi
    Commented Nov 15, 2013 at 15:22
5
\$\begingroup\$

Python 2.x - 51

Same concept as crazedgremlin's solution for Python 3.x:

s=input();print s==sum(int(c)**len(`s`)for c in`s`)
\$\endgroup\$
0
4
\$\begingroup\$

C - 97 93 characters

a,b;main(c){scanf("%d",&c);b=c;for(;c;c/=10)a+=pow(c%10,(int)log10(b)+1);printf("%d",a==b);}

With indentation:

a,b;
main(c) { 
  scanf("%d",&c);
  b=c;
  for(;c;c/=10)
    a+=pow(c%10,(int)log10(b)+1);
  printf("%d",a==b);
}
\$\endgroup\$
5
  • 2
    \$\begingroup\$ You don't have to define int for global variables. \$\endgroup\$
    – null
    Commented Jan 10, 2014 at 15:49
  • \$\begingroup\$ Woah. You're reading the input into argc. \$\endgroup\$ Commented Jan 6, 2017 at 14:16
  • \$\begingroup\$ Also, shouldn't having to do -lm at compile-time count +1 byte? \$\endgroup\$ Commented Jan 6, 2017 at 14:21
  • \$\begingroup\$ @Blacksilver the -lm flag is not required for C89 compilers. \$\endgroup\$
    – Josh
    Commented Jan 9, 2017 at 14:55
  • \$\begingroup\$ Aha. Learn a new thing every day. \$\endgroup\$ Commented Jan 9, 2017 at 14:59
4
\$\begingroup\$

05AB1E (legacy), 7 bytes

DSDgmOQ

Try it online!

-2 bytes thanks to @daHugLenny

\$\endgroup\$
1
  • 3
    \$\begingroup\$ You can replace §1ô with S \$\endgroup\$
    – acrolith
    Commented Nov 8, 2016 at 15:45
3
\$\begingroup\$

Haskell 2010 - 76 characters

main=do x<-getLine;print$(==x)$show$sum$map((^length x).(+(-48)).fromEnum)x
\$\endgroup\$
1
  • 1
    \$\begingroup\$ You shouldn't post the number of ms to run the code, but the number of chars you used. ;) \$\endgroup\$ Commented Nov 15, 2013 at 4:02
3
\$\begingroup\$

Awk: 40 39 characters

{for(;i<NF;)s+=$(i+++1)**NF;$0=$0==s}1

Sample run:

bash-4.1$ awk -F '' '{for(;i<NF;)s+=$(i+++1)**NF;$0=$0==s}1' <<< '153'
1

bash-4.1$ awk -F '' '{for(;i<NF;)s+=$(i+++1)**NF;$0=$0==s}1' <<< '1634'
1

bash-4.1$ awk -F '' '{for(;i<NF;)s+=$(i+++1)**NF;$0=$0==s}1' <<< '2013'
0
\$\endgroup\$
3
\$\begingroup\$

Bash, 64 chars

for((a=$1;a>0;s+=(a%10)**${#1},a/=10));do :; done;echo $[s==$1]

a=$1;p=${#a};for((;a>0;a/=10));do s=$((s+(a%10)**p));done;echo $((s==$1))

\$\endgroup\$
3
  • 1
    \$\begingroup\$ You are using variable p in a single place, so no need for it. You can move the initialization of variable a into the for to spare its separate ;: for((a=$1;a>0;a/=10));do s=$[s+(a%10)**${#1}];done;echo $[s==$1]. \$\endgroup\$
    – manatwork
    Commented Nov 15, 2013 at 11:08
  • 1
    \$\begingroup\$ By moving the evaluation into the for one more character can be shortened: for((a=$1;a>0;s+=(a%10)**${#1},a/=10));do :; done;echo $[s==$1]. \$\endgroup\$
    – manatwork
    Commented Nov 15, 2013 at 11:16
  • \$\begingroup\$ Oh, curious! I tried something like that, but it didn't work. Curious what went wrong. \$\endgroup\$ Commented Nov 16, 2013 at 1:53
3
\$\begingroup\$

Lua (101 chars)

Lua isn't known for being concise, but it was fun to try anyway.

for n in io.lines()do l,s=n:len(),0 for i=1,l do d=n:byte(i)s=s+(d-48)^l end print(s==tonumber(n))end

Improvements welcome.

\$\endgroup\$
1
  • \$\begingroup\$ As it is not required that your program can handle and process a list of numbers, I would not use bytes to implement that functionality. Replacing the loop for n in io.lines()do [...]end with n=io.read() saves some bytes (TIO). \$\endgroup\$ Commented Sep 1, 2017 at 19:55
3
\$\begingroup\$

Delphi - 166

uses System.SysUtils,math;var i,r,l:integer;s:string;begin r:=0;readln(s);l:=length(s);for I:=1to l do r:=round(r+power(strtoint(s[i]),l));writeln(inttostr(r)=s);end.

With indent

uses System.SysUtils,math;
var
  i,r,l:integer;
  s:string;
begin
  r:=0;
  readln(s);
  l:=length(s);
  for I:=1to l do
    r:=round(r+power(strtoint(s[i]),l));
  writeln(inttostr(r)=s);
end.
\$\endgroup\$
3
\$\begingroup\$

JavaScript - 70 58 characters

for(i in a=b=prompt())b-=Math.pow(a[i],a.length)
alert(!b)

Note:

If you're testing this in your dev console on Stack Exchange, be aware that there are a number of non-standard properties added to String.prototype that will break this solution, such as String.prototype.formatUnicorn. Please be sure to test in a clean environment, such as on about:blank.

\$\endgroup\$
6
  • \$\begingroup\$ I count 70 characters there. \$\endgroup\$
    – manatwork
    Commented Nov 15, 2013 at 16:10
  • \$\begingroup\$ @manatwork, whoops, forgot to count the newline. \$\endgroup\$
    – zzzzBov
    Commented Nov 15, 2013 at 19:10
  • \$\begingroup\$ Great trick that decrementation! \$\endgroup\$
    – manatwork
    Commented Nov 16, 2013 at 13:12
  • 2
    \$\begingroup\$ it always returns true for me, regardless of input \$\endgroup\$
    – koko
    Commented Jul 8, 2014 at 9:27
  • \$\begingroup\$ @koko, I've added a note to explain why you're receiving incorrect results. \$\endgroup\$
    – zzzzBov
    Commented Nov 8, 2016 at 15:00
3
\$\begingroup\$

Java - 84 bytes

(a,l)->{int s=0;for(byte c:a.getBytes())s+=Math.pow(c-48,l);return a.equals(""+s);};

Non-lambda version: 101 bytes:

boolean n(String a,int l){int s=0;for(byte c:a.getBytes())s+=Math.pow(c-48,l);return a.equals(""+s);}

Called like this:

interface X {
    boolean n(String a, int l);
}

static X x = (a,l)->{int s=0;for(byte c:a.getBytes())s+=Math.pow(c-48,l);return a.equals(""+s);};

public static void main(String[] args) {
    System.out.println(n("153",3));
    System.out.println(n("1634",4));
    System.out.println(n("123",3));
    System.out.println(n("654",3));
}

Returns:

true
true
false
false
\$\endgroup\$
2
3
\$\begingroup\$

Japt, 14 9 7 bytes

¶ì_xpZÊ

Try it online


Explanation

Implicit input of integer U.

ì_

Convert U to an array of digits (ì), pass it through a function and convert back to an integer after.

xpZÊ

Reduce by addition (x), raising each element to the power (p) of the length (Ê) of the array in the process.

Check if the result is strictly equal to U.

\$\endgroup\$
1
  • \$\begingroup\$ I think ¥U¬®n pUlÃx would work for 11 bytes ;) \$\endgroup\$
    – Oliver
    Commented May 18, 2017 at 17:39
3
\$\begingroup\$

Vyxal, 8 6 bytes

f⁰Le∑=

Try it Online!

f      # Map each digit to integer
   e   # (for each) to the power of 
 ⁰L    # Input length
    ∑  # Is sum...
     = # Equal to
       # (Implicit input)?

-2 thx to lyxal.

\$\endgroup\$
1
  • \$\begingroup\$ Try it Online! for 5 bytes \$\endgroup\$
    – lyxal
    Commented May 15, 2022 at 13:31
2
\$\begingroup\$

F# - 92 chars

let n=stdin.ReadLine()
n|>Seq.map(fun x->pown(int x-48)n.Length)|>Seq.sum=int n|>printf"%b"
\$\endgroup\$
2
\$\begingroup\$

Common Lisp - 116 102 characters

(defun f(m)(labels((l(n)(if(> n 0)(+(expt(mod n 10)(ceiling(log m 10)))(l(floor n 10)))0)))(= m(l m))))

Formatted:

(defun f(m)
  (labels((l(n)
            (if(> n 0)
               (+(expt(mod n 10)(ceiling(log m 10)))
                 (l(floor n 10)))
               0)))
    (=(l m)m)))
\$\endgroup\$
2
\$\begingroup\$

Smalltalk - 102 99 characters

[:n|a:=n asString collect:[:e|e digitValue]as:Array.^n=(a collect:[:each|each raisedTo:a size])sum]

At the Workspace, send value: with the number, and Print It.

\$\endgroup\$
2
\$\begingroup\$

C#, 117

using System.Linq;class A{int Main(string[] a){return a[0].Select(c=>c-'0'^a[0].Length).Sum()==int.Parse(a[0])?1:0;}}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.