Для игры, описанной в задании 19, найдите минимальное значение S, при котором одновременно выполняются два условия:
– у Вани есть выигрышная стратегия, позволяющая ему выиграть первым или вторым ходом при любой игре Пети;
– у Вани нет стратегии, которая позволит ему гарантированно выиграть первым ходом.
Решение руками
Рассмотрев предыдущие 2 задачи, мы нашли, что – проигрышная позиция,
– выигрышная позиция. Ваня должен победить своими 1-мы (но это не гарантированно) или 2-мы ходами. Если он не побеждает первым, то все равно обязан выйти на победу своим вторым ходом при любой игре Пети. Значит Ване необходимо попасть в выигрышную позицию
, чтобы была возможность вывести Петю на проигрыш. Рассмотрим кол-во камней, из которого можно попасть в
минимальным ходом:
камней.
Заметим, что при начальном Ване может выиграть как первым, так и вторым ходом, что и подходит под условие нашей задачи. Так как других вариантов попадания в
нет, эта начальная позиция и является минимальной.
Программное решение
def f(s):
# если кол-во камней в куче >= 58, значит мы победили
# (для победы нам нужно сделать 0 ходов)
if s >= 58:
return 0
# если s меньше 58, значит мы рассматриваем все возможные ходы игрока
# (создаем массив n, в котором будут результаты для текущего s+1, s*2, s*4)
n = [f(s+1), f(s*2), f(s*4)]
# если своим ходом мы можем получить такое кол-во камней, при котором противник проиграет,
# значит мы выберем именно его (в генератор c добавляются значения из n <= 0)
c = [i for i in n if i <= 0]
# если с не пустой, значит результатом будет следующий по счету за ним ход,
# выигрышный для Пети
# например, -(-1*)+1 = 2 ход
if c:
res = -(max(c))+1
# иначе получаем номер хода, выигрышного для Вани
else:
res = -(max(n))
return res
# проверяем все возможные начальные позиции
for s in range(1,58):
# если функция выдает нам победу 2ым ходом Вани, значит выводим S
if f(s) == -2:
print(s)