Решение. Рассмотрим значение S = 24. Своим первым ходом Петя может получить позиции (6, 24), (7, 24), (8, 24), (9, 24) и (10, 24). К победе Петю приводит позиция (10, 24). Сколько бы камней не добавил Ваня, он не сможет получить более 44 камней суммарно, и Петя выигрывает на своем втором ходе. При остальных позициях Петя не сможет выиграть Ваню своим вторым ходом.
Второе значение S — 33. Своим первым ходом Петя может получить позиции (6, 33), (7, 33), (8, 33), (9, 33) и (10, 33). К победе Петю приводит позиция (6, 33). Сколько бы камней не добавил Ваня, он не сможет получить более 45 камней суммарно, и Петя выигрывает на своем втором ходе. При остальных позициях Петя не сможет выиграть Ваню.
Ответ: 24 и 33.
Приведём решение Дмитрия Пехова на языке Python.
def f(a,b,m):
if a+b >= 46:
return m%2==0
if m==0:
return 0
h = []
if a <= b:
for i in range(1,a+1):
h.append(f(a+i,b,m-1))
else:
for i in range(1,b+1):
h.append(f(a,b+i,m-1))
if (m-1)%2==0:
return any(h)
else:
return all(h)
print('19)', min([s1 + s2 for s1 in range(1,46) for s2 in range(1,46) if f(s1,s2,1)]))
print('20)', min([s2 for s2 in range(1,41) if not f(5,s2,1) and f(5,s2,3)]))
print('20)', max([s2 for s2 in range(1,41) if not f(5,s2,1) and f(5,s2,3)]))
print('21)', min([s2 for s2 in range(1,41) if not f(5,s2,2) and f(5,s2,4)]))
Приведём решение Юрия Красильникова на языке Python.
def ход(номер,лимит,позиция):
игрок=2-номер%2
враг=3-игрок
if sum(позиция)>=46: return враг
if номер>лимит: return 0
куча1,куча2=позиция
if куча1<куча2: позиции=[(куча1+добавка,куча2) for добавка in range(1,куча1+1)]
else: позиции=[(куча1,куча2+добавка) for добавка in range(1,куча2+1)]
результаты=[ход(номер+1,лимит,поз) for поз in позиции]
if any(рез==игрок for рез in результаты): return игрок
if all(рез==враг for рез in результаты): return враг
return 0
print('#19:',min([куча1+куча2 for куча1 in range(1,44) for куча2 in range(1,44) if ход(1,1,(куча1,куча2))==1]))
print('#20:',*[куча2 for куча2 in range(1,41) if ход(1,1,(5,куча2))==0 and ход(1,3,(5,куча2))==1])
print('#20:',*[куча2 for куча2 in range(1,41) if ход(1,2,(5,куча2))==0 and ход(1,4,(5,куча2))==2])
Приведём решение Юрия Ворошилова на языке Python.
def f(x,y,n):
if x+y>=46 and n==3:
return 1
if x+y>=46 and n==1:
return 0
if x+y<46 and n==3:
return 0
if x+y>=46 and n%2==0:
return 0
if x+y<46 and n%2==1:
a=[]
if x < y:
for i in range(1,x+1): a.append(f(x+i, y, n+1))
else:
for i in range(1,y+1): a.append(f(x, y+i, n+1))
return all(a)
if x+y < 46 and n%2==0:
a=[]
if x < y:
for i in range(1,x+1): a.append(f(x+i, y, n+1))
else:
for i in range(1,y+1): a.append(f(x, y+i, n+1))
return any(a)
for y in range(1,41):
if f(5, y, 0):
print(y)
Приведём решение Маргариты Фалько на языке Python.
def g(s1, s2, p, end):
if s1 + s2 > 45: return p in end
if p > max(end): return False
moves1 = [g(s1+i, s2, p+1, end) for i in range(1, s1+1) if s1 <= s2]
moves2 = [g(s1, s2+i, p+1, end) for i in range(1, s2+1) if s2 <= s1]
moves = moves1 + moves2
return any(moves) if ((p+1) % 2) == (end[0] % 2) else all(moves)
print('Задание 19:', min([s1+s2 for s1 in range(1,44) for s2 in range(1,44) if g(s1, s2, 0, [1])]))
res_20 = [s1 for s1 in range(1,44) if g(s1, 5, 0, [1, 3]) and not g(s1, 5, 0, [1])]
print('Задание 20:', min(res_20), max(res_20))
print('Задание 21:', min([s1 for s1 in range(1,40) if g(s1, 5, 0, [2, 4]) and not g(s1, 5, 0, [2])]))