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
\$\endgroup\$
  • 9
    \$\begingroup\$ what did i just read \$\endgroup\$ – Jbwilliams1 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)
\$\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[]
\$\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\$
  • \$\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.

\$\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.

\$\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.

\$\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))
\$\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.

\$\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
\$\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}
\$\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\$
  • \$\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}
\$\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\$
  • \$\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`)
\$\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);
}
\$\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\$

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\$
4
\$\begingroup\$

05AB1E, 7 bytes (Non-competing)

DSDgmOQ

Try it online!

-2 bytes thanks to @daHugLenny

\$\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
\$\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
\$\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\$
  • 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.

\$\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\$

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\$
  • \$\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
\$\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.

\$\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"
\$\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\$
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
\$\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.