Определить старшие разряды числа и вычислить из сумму, не используя циклы и строки

Необходимо определить старшие разряды введенного числа и вычислить их сумму без использования циклов и строк.

моя попытка:

a = int(input("Введите число: "))
count = len(str(a))
n = count // 2
if count == 4:
    one = a // 1000
    two = (a // 100) % 10
    sum = one + two
elif count == 3:
    one = a // 100
    two = (a // 10) % 10
    sum = one + two
elif count == 2:
    one = a // 10
    sum = one
print(f"Сумма элементов старших разрядов: {n}")

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

Автор решения: Vladimir Bogdanov

Если задуматься, то задача не так уж проста. Привожу вариант на итераторе (который не попал в список запрещенных), без циклов (под циклами я понимаю for и while), без конвертации в строку и без условных операторов (if и match). Но так или иначе без прохода по числу не обойтись, что и делает итератор. Существует вариант с использованием log10, но тогда, во-первых, придется импортировать библиотеку math, во-вторых, появляются нюансы с числами кратными 10. Предложенный алгоритм задействует особенность функции iter вызывать некую функцию до тех пор, пока не будет получено триггерное значение (в данном случае кортеж (0,0)). Функция get_digits сохраняет свое состояние между вызовами в собственном атрибуте 'num', дабы хранить остаток от деления на 10 исходного числа. Алгоритму не важен размер заданного числа.

num = 12345
# Функция раскладывает число на цифры
# Как только цифры закончатся, вернет (0,0)
def get_digits():
    get_digits.num = getattr(get_digits,'num',(abs(num),0))
    get_digits.num = divmod(get_digits.num[0], 10)
    return get_digits.num
# Итератор вызывает функцию до тех пор, пока не получит (0,0)
digits = (*iter(get_digits, (0,0)),)[::-1]
# Оставляем только остаток от деления
digits=tuple(map(lambda item: item[1], digits))
# Как альтернатива, можно получить digits одной строкой
# digits = tuple(map(lambda item: item[1],(*iter(get_digits, (0,0)),)[::-1]))
# Вычисляем количество старших разрядов
idx = len(digits) // 2 + len(digits) % 2
print(f"Сумма элементов старших разрядов: {sum(digits[:idx])}")
→ Ссылка
Автор решения: Stanislav Volodarskiy

Если можно функции, то есть рекурсивное решение. high_sum – просто обёртка. Вся работа делается внутри rec. Параметр n скачет по числу через два разряда, m перебирает все разряды. s накапливает сумму. На каждой итерации к s прибавляются две цифры (n % 10 + n // 10 % 10) и вычитается одна (m % 10).

Множитель n // 10 and 1 равен нулю если мы добрались до старшего разряда в n и количество разрядов нечётно. В противном случае он равен единице. Он нужен чтобы при нечётном числе разрядов средний разряд включался в сумму.

n or ... выполняет ... если n равно нулю.
n and ... выполняет ... если n не равно нулю.

def high_sum(n):

    def rec(n, m, s):
        n or print(s)
        n and rec(
            n // 100,
            m // 10,
            s + n % 10 + n // 10 % 10 - (m % 10) * (n // 10 and 1)
        )

    rec(n, n, 0)


high_sum(int(input()))
$ echo 1234 | py temp.py
3

$ echo 12345 | py temp.py
6

$ echo 123456 | py temp.py
6

P.S. От некрасивого множителя n // 10 and 1 можно избавиться предварительно умножив n на десять:

def high_sum(n):

    def rec(n, m, s):
        n or print(s)
        n and rec(n // 100, m // 10, s + n % 10 + n // 10 % 10 - m % 10)

    rec(10 * n, 10 * n, 0)


high_sum(int(input()))
→ Ссылка