Test a number for narcissism

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

• Is it ok if I output True if it's such a number, but anything else (in this case the number itself) if not? – devRicher Jan 6 '17 at 21:51

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
• what did i just read – Jbwilliams1 Feb 18 '14 at 20:13
• @LagWagon God's language – tomsmeding Jul 8 '14 at 8:00

Brachylog, 10 bytes

lg;?↔z^ᵐ+?


Try it online!

The predicate succeeds if the input is an Armstrong number and fails if it is not. If run as a full program, success prints true. and failure prints false.

lg;?↔z     A list of pairs [a digit of input, the length of input].
^ᵐ   A list of numbers where each is a digit of the input raised to the power of its length.
+  The sum of those numbers.
? Attempt to unify that sum with the input.

• Originally, this was nine bytes, but I realized that if I gave it a number more than nine digits long it would stop acting correctly, as previously I hadn't put g in there and it worked by virtue of single-digit lengths being length-1 sequences of themselves. – Unrelated String Mar 1 at 6:30

Tcl, 77 bytes

proc N n {expr [join [lmap d [split $n ""] {expr$d**[string le $n]}] +]==$n}


Try it online!

Retina, 118 bytes

Byte count assumes ISO 8859-1 encoding.

.*
$0$0¶$0 (?<=^\d*)\d x (?=.*$)
¶
0¶

\d+
$* ¶(1+) ¶$1 $1 {^x ? }s(?<=x.*)1(?=1* (1+))$1
1*

1¶1
11
^(1*)¶+\1\b


Try it online

Explanation

.*                          # Copy number 3 times. For Length, Unary, and Digits
$0$0¶$0 (?<=^\d*)\d # Convert first copy to x's (Length) x (?=.*$)                     # Split up digits of last copy, each on their own line
¶
0¶                          # Remove zeros, because they leave blank lines

\d+                         # Convert to unary
$* ¶(1+) # Duplicate each separated digit ¶$1 $1 {^x ? # While x's exist, remove an x ... }s(?<=x.*)1(?=1* (1+)) # and multiply each value by the digit (nth power)$1
1*                         # Remove original digits

1¶1                         # Remove lines between digits
11
^(1*)¶+\1\b                 # Match if values are equal


Ly, 51 bytes

ns>lS0sp11[ppl:Isp>l<ysp>l<sp>,^<lsy,=!]>&+s<<l=fp


Try it online!

Pari/GP, 35 bytes

