Optimizing code – Part 0
This first part will deal with setting up the problem and the first initial code.
Problem
The problem to solve is to find the first x amount of Narcissistic Numbers . What they are is easy to explain. The process by which to identify if a number is narcissistic is by following these steps:
- Separate number into individual numerals
- Raise each numeral to the power that is equal to the total amount of numerals (length of the number)
- Sum those results together
- If that sum is equal to the original number then it is narcissistic
A quick example is 153 .
- Separate numerals are 1, 5 and 3.
- 1 ** 3 = 1, 5 ** 3 = 125 and 3 ** 3 = 27
- 1 + 125 + 27 = 153
- 153 == 153 is true
Therefore 153 is narcissistic. By looking at this algorithm we can see that all numbers with length 1 are narcissistic. Since something to the power of 1 is itself.
Naive code
The naive implementation is the following:
import sys
from datetime import datetime
def is_narcissistic(x: int) -> bool:
str_x = str(x)
s = sum([int(i) ** len(str_x) for i in str_x])
return s == x
def find_narcissistic_numbers(desired: int) -> None:
for x in range(sys.maxsize):
if is_narcissistic(x):
desired -= 1
if desired == 0:
return
start = datetime.utcnow()
find_narcissistic_numbers(28)
print(datetime.utcnow() - start)
This code will make the number we are checking into a string and by utilizing Python iterators it will iterate over each character in the string and therefore we have step 1 down. Then in the list comprehension we also raise to the power that is the length of the string (amount of numerals) and we sum it . This is step 2 and 3. Then we check the original with that sum and get step 4.
The total run time for this code on my laptop is : 0:08:09.315972
Let us look in future parts how we can optimize this code.