Если немного подумать головой, то перебор сокращается до чисел:
- Кратных трём. Это оставляет для перебора 30 чисел вместо 90, от 12 до 99 с шагом 3.
- Не имеющих в составе цифр нуля (долой ещё 3 числа: 30, 60, 90).
- Ограниченных произведением цифр снизу - 4 = 12 / 3, а сверху - 32 = 96 / 3 (произведение 33 = 99 / 3 отпадает как кратное 11, у нас же нет цифры 11).
- Некратных 11, 13 и большим простым числам. Или, формулируя по-другому, имеющих только такие простые делители, которые меньше 10. Это 2, 3, 5, 7.
- Причём, если число содержит цифру, то оно обязано на неё делиться, что сразу исключает из состава цифр 7 (на 7 делятся только 70 и 77, и они оба некратны трём).
- Числа с цифрой 8, делящиеся на 8, - это 48, 80, 88, причём, 2 последних не подходят как некратные трём.
- Числа с цифрой 9 должны делиться аж на 27. Таких чисел в пределах сотни нет.
- Также, по признаку делимости на 3, сумма цифр должна делиться на 3, значит, если одна из цифр - 3 или 6 (9 не подходит), то другая цифра - это тоже 3 или 6. 33 и 66 делятся на 11, 63 - на 7, для проверки остаётся только 36, не имеющее "плохих" делителей.
- Если число ab (составленное из цифр a и b) подходит, то число ba не подходит, т.к. у него то же самое произведение цифр.
- И ещё немного о выражении, которое является критерием отбора чисел:
a * b * 3 - a * 10 - b == 0
a * (b * 3 - 10) - b == 0
b * 3 > 10 (и это ещё мягко сказано)
b >= 4
a = b / (b * 3 - 10)
Только при b = 4 или b = 5 правая часть является натуральным числом.
Итак, для перебора остаются числа, кратные трём, и содержащие цифры из множества {1, 2, 4, 5}, причём, сумма цифр должна быть кратна трём, что вместе с ограничением (10) сужает комбинации до пар {1, 5}, {2, 4}, {4, 5}, причём, в первых двух из них большая цифра должна быть младшей. Впрочем, 51 и 42 имеют "плохие" делители и в любом случае не подошли бы.
Заметим ещё, что числа 45 и 54 нам тоже не подойдут, т.к. не делятся на одну из своих цифр (цифру 4).
А числа 36 и 48, упомянутые в пп. 6 и 8, не подходят по условию (10).
В итоге, мы снизили мощность множества для перебора с 90 до 2 чисел.
for a, b in ((1, 5), (2, 4)):
n = a * 10 + b
if a * b * 3 == n:
print(n)
Перебираем не сами числа, а пары цифр, это позволяет обойтись без делений.
Или вот таким образом:
print(*(n for a, b in ((1, 5), (2, 4))
for n in [a * 10 + b] if a * b * 3 == n), sep = '\n')
Результат в обоих случаях:
15
24
Впрочем, и эти числа можно было найти аналитически из уравнения (10), ведь если b = 4 или 5, то a вычисляется однозначно. Но надо ж было хоть что-нибудь оставить программе, чтобы она доблестно нашла и вывела.
# которая находит и выводит все двузначные числа,
# которые равны утроенному произведению своих цифр.
# К таким относятся, например, 15 и 24.
# Пояснение:
# 15 -> 1*5*3 = 15 - получившееся число равно оригиналу, значит число надо вывести
# 16 -> 1*6*3 = 18 - число выводить не нужно, 18 не равно 16