n->n==vecsum([d^#s|d<-s=digits(n)])


Try it online!

K (ngn/k), 22 bytes

{x~+/*/'(#:r)#'r:10\x}


Try it online!

• there's no need for a : after a monadic verb, #:r -> #r – ngn Nov 5 '18 at 17:53

Javascript (ES6) 46 bytes - Not competing

n=>(s=[...''+n]).forEach(v=>n-=v**s.length)|!n


Explanation:

n=>
(s=[...''+n])        // Convert input to array of chars and assign to s
.forEach(v=>       // Loop over s (returns undefined)
n-=v**s.length)  // reduce input by char^length
|                  // undefined is falsy, so we OR
!n                 // OR with negated input
// returns 1 if 0, 0 otherwise


Kotlin, 60 bytes

map{Math.pow(it-'0'+0.0,length+0.0)}.sum()==this.toInt()+0.0


Beautified

map {
Math.pow(it - '0' + 0.0, length + 0.0)
}.sum() == this.toInt() + 0.0


Test

fun String.f() =
map{Math.pow(it-'0'+0.0,length+0.0)}.sum()==this.toInt()+0.0

fun main(args: Array<String>) {
(0..1000).filter { it.toString().f() }.forEach { println(it) }
}


TryItOnline

APL (Dyalog Unicode), 8 bytesSBCS

Tacit prefix function taking the input as a string.

⍎≡1⊥⍎¨*≢


Try it online!

⍎ is the evaluated argument

≡ identical to

1⊥ the sum (lit. convert from base-1) of

⍎¨ the evaluated characters (i.e the digits)

* raised to the power of

≢ the tally of characters (i.e. digits)

JavaScript (ES7), 43 38 bytes

Takes input as a string.

n=>n==eval([...n,0].join**n.length+)


Try It

f=
n=>n==eval([...n,0].join**n.length+)
o.innerText=f(i.value="153")
oninput=_=>o.innerText=f(i.value)
<input id=i type=number><pre id=o>

CJam, 12 bytes

{_Ab_,f#:+=}


Try it online!

Explanation:

{          }   anonymous block, input: 1634
b           get digits in base
A              10: [1 6 3 4]
,         take the length: 4
#       and raise
f          each element
_              of the list of digits
to that power: [1 1296 81 256]
:      fold over
=    and compare
_               to the original: 1 (true)


Pyt, 11 bytes

ĐĐḶ⌊⁺⇹ą⇹^Ʃ=


Explanation:

                      Implicit input
ĐĐ                    Duplicate the input twice
Ḷ⌊⁺                Get number of digits in the input
⇹ą              Convert input to array of digits
⇹^Ʃ           sum the digits raised to the power of the number of digits
=          equals input?


Try it online!

L,BDdbLdXBcBsA=


Try it online!

JavaScript 7, 41 Bytes

s=>[...s].map(x=>N+=x**s.length,N=0)|N==s


JavaScript 46 bytes

F=n=>![...n].reduce((x,c)=>x-(+c)**n.length,n)

console.log(F("153") == true)
console.log(F("370") == true)
console.log(F("371") == true)
console.log(F("152") == false)
console.log(F("150") == false)

• Is it necessary to convert c into number? – l4m2 Jan 5 '18 at 4:14

Swift 3.2: 107 characters

Of course Swift is absolutely not a quick language but I thought I would try:

func n(s:String){let c=s.utf8.map{Double($0)-48};print(c.reduce(0){$0+pow($1,Double(c.count))}==Double(s))}  Perl 5, 24 bytes 21 bytes of code + 3 for -pF flags for$i(@F){$_-=$i**@F}


Try it online!

Japt, 149 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.

• I think ¥U¬®n pUlÃx would work for 11 bytes ;) – Oliver May 18 '17 at 17:39

R, 71696656 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.

• 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). – Iszi Nov 14 '13 at 20:40
• Integer division doesn't round... The integer division of 370 by 100 is 3 with the remainder of 70 and not 3.70. – plannapus Nov 15 '13 at 7:40
• 48 bytes...somebody bumped this to the homepage! – Giuseppe Sep 1 '17 at 19:55

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.

• +1 i would have never thought of doing that, it's brilliant. – plannapus Nov 15 '13 at 16:26

Pyth (non-competing), 10 bytes

qsm^sdlQ


Verify the test cases.

Python 2, 44 bytes

I think this is the shortest you can get for Python. Uses a lambda rather than a full program.

lambda s:sum(int(x)**len(s)for x ins)==s


Try it online!

lambda s:sum(map(lambda x:int(x)**len(s),s))==s


Try it online!

echo $[ printf "+%c**${#1}" $(fold -w1<<<$1) == $1 ]  Try it online! Takes input as parameter, outputs 1 if is narcissist, 0 if not. fold prints each digit one per line, printf adds +<digit>**<length> forming the arithmetic expression which is evaluated and compared to the original input. Befunge 98, 58 bytes 1-00p&:a\v 00g1+00p>:a%\a/:!kv \:9kv00gk:00gk*+> @.!-$<


Try it Online!

I'm sure this can be golfed further. I will take another look at it and add an explanation later...

Pushy, 9 bytes

Note that this answer is non-competing as Pushy postdates the challenge. However, I thought I'd post it because it's interestingly short for a simple stack-based language:

VsLKeS^=#


Try it online!

It works like this (how the two stacks would look for the example input is shown on the right):

    \ Implicit input, for example 1634.  [1634], []
V   \ Copy into second stack.            [1634], [1634]
s   \ Split into individual digits       [1,6,3,4], [1634]
L   \ Push stack length                  [1,6,3,4,4], [1634]
Ke  \ Raise all to this power            [1,1296,81,256], [1634]
S   \ Take sum                           [..., 1634], [1634]
^=  \ Check equality with initial input  [..., True], []
#   \ Output this boolean (as 0/1)


{$_==sum .comb.map(* **.comb)}  Pretty straightforward. The chars method would be more typically used to get the number of characters in the input string, but comb returns those characters as a list, which evaluates to the number of characters in numeric context, and saves us a byte. Jelly, 6 bytes (non-competing) D*L$S=


Try it online!

D        Get the digits of the input
*L$Raise each element to power of its length S Sum = Equals input?  JavaScript (ES6), 56 bytes eval(${n=prompt()}0.split.join(**\${n.length}+))==n


Python, 90 Bytes

a,z=input(),[]
for x in list(a):z.append(int(x)**len(a))
print(1 if sum(z)==int(a) else 0)
`