Форум » Динамическое программирование » ege 23 №5404 » Ответить

ege 23 №5404

s11kai: Здравствуйте, у меня получилось только 10, а в ответе 34, кто сможет подсказать, чего я потерял? [pre2] def f(num): while num >= 10: digits = [int(d) for d in str(num)] if sum(digits)>8: num = digits[0]*digits[1] else: if sum(digits) == 8: return True else: return False count = 0 for num in range(10, 100): if f(num): #print(num) count += 1 print(count) [/pre2] Спасибо!

Ответов - 16, стр: 1 2 All

s11kai: Вау, дошел до 19: [pre2] def f(num): while num >= 10: digits = [int(d) for d in str(num)] if sum(digits)>8: num = digits[0]*digits[1] else: if digits[0]*digits[1] == 8 or sum(digits) == 8: return True else: return False count = 0 for num in range(10, 100): if f(num): print(num) count += 1 print(count) [/pre2]

Aleksey6819: s11kai, Вы не обрабатываете все суммы. Например: 89 8+9=17 1+7=8 Также у Вас не обрабатывается 99 (18,81), 9+9=18 1*8=8 или 9*9=81 8*1=8

s11kai: Aleksey6819 пишет: Например: 89 8+9=17 1+7=8 Также у Вас не обрабатывается 99 (18,81), 9+9=18 1*8=8 или 9*9=81 8*1=8 Вот эти числа и оказались самыми противными, не могу придумать как их обработать. Стыдно, но максимум,чего достиг, так это 32, так понимаю, что не обрабатывает 89, и не пойму, как выдать, что при 99 - два результата Подскажите кодом, кто может [pre2] def f(num): while num >= 10: digits = [int(d) for d in str(num)] if digits[0] * digits[1] == 8 or sum(digits) == 8: return True num = digits[0] * digits[1] return False count = 0 for num in range(10, 100): if f(num): print(num) count += 1 print(count)#32 [/pre2] Спасибо


s11kai: [pre2] def f(num): while num >= 10: digits = [int(d) for d in str(num)] if digits[0] * digits[1] == 8 or sum(digits) == 8: return True if sum(digits)>=17: #заметил, что список начинается с 17 вот и загнал его на повтор num = sum(digits) else: num = digits[0] * digits[1] return False count = 0 for num in range(10, 100): if f(num): print(num) count += 1 print(count)#34 [/pre2] Получилось 34, но скорее случайно, заметил что список чисел начинается с 17 вот и загнал его на повтор, хотелось бы посмотреть на чужой код для анализа, поскольку понимаю, что на 99 должно быть сразу два, а у меня только 1. Стало быть какое-то число лишнее Спасибо

Aleksey6819: s11kai [pre2]def f(num): while num>=10: digits = [int(d) for d in str(num)] if digits[0] * digits[1] == 8 or sum(digits) == 8: return True else: return f(sum(digits)) or f(digits[0] * digits[1]) return False count = 0 for num in range(10, 100): if f(num): #print(num) count += 1 print('Ответ:',count)[/pre2]

s11kai: Aleksey6819 пишет: [pre2]def f(num): while num>=10: digits = [int(d) for d in str(num)] if digits[0] * digits[1] == 8 or sum(digits) == 8: return True else: return f(sum(digits)) or f(digits[0] * digits[1]) return False count = 0 for num in range(10, 100): if f(num): #print(num) count += 1 print('Ответ:',count)[/pre2] Красиво получилось, главное, что этот код строки мне был знаком, но увы, самому до его применения додуматься не получилось Спасибо, Aleksey6819, выручили!

Ж: f=lambda n: f(sum(int(c) for c in str(n)))+f(reduce(lambda a,b: a*b, [int(c) for c in str(n)])) if n>9 else n==8 print(sum(f(n) for n in range(10,100))) (проверка N>9 нужна для того, чтобы не зависнуть в рекурсии на одном числе, т.к. сума и произведение цифр однозначного числа - это само число)

s11kai: Ж пишет: f=lambda n: f(sum(int(c) for c in str(n)))+f(reduce(lambda a,b: a*b, [int(c) for c in str(n)])) if n>9 else n==8 print(sum(f(n) for n in range(10,100))) Красиво, но непонятно, и кроме того выдает ошибку: NameError: name 'reduce' is not defined

s11kai: Кажется разобрался! Во-первых, мы должны подключить функцию reduce и рабочий код должен быть примерно таким: from functools import reduce f = lambda n: f(sum(int(c) for c in str(n))) + f(reduce(lambda a, b: a*b, [int(c) for c in str(n)])) if n > 9 else n == 8 print(sum(f(n) for n in range(10, 100))) Во-вторых, думаю стоит пояснить работу данного кода для тех, кто делает первые шаги f = lambda n: Создаем анонимную функцию `f` с использованием лямбда-выражения, которая способна принимать один аргумент `n`. Эта функция `f` имеет следующую структуру: если `n` больше 9 (то есть, это двузначное число), то выполняются два рекурсивных вызова функции `f`. Первая рекурсивная часть - `f(sum(int(c) for c in str(n)))` - суммирует все цифры числа `n`(преобразуя каждую цифру в `int`) и передает результат в вызов `f`. Вторая рекурсивная часть - `f(reduce(lambda a, b: a*b, [int(c) for c in str(n)]))` - умножает все цифры числа `n` (преобразуя каждую цифру в `int`) и передает результат в вызов `f`. Затем результаты этих двух рекурсивных вызовов суммируются. Если `n` не больше 9 (то есть, это однозначное число), то возвращаемся к проверке условия `n == 8`. Если `n` равно 8, то возвращается `True`, иначе - `False`. Затем вне функции `f`, используется генератор списка `[f(n) for n in range(10, 100)]`, который создает список результатов функции `f` для всех чисел в диапазоне от 10 до 99. Наконец, функция `sum` применяется к этому списку для вычисления суммы результатов. Таким образом, код проверяет сумму и произведение цифр всех чисел в диапазоне от 10 до 99 и считает количество тех, у которых или сумма, или произведение равно 8 Спасибо, Ж за ваш код, сам бы я до такого никогда не додумался

