Не могу придумать алгоритм для решения задачи на Python

Условие:

Сколько существует целых положительных чисел таких, что их запись в восьмеричной системе счисления оканчивается на две одинаковые цифры, запись не содержит цифр 0, и сумма цифр в записи равна 8. В ответе укажите целое число.


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

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

ну алгоритм то простой:

count = 0
for i in range(1, 2396745 + 1):
    # определяем цифры 8ричной записи
    digits = []
    value = i
    while value > 0:
        digits.append(value % 8)
        value = value // 8

    # проверяем условие
    if sum(digits) == 8 and len(digits) > 1 and digits[0] == digits[1] and 0 not in set(digits):
        count += 1

print(count)

но вот сколько таких чисел - вопрос, алгоритм пока 43 насчитал, так что тут надо теоретически думать

P.S.

решил, то, что запись не содержит 0, а сумма цифр равна 8 означает, что надо рассмотреть максимум число

0o11111111 = 2396745

P.P.S.

чуть более быстрый алгоритм - сначала проверяем 2 последние цифры и только после этого разбираем число на цифры:

count = 0

for i in range(1, 2396745 + 1):
    digits = []
    value = i

    if value % 8 != (value // 8) % 8:
        continue

    while value > 0:
        digits.append(value % 8)
        value = value // 8

    if sum(digits) == 8 and 0 not in set(digits):
        count += 1

Еще чуть более быстрый алгоритм без использования списков и множеств:

count = 0

for i in range(1, 2396745 + 1):
    value = i

    if value % 8 != (value // 8) % 8:
        continue

    digits_sum = 0
    digits_prod = 1

    while value > 0:
        digit = value % 8
        digits_sum += digit
        digits_prod *= digit
        value = value // 8

    if digits_sum == 8 and digits_prod != 0:
        count += 1

проверку на 2 одинаковые последние цифры можно заменить на более быстрый код:

# не анализировать, если последние 2 цифры не равны (в 10 ричной системе это означает кратноть 9)
if (value % 64) % 9 != 0 or (value % 64) == 0:
    continue
→ Ссылка
Автор решения: Harry

Опять при всем уважении к Zhihar...

Но не лучше ли пойти с конца? Рассмотреть возможные варианты окончания — 11, 22, ..., 44 и к ним — количество представлений чисел 6, 4, 2, 0 всякими (ненулевыми :)) цифрами.

def cnt(s):
    if s < 0:  return 0
    if s == 0: return 1
    sum = 0
    for i in range(1,7):
        sum = sum + cnt(s-i)
    return sum

sum = 0
for i in range(0, 7, 2):
    sum = sum + cnt(i)

print(sum)

Результат верный — те же 43, глубина рекурсии очень небольшая, так что какая-нибудь мемоизация ни к чему.

Сам код — по сути перевод изначально написанного мною на С++, так что если можно написать красивее — перепишите...

Время у Zhihar — 1,06 c, у меня — 0,02 с...

→ Ссылка