Решение 1. Анализ через f(a, b, m)
🔹 Создаем рекурсивную функцию
def f(a, b, m):
📌 Функция определяет, может ли текущий игрок гарантированно победить, если до окончания анализа осталось m ходов.
🔹 Проверяем окончание игры
if a + b >= 165 or m < 0:
📌 Если сумма камней уже достигла 165 или ходы закончились, рекурсия завершается.
🔹 Возвращаем результат
return m % 2 == 0
📌 Чётность m показывает, чей ход оказался победным.
🔹 Перебираем все возможные ходы
h = f(a + 4, b, m - 1), f(a * 2, b, m - 1), f(a, b + 4, m - 1), f(a, b * 2, m - 1)
📌 Четыре действия: +4 или ×2 для первой или второй кучи.
🔹 Выбираем any
return any(h)
📌 Для задания 19 с «неудачного» хода Пети достаточно существования хотя бы одного выигрышного хода (any).
✅ Задание 19
📌 Найти минимальное S, при котором после неудачного хода Пети Ваня выигрывает своим первым ходом.
print(19, [s for s in range(1, 151) if f(14, s, 2)])
📌 Проверяем f(14, S, 2). Минимальное значение: 38.
🔹 Для заданий 20 и 21 меняем any на any/all
return any(h) if (m - 1) % 2 == 0 else all(h)
📌 На своём ходу — any, на ходе соперника — all.
✅ Задание 20
📌 Петя не выигрывает первым и вторым ходом, но выигрывает третьим.
print([s for s in range(1, 151) if not f(14, s, 1) and not f(14, s, 3) and f(14, s, 5)])
📌 Два первых значения: 32 и 59.
✅ Задание 21
📌 Ваня выигрывает вторым или третьим ходом, но не гарантированно вторым.
print([s for s in range(1, 151) if not f(14, s, 4) and f(14, s, 6)])
📌 Ответ: 57.