Lucas Almeida
Lucas Almeida

Reputation: 33

Narcissistic numbers in Python

I am beginner to the Python programming language and I have been using a website to help me exercise. It gave me this challenge to make a program that returns true if a given number is narcissistic or false otherwise.

Examples of narcissistic numbers:

153 (3 digits): 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153
1634 (4 digits): 1^4 + 6^4 + 3^4 + 4^4 = 1 + 1296 + 81 + 256 = 1634

But for some reason when the number 371 is given the function returns False instead of True.

The code:

def narcissistic(value):
    logical = True
    logical2 = True
    i = 0
    j = 0
    notation = 10
    sum = 0

    #Calculating the number notation 
    while logical:
        if 10 ** i <= value:
            notation = 10 ** i
            i = i + 1
        else:
            logical = False

    #i from now on is also the qauntity of digits
    while logical2:
        if ( notation / 10 ** j ) >= 1:
            sum = sum + ( value // ( notation / 10 ** j ) ) ** i
            j = j + 1
        else:
            logical2 = False

    if sum == value:
        return True
    else:
        return False

Upvotes: 2

Views: 3022

Answers (5)

Med Sep
Med Sep

Reputation: 344

This can be solved using list comprehension in 1 line of code.

def Narcissistic(x):
        y = sum([int(i)**(len(x)) for i in (x)])
return Narcissistic(x)

Upvotes: 0

d.b
d.b

Reputation: 32538

Could grab individual digits without converting to string

import math
def narcissistic(value):
    n = math.floor(math.log10(value)) + 1
    x = [math.floor((value/10**i)%10)**n for i in range(n)]   
    print(sum(x) == value)

narcissistic(371)
#True

Upvotes: 2

R Borges
R Borges

Reputation: 197

change ^ to **

def narcissistic(number):
  number_string = str(number)
  number_len = len(number_string)

  number_nar = 0
  for char in number_string:
    number_nar+= int(char) ** number_len        
  return number_nar

number = 153
number_nar = narcissistic(number)
print(number_nar)

number = 1634
number_nar = narcissistic(number)
print(number_nar)

output:

153

1634

Upvotes: 0

Nick Reed
Nick Reed

Reputation: 5059

Your code is very close! The issue lies here:

sum = sum + ( value // ( notation / 10 ** j ) ) ** i

For 1634, this multiplies 1, 16, 163, and 1634. You need only the LSB of these numbers, in this example 1, 6, 3, and 4 - use the modulo operator to get this. If we mod them by 10 to get only the LSB...

sum = sum + (( value // ( notation / 10 ** j ) ) % 10) ** i

...then the code works perfectly.

Demo

Upvotes: 4

Green Cloak Guy
Green Cloak Guy

Reputation: 24681

It would probably be easier to do this task by converting the value to a string and back. Taking the length of the string is an easy way to get the number of digits ("the poor man's logarithm"), and you can easily iterate over individual digits:

def narcissistic(value):
    str_value = str(value)
    num_digits = len(str_value)
    return (value == sum(int(digit) ** num_digits for digit in str_value))
>>> narcissistic(153)
True
>>> narcissistic(1634)
True
>>> narcissistic(371)
True
>>> narcissistic(372)
False

Upvotes: 4

Related Questions