3

I am working on this seemingly simple problem, where I need to add one to every digit of a number. Example: number = 1234 ; output = 2345

That's simple, but when 9 is one of those digits, then by the law of addition, that 9 will be replaced by 0 and 1 will be added to the number on the left (9 + 1 = 10, hence, place value = 0 & carry over = 1) Example: number = 1239 ; output = 2350

number = 1234
s = str(number)
l = []

for num in s:
    num = int(num)
    num += 1
    if num > 9:
        num = 0
        l.append(num)
    else:
        l.append(num)

print int(''.join(str(v) for v in l))

Can someone please explain to me, what logic should I use? I can see something on the lines of modular arithmetic, but not really sure how to implement that. Thanks :)

hky404
  • 1,039
  • 3
  • 17
  • 35

3 Answers3

7

A simple approach would be as follows

Consider a number N = anan-1an-2...a0

Then F(N) = N + (10n-1+10n-2 .. 100) = N + int('1' X N) = N + (10n - 1) / (10 - 1) = N + (10n - 1) / 9

>>> def foo(N):
    return N + int('1'*len(str(N)))

>>> foo(1234)
2345
>>> foo(1239)
2350

Edit: Simplifying a bit by utilizing sum of power formula

>>> def foo(N):
    return N + ((10**len(str(N)) - 1) // 9)
Abhijit
  • 62,056
  • 18
  • 131
  • 204
  • 1
    Whoa this is elegant. Can you explain this? It's early morning for me and without coffee I can't wrap my brain around this :). Also, you can do this without importing `math` I believe – Parker Oct 25 '14 at 17:51
  • 1
    @Parker: Explanation added. And yes you can do without math. Initially I was thinking to add `log` magic to find the length of the string and then I realized its an overkill and moreover there are precision issues. – Abhijit Oct 25 '14 at 17:54
  • @Abhijit wow! fantastic!! Didn't even think on the lines of that. Awesome!! Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. - Zen of Python :D – hky404 Oct 25 '14 at 18:07
  • Nice! You might want to make sure `10**len(str(N)) / 9` always returns an integer though (Python 3...) – Alex Riley Oct 25 '14 at 18:10
2

With pure math:

num = num + (10**int(math.ceil(math.log10(num)))-1)//9
Daniel
  • 42,087
  • 4
  • 55
  • 81
2

Your code can be easily modified to process the digits in reversed order and maintain the carry state. The "modular arithmetic" you're looking for is typically implemented using the % operator:

number = 1234
s = str(1234)
l = []

carry = 0
for num in reversed(s):
    num = int(num) + carry
    num += 1
    carry = num / 10
    l.append(num % 10)

print int(''.join(str(v) for v in reversed(l)))
user4815162342
  • 141,790
  • 18
  • 296
  • 355