Найти сумму чисел в последовательности

Нужно найти сумму чисел в следующей последовательности: 2, 22, 222, 2222, ..., 2(n), - где, n - количество разрядов в последнем числе

Для примера, n = 5 последнее число будет 22222, а сумма чисел в последовательности - 24690.

n = 5  # кол-во разрядов
last_num = 0  # итоговое число
i = 1  # счетчик разрядов
sum = 0  # 2 + 22 + 222 + 2222 + 22222 => 24690

while n > 0:
    last_num += 2 * i
    i *= 10
    n -= 1
print(last_num)
while last_num != 0:
    sum += last_num // 10
    last_num //= 10
print(sum)

Понимаю, что код кривой, так как только начал учит Python. Подскажите пожалуйста, как найти сумму чисел, поскольку условие sum += last_num // 10 "отсекает" первую двойку и по итогу сумма получается из чисел 2222 + 222 + 22 + 2 = 2468, вместо 22222 + 2222 + 222 + 22 + 2 = 24690.


Ответы (6 шт):

Автор решения: Vestalt

У вас появляется ошибка, потому что вы отсекаете последнюю цифру дважды (sum += last_num // 10 и last_num //= 10). Нужно убрать одно из действий:

n = 5  # кол-во разрядов
last_num = 0  # итоговое число
i = 1  # счетчик разрядов
sum_ = 0  # 2 + 22 + 222 + 2222 + 22222 => 24690

while n > 0:
    last_num += 2 * i
    i *= 10
    n -= 1
print(last_num)
while last_num != 0:
    sum_ += last_num
    last_num //= 10
print(sum_)

22222
24690

Кстати, код вполне нормальный. Только имя sum в python зарезервировано под функцию, поэтому его не стоит использовать в качестве названия переменной.

В таких случаях можно добавлять '_' к концу имени.

→ Ссылка
Автор решения: Сергей

Основная ошибка - излишняя сложность. У вас идея верная, но уберите две строки. Python призывает к лаконичности и ясности, начинайте решение с продумывания самого лаконичного и ясного варианта. Но ясность важнее лаконичности.

n = 5  # кол-во разрядов
last_num = 0  # итоговое число
i = 1  # счетчик разрядов
sum1 = 0  # 2 + 22 + 222 + 2222 + 22222 => 24690

while n > 0:
    last_num += 2 * i
    i *= 10
    n -= 1
    sum1 += last_num
print(sum1)
→ Ссылка
Автор решения: Stanislav Volodarskiy

Можно не отсекать, а накапливать:

  • term - слагаемое: 0, 2, 22, 222, ..., 2(n);
  • sum_ - накопительная сумма: 2 + 22 + 222 + ...;
  • n - счётчик итераций.

Проще некуда:

n = 5
sum_ = 0
term = 0
while n > 0:
    term = 10 * term + 2
    sum_ += term
    n -= 1
print(sum_)

Если применить немного изобретательности, слагаемые можно считать напрямую. На одну переменную меньше, но понять что происходит сложнее:

n = 5
sum_ = 0
while n > 0:
    sum_ += 2 * (10 ** n - 1) // 9
    n -= 1
print(sum_)

И ещё немного изобретательности: есть замкнутая формула для ответа. Одна строка и долгие объяснения почему так:

n = 5
print(2 * ((10 ** (n + 1) - 1) // 9 - n - 1) // 9)
→ Ссылка
Автор решения: CrazyElf

В одну строчку по приколу, но тут используется строковое представление цифры для удобства:

n = 5
k = '2'
print(sum(int(k*i) for i in range(1, n+1)))
# 24690

Просто "размножаем" цифру нужное число раз (для этого она должна быть строкой), превращаем в число, всё это в цикле и дальше суммируем.

→ Ссылка
Автор решения: TigerTV.ru

Еще вариант:

from functools import reduce

n = 5
d = 2
res = [0] * n
q = 0
for i in range(n, 0, -1):
    q, res[i-1] = divmod(q + i * d, 10)

print(*res, sep='')                     # 24690
print(''.join(map(str,res)))            # 24690
print(reduce(lambda x, y: 10*x+y, res)) # 24690

Или так:

from itertools import accumulate, repeat

n = 5
d = 2
print(sum(accumulate(repeat(d, n), lambda x, y: x * 10 + y))) # 24690
→ Ссылка
Автор решения: EugK

Простое, быстрое, однострочное, кастомизируемое решение для любой версии питона, поддерживающего f-strings, работающее для любого n за O(n)

n = 1_000_000
digit = 2
print(sum([int(f"{digit}" * el) for el in range(1, n + 1)]))
→ Ссылка