53
\$\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):

13 + 53 + 33 = 1 + 125 + 27 = 153

1634:

14 + 64 + 34 + 44 = 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 list, does not qualify.

OEIS A005188

\$\endgroup\$
  • 3
    \$\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 Jan 6 '17 at 21:51

73 Answers 73

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
| improve this answer | |
\$\endgroup\$
  • 9
    \$\begingroup\$ what did i just read \$\endgroup\$ – Jacob Feb 18 '14 at 20:13
  • 4
    \$\begingroup\$ @LagWagon God's language \$\endgroup\$ – tomsmeding Jul 8 '14 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)
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I did a double-take on `` ~.` `` but it seems impossible to improve. Nice one. \$\endgroup\$ – Peter Taylor Nov 20 '13 at 17:28
15
\$\begingroup\$

Mathematica, 43 chars

Tr[#^Length@#&@IntegerDigits@#]==#&@Input[]
| improve this answer | |
\$\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.

| improve this answer | |
\$\endgroup\$
  • \$\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 Nov 14 '13 at 12:26
  • \$\begingroup\$ I think so long as you define what your true and false outputs are, it should be legal \$\endgroup\$ – Cruncher Nov 14 '13 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 Nov 14 '13 at 20:47
  • \$\begingroup\$ Same idea but shorter: perl -pe'map$s+=$_**@y,@y=/./g;$_=$_==$s' \$\endgroup\$ – msh210 Jun 19 '16 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.

| improve this answer | |
\$\endgroup\$
  • 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\$ – John Dvorak Nov 14 '13 at 4:45
  • \$\begingroup\$ @JanDvorak My bad -- added keyboard input. \$\endgroup\$ – rationalis Nov 14 '13 at 6:08
12
\$\begingroup\$

Ruby, 34+5=39

With command-line flags

ruby -nlaF|

Run

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

Outputs true or false.

| improve this answer | |
\$\endgroup\$
  • 3
    \$\begingroup\$ This may be the most Ruby flags I've ever seen in a legitimate code golf :P \$\endgroup\$ – Doorknob Nov 21 '13 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.

| improve this answer | |
\$\endgroup\$
  • \$\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 Nov 14 '13 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 Nov 15 '13 at 7:40
  • 1
    \$\begingroup\$ 48 bytes...somebody bumped this to the homepage! \$\endgroup\$ – Giuseppe Sep 1 '17 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))
| improve this answer | |
\$\endgroup\$
  • 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 Nov 14 '13 at 7:12
  • \$\begingroup\$ That's awesome! Thanks for the tip. \$\endgroup\$ – danmcardle Nov 14 '13 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 Nov 16 '13 at 17:31
  • \$\begingroup\$ Good point, edited. \$\endgroup\$ – danmcardle Nov 17 '13 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\$ – Martin Thoma Nov 18 '13 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.

| improve this answer | |
\$\endgroup\$
  • \$\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 Nov 14 '13 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 Nov 14 '13 at 15:09
  • \$\begingroup\$ @manatwork: Thank you for the warm welcome to codegolf :) \$\endgroup\$ – Vlad Preda Nov 14 '13 at 15:13
  • \$\begingroup\$ Can be golfed to this for(;$i<$l=strlen($a=$argn);)$s+=$a[$i++]**$l;echo$s==$a; \$\endgroup\$ – Jörg Hülsermann May 17 '17 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
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Never actually used dc, save for frantic typos in attempt to write cd \$\endgroup\$ – Stan Strum Jan 5 '18 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}
| improve this answer | |
\$\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.

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

Kona, 18

...

{x=+/(0$'u)^#u:$x}
| improve this answer | |
\$\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
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I was wondering if someone was going to do PowerShell before I did. \$\endgroup\$ – Iszi Nov 14 '13 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 Nov 14 '13 at 21:03
  • 1
    \$\begingroup\$ 61 chars: ($x=$n=read-host)-split''|%{$x-=[math]::pow($_,$n.length)};!$x \$\endgroup\$ – Danko Durbić Nov 15 '13 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 Nov 15 '13 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 Nov 15 '13 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`)
| improve this answer | |
\$\endgroup\$
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);
}
| improve this answer | |
\$\endgroup\$
  • 2
    \$\begingroup\$ You don't have to define int for global variables. \$\endgroup\$ – Konrad Borowski Jan 10 '14 at 15:49
  • \$\begingroup\$ Woah. You're reading the input into argc. \$\endgroup\$ – SIGSTACKFAULT Jan 6 '17 at 14:16
  • \$\begingroup\$ Also, shouldn't having to do -lm at compile-time count +1 byte? \$\endgroup\$ – SIGSTACKFAULT Jan 6 '17 at 14:21
  • \$\begingroup\$ @Blacksilver the -lm flag is not required for C89 compilers. \$\endgroup\$ – Josh Jan 9 '17 at 14:55
  • \$\begingroup\$ Aha. Learn a new thing every day. \$\endgroup\$ – SIGSTACKFAULT Jan 9 '17 at 14:59
4
\$\begingroup\$

05AB1E, 7 bytes (Non-competing)

DSDgmOQ

Try it online!

-2 bytes thanks to @daHugLenny

| improve this answer | |
\$\endgroup\$
  • 3
    \$\begingroup\$ You can replace §1ô with S \$\endgroup\$ – acrolith Nov 8 '16 at 15:45
3
\$\begingroup\$

Haskell 2010 - 76 characters

main=do x<-getLine;print$(==x)$show$sum$map((^length x).(+(-48)).fromEnum)x
| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ You shouldn't post the number of ms to run the code, but the number of chars you used. ;) \$\endgroup\$ – user unknown Nov 15 '13 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
| improve this answer | |
\$\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))

| improve this answer | |
\$\endgroup\$
  • 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 Nov 15 '13 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 Nov 15 '13 at 11:16
  • \$\begingroup\$ Oh, curious! I tried something like that, but it didn't work. Curious what went wrong. \$\endgroup\$ – user unknown Nov 16 '13 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.

| improve this answer | |
\$\endgroup\$
  • \$\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\$ – Jonathan Frech Sep 1 '17 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.
| improve this answer | |
\$\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.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I count 70 characters there. \$\endgroup\$ – manatwork Nov 15 '13 at 16:10
  • \$\begingroup\$ @manatwork, whoops, forgot to count the newline. \$\endgroup\$ – zzzzBov Nov 15 '13 at 19:10
  • \$\begingroup\$ Great trick that decrementation! \$\endgroup\$ – manatwork Nov 16 '13 at 13:12
  • 2
    \$\begingroup\$ it always returns true for me, regardless of input \$\endgroup\$ – koko Jul 8 '14 at 9:27
  • \$\begingroup\$ @koko, I've added a note to explain why you're receiving incorrect results. \$\endgroup\$ – zzzzBov Nov 8 '16 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
| improve this answer | |
\$\endgroup\$
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.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ I think ¥U¬®n pUlÃx would work for 11 bytes ;) \$\endgroup\$ – Oliver May 18 '17 at 17:39
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"
| improve this answer | |
\$\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)))
| improve this answer | |
\$\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.

| improve this answer | |
\$\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;}}
| improve this answer | |
\$\endgroup\$
2
\$\begingroup\$

Haskell, 68 66 bytes

d 0=[]
d n=mod n 10:d(div n 10)
sum.(\a->map(^length a)a).d>>=(==)

Usage:

*Main> sum.(\a->map(^length a)a).d>>=(==) $ 1634
True
| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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