s11kai: from functools import reduce f = lambda n: f(sum(int(c) for c in str(n))) + f(reduce(lambda a, b: a*b, [int(c) for c in str(n)])) if n > 9 else n == 8 print(sum(f(n) for n in range(10, 100))) На первый взгляд показалось, что данный код оптимален, но если подумать, то можно написать такой: [pre2] def f(n): if n>9: S=sum(map(int,str(n))) P=n%10*(n//10) return f(S)+f(P) else: return n==8 print(sum(f(n) for n in range(10, 100))) [/pre2] При этом, если первый код состоит из 179 символов, то второй - 164, что как не крути - получается короче! вот если-бы избавиться от функции reduce, то размер кода уменьшится как минимум на 28 символов from functools import reduce

s11kai: Оказалось, что функцию reduce удалить не сложно. Вот что у меня получилось: f=lambda n: f(sum(int(c) for c in str(n)))+f(n%10*(n//10)) if n>9 else n==8 print(sum(f(n) for n in range(10,100))) код уменьшился до 114 знаков а можно ли его еще уменьшить, вопрос конечно интересный!

s11kai: код уменьшен до 106 знаков: f=lambda n:f(sum(map(int,str(n))))+f(n%10*(n//10)) if n>9 else n==8 print(sum(f(n) for n in range(10,100))) кто меньше?

Ж: Знала, что Вам понравится)) f=lambda n :f(n%10+n//10)+f(n%10*(n//10)) if n>9 else n==8 print(sum(f(n)>0 for n in range(10,100))) 100 символов) (внесено изменение, чтобы отсечь случаи, когда из одного числа можно получить 8 несколькими способами) вот если-бы избавиться от функции reduce, то размер кода уменьшится как минимум на 28 символов from functools import reduce reduce (в теме выше) я использовала для универсальности, когда разрядность числа неизвестна НО комментарий по вашим размышлениям: Таким образом, код проверяет сумму и произведение цифр всех чисел в диапазоне от 10 до 99 и считает количество тех, у которых или сумма, или произведение равно 8 Код суммирует и перемножает цифры не чисел 10-99, а результатов применения этих двух операций к суммам и произведениям цифр чисел, полученных на предыдущих этапах: 89 преобразуется в 17 или в 72, которые преобразуются в 8 или в 7 (здесь вызовы завершаются, из результатов подходит 1) или в 9 и 9 (здесь вызовы завершаются, из результатов подходит 0)

s11kai: Ж пишет: 89 преобразуется в 17 или в 72, которые преобразуются в 8 или в 7 (здесь вызовы завершаются, из результатов подходит 1) или в 9 и 9 (здесь вызовы завершаются, из результатов подходит 0) НО комментарий по концовке ваших размышлений: 89 преобразуется в 17 или в 72, которые преобразуются в 8 или в 7 (здесь вызовы завершаются, из результатов подходит 1) или в 9 и 14 14 преобразуется в 5 или 4 (здесь вызовы завершаются, из результатов подходит 0) а если мои размышления дополнить: Таким образом, код проверяет рекурсивно сумму и произведение цифр всех чисел в диапазоне от 10 до 99 и считает количество тех, у которых или сумма, или произведение равно 8 до тех пор пока результат не станет однозначным не равным 8 ниже иллюстрирую, что хотел сказать 10 - 0 0 ... 17 - 0 1 т.к. 1*7 = 7 (перемножаем цифру 1 на цифру 7 числа 17 ) 7 != 8 => 0 (1 знак выход False): 1+7 = 8 (сумма цифры 1 и цифры 7 числа 17) 8 == 8 =>1 (выход True) ... 99 - 1 1 т.к. 9*9 = 81 - число 2x значное, поэтому рекурсия 8*1 = 8 => 1 (выход True) 8+1 = 9 !=8 => 0 (1 знак выход False) 9+9 = 18 - число 2x значное, поэтому рекурсия 1*8 = 8 => 1 (выход True) 8+1 = 9 !=8 => 0 (1 знак выход False)

Ж: Теперь ок! Кстати, дочь скормила этот код чату GPT, чтобы он еще его сократил, он сократил, лишив программу смысла и надежды на верный ответ.

s11kai: О времена, о нравы! Было приятно с Вами познакомиться, хоть и виртуально, но меня сильно раздражает появление на страницах данного форума рекламных роликов, поэтому принял решение его покинуть



полная версия страницы