I've been going through some code challenges. And one struck me in particular. CodeAbbey has a Weighted Sum of Digits challenge. And this was my answer.
# open and read a file, hardcoded numbers, etc. Here is a sample
raw_data = (6, 19, 64, 6527226, 12345146)
for number in raw_data:
wsd = 0 # Stores sum
number_list = list(str(number)) # Converts the number into a list.
for i, k in enumerate(number_list): # Enumerates each number
wsd += (int(i+1) * int(k)) # Multiplies and adds product to wsd
print(wsd)
output >>> 6, 19, 14, 114, 137
Anyone with more experience able to see a better way of getting the sum?
If using map:
>>> map(lambda d: sum([ (i+1) * int(v) for i,v in enumerate(list(str(d)))]), raw_data)
[6, 19, 14, 114, 137]
for number in raw_data:
print(sum(i * int(d) for i, d in enumerate(str(number), 1)))
This can be done entirely using math operations. Look how the sum is generated, e.g. for 12345146:
6
4+6
1+4+6
5+1+4+6
4+5+1+4+6
3+4+5+1+4+6
2+3+4+5+1+4+6
+ 1+2+3+4+5+1+4+6
So firs you add last digit, then last and previous, then last, previous and previous etc. until you add all digits. And this can be simply implemented by following algorithm:
raw_data = (6, 19, 64, 6527226, 12345146)
for d in raw_data:
wsd = 0
lst = 0 # this is for holding last 'sum row'
while d > 0:
lst = lst + d % 10 # append another digit
wsd += lst
d //= 10
#
print wsd
#
On my computer this is about two times faster than algorithms using enumeration and string conversion (I multiplied raw_data 100000 times, thus getting 500000 elements for comparison).