Для игры, описанной
— у Вани есть выигрышная стратегия, позволяющая ему выиграть первым или вторым ходом при любой игре Пети;
— у Вани нет стратегии, которая позволит ему гарантированно выиграть первым ходом.
Такое значение S — 14. При S = 14 Петя своим первым ходом может получить позиции
Рассмотрим значение S = 15. Своим первым ходом Ваня увеличивает количество камней в куче
Рассмотрим значение S = 18. Своим первым ходом Ваня увеличивает количество камней в куче
Рассмотрим значение S = 56. Своим первым ходом Ваня увеличивает количество камней
Ответ: 14.
Приведём решение Евгения Джобса (аналитическое).
Изобразим игру схематически, опираясь на данные, которые нашли при решении предыдущей задачи.
То есть необходимо, чтобы ход из позиции для S был либо в значения
Приведём решение Евгения Джобса (ручное, эл. таблицы).
В первой строке укажем количество камней в куче.
Во второй строке последовательно закрасим сначала клетки, соответствующие игре в один ход (зеленый), затем в два (красный). После этого найдем ячейки, которые соответствуют игре в три хода (зеленый 2) и игре
Приведём решение Евгения Джобса на языке Python.
Так как мы будем находить победу вторым или четвертым ходом, необходимо ограничить перебор значений условием, что перебираемое значение не входит в множество s2.
# множество вершин для игры в 1 ход
s1 = set()
for s in range(1, 77):
if any(x >= 78 for x in (s+1, s+4, s*4)):
s1.add(s)
# множество вершин для игры в 2 хода
s2 = set()
for s in range(1, 77):
if all(x in s1 for x in (s+1, s+4, s*4)):
s2.add(s)
# множество вершин для игры в 3 хода
s3 = set()
for s in range(1, 77):
if all(x in s2 for x in (s+1, s+4, s*4)):
s3.add(s)
# множество вершин для четвертого хода
s4 = set()
for s in range(1, 77):
if s not in s2 and\
all(x in s1|s3 for x in (s+1, s+4, s*4)):
s4.add(s)
print(min(s4))
Приведём решение Юрия Красильникова на языке Python.
def move(n,lim,s):
# n - номер хода, lim - ограничение на число ходов, s - число камней
# Результат: 1 - выиграл первый игрок, 2 - второй, 0 - победителя нет
player = 2 - n%2# Текущий игрок
rival = 3 - player# Противник
if s >= 78:# Игра уже окончена
return rival # Выиграл сделавший предыдущий ход
if n > lim:# Превышен лимит ходов
return 0# Победитель не определен
pos = [s+1, s+4, s*4]# Позиции после хода игрока
res = [move(n+1, lim, x) for x in pos]# Результаты ходов
if any([x == player for x in res]):# Есть выигрышный ход
return player
if all([x == rival for x in res]):# Все ходы проигрышные
return rival
return 0# Победитель не определен
print('#19:',*[s for s in range(1,78) if move(1,2,s)==2])
print('#20:',*[s for s in range(1,78) if move(1,1,s)==0 and move(1,3,s)==1])
print('#21:',*[s for s in range(1,78) if move(1,2,s)==0 and move(1,4,s)==2